# Coding agents

These docs are markdown-first on purpose: the primary reader is often a coding agent. Every page is dual-served — `/docs/<slug>` rendered for humans, `/docs/<slug>.md` as raw markdown for agents — and the machine index lives at [https://app.routerplus.com/llms.txt](https://app.routerplus.com/llms.txt).

This page covers wiring **Claude Code** and **Codex CLI** through the gateway and an **installation runbook** for a coding agent. The user completes signup and email verification through Clerk in a browser before the agent configures an API client. To build the gateway into a product instead, give your agent the [Agent integration guide](agent-integration.md).

## Claude Code

Claude Code speaks the Anthropic wire format, which the gateway's `/v1/messages` surface accepts directly. Two environment variables, no other change:

```bash
export ANTHROPIC_BASE_URL=https://api.routerplus.com
export ANTHROPIC_AUTH_TOKEN=$TM_API_KEY
claude
```

Or as a one-shot launch:

```bash
ANTHROPIC_BASE_URL=https://api.routerplus.com ANTHROPIC_AUTH_TOKEN=$TM_API_KEY claude
```

> [!WARNING]
> If this machine's Claude Code is **signed in** (claude.ai subscription), the
> login session outranks env keys: interactively you'll get a one-time "use
> this API key?" prompt — approve it — but in headless `-p` mode there is no
> prompt and requests fail with a 401. For headless/CI use, point Claude Code
> at a fresh config dir so the env key is the only credential:
> `CLAUDE_CONFIG_DIR=$(mktemp -d) ANTHROPIC_BASE_URL=https://api.routerplus.com ANTHROPIC_API_KEY=$TM_API_KEY claude -p "..."`

What makes this work:

- `ANTHROPIC_AUTH_TOKEN` is sent as `Authorization: Bearer …`, which the gateway accepts everywhere (as it does `x-api-key`).
- Claude Code appends query strings (`/v1/messages?beta=true`); the gateway routes on the pathname, so these pass through cleanly.
- Model ids resolve against the catalog at [https://app.routerplus.com/api/models.json](https://app.routerplus.com/api/models.json), which lists one clean id per model (`claude-haiku-4-5`, `claude-sonnet-4-5`, …). Claude Code often sends **dated** ids (`claude-haiku-4-5-20251001`); those resolve to their family automatically and your original id goes to the provider verbatim — see [Models & catalog](/docs/models). A genuinely unknown id gets an honest `404` naming it.
- Every request Claude Code makes lands in `https://api.routerplus.com/v1/usage` with its token counts and `cost_usd`, so you can watch what a session costs.

> [!NOTE]
> The gateway serves these buyer endpoints — `/v1/chat/completions`,
> `/v1/messages`, `/v1/messages/count_tokens` (unbilled, models with an
> Anthropic-dialect deployment), `/v1/models`, `/v1/images/generations`,
> `/v1/videos`, `/v1/usage`, `/v1/generation`, `/v1/route` and `/v1/limits` —
> plus an unauthenticated `/healthz`. Anything else an authenticated tool probes
> receives a well-formed `404` with `error_type: not_found` in the caller's own
> dialect, not a hang or an HTML page.

### Persistent setup

Exports vanish with the shell. To make the gateway Claude Code's default,
put the env block in `~/.claude/settings.json` (or a project's
`.claude/settings.json` to scope it to one repo):

```json
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://api.routerplus.com",
    "ANTHROPIC_AUTH_TOKEN": "tm_vk_..."
  }
}
```

### Pinning which models Claude Code uses

Claude Code picks its own model ids; steer them with the standard variables,
using any Claude id from the catalog:

```bash
export ANTHROPIC_MODEL=claude-sonnet-5          # main model
export ANTHROPIC_SMALL_FAST_MODEL=claude-haiku-4-5  # background/fast tasks
```

Inside a session, `/model` accepts any catalog id the same way. Spend from
every session lands in [the console](https://app.routerplus.com/console/usage) and
`https://api.routerplus.com/v1/usage`, per request.

## Codex CLI

> [!WARNING]
> Current Codex CLI releases do not work with the gateway. Since February 2026, Codex
> calls only the OpenAI Responses API
> ([openai/codex discussion #7782](https://github.com/openai/codex/discussions/7782)),
> and a config with `wire_api = "chat"` stops with an error. The gateway does not
> implement the Responses API: `POST /v1/responses` returns a `404` with
> `error_type: not_found`.

Codex releases from before February 2026 still speak Chat Completions. For those, pin
the wire in the provider block:

```toml
# ~/.codex/config.toml
[model_providers.tm]
name = "RouterPlus"
base_url = "https://api.routerplus.com/v1"
env_key = "TM_API_KEY"
wire_api = "chat"

[profiles.tm]
model_provider = "tm"
model = "gpt-4o-mini"
```

```bash
TM_API_KEY=tm_vk_... codex --profile tm
```

On such a release, `wire_api = "chat"` is a requirement, not a preference: a profile
left on the Responses wire fails on every call.

## Other OpenAI-compatible harnesses

Most coding tools that speak "OpenAI-compatible" take the same two values:
**base URL** `https://api.routerplus.com/v1` and **API key** `tm_vk_...`. The pattern, in
the tools' own vocabulary:

| Tool | Where |
|---|---|
| Cursor | Settings → Models → API Keys: set the OpenAI key to your `tm_vk_...` key and enable "Override OpenAI Base URL" with `https://api.routerplus.com/v1` |
| Cline / Roo | Provider: "OpenAI Compatible" → Base URL `https://api.routerplus.com/v1`, key `tm_vk_...`, model id from the catalog |
| Continue | `models` entry with `provider: "openai"`, `apiBase: "https://api.routerplus.com/v1"`, `apiKey: "tm_vk_..."` |
| aider | `OPENAI_API_BASE=https://api.routerplus.com/v1 OPENAI_API_KEY=tm_vk_... aider --model openai/claude-sonnet-5` |
| Anything else | If it has a "base URL" box next to its OpenAI key box, those two values are the whole integration |

Every chat model in the catalog works through this surface — Claude models included (image models use [POST /v1/images/generations](/docs/api-images), video models [POST /v1/videos](/docs/api-videos));
the gateway translates. Two honest caveats:

- Tools built on the OpenAI **Responses** API (the OpenAI Agents SDK's default, and
  every current Codex CLI release) do not work yet: `POST /v1/responses` returns a
  404. Pick the tool's Chat Completions mode where one exists.
- These are configuration patterns, not per-version walkthroughs — tool UIs
  move. The two values above are the invariant.

## SDKs inside the project your agent is editing

| Client | Change |
|---|---|
| OpenAI SDK (any language) | `base_url = "https://api.routerplus.com/v1"`, `api_key = TM_API_KEY` |
| Anthropic SDK (any language) | `base_url = "https://api.routerplus.com"`, `api_key = TM_API_KEY` |
| Raw HTTP | host → `https://api.routerplus.com`, key in `Authorization: Bearer` or `x-api-key` |

Full streaming examples for both surfaces are in the [Quickstart](/docs/quickstart); for migrating a whole codebase in one prompt, see [Migrate](/docs/migration).

## The installation runbook

This section is written to be executed. Give it to your agent — `read https://app.routerplus.com/docs/install.md and get me set up` — or walk it yourself.

**Objective:** this environment makes a successful, streamed, billed model call through the gateway.

**Done when:** a streamed completion ends with a usage object containing a `cost` field, and `https://api.routerplus.com/v1/usage` shows the request.

1. **Get a key** (skip if `TM_API_KEY` is already set). The user opens
   [Sign up](https://app.routerplus.com/signup), completes Clerk authentication and email
   verification, and saves the first key shown after sign-in. Signup does not grant
   free credit: add paid credits in [Billing](https://app.routerplus.com/console/billing). Existing customers sign in at
   [https://app.routerplus.com/login](https://app.routerplus.com/login) with the same verified email and
   create a key at [API keys](https://app.routerplus.com/console/keys). Raw keys are shown once.
   Account creation has no terminal API; do not call the retired `POST /v1/signup`
   or local `POST /login` routes. Continue client setup when the key is available.

2. **Export the key**, and write it to the project's `.env` if one exists (never commit it):

   ```bash
   export TM_API_KEY=tm_vk_...
   ```

3. **Discover the models.** Any id in this file works in step 4:

   ```bash
   curl -s https://app.routerplus.com/api/models.json
   ```

4. **Make the test call.** OpenAI-compatible surface; works for every chat model, including Claude models — the gateway translates:

   ```bash
   curl -N https://api.routerplus.com/v1/chat/completions \
     -H "Authorization: Bearer $TM_API_KEY" \
     -H "content-type: application/json" \
     -d '{"model":"claude-haiku-4-5","stream":true,"max_tokens":40,"messages":[{"role":"user","content":"Reply with exactly: MARKETPLACE OK"}]}'
   ```

   Expected: an SSE stream ending with a usage chunk that has a `cost` field, then `data: [DONE]`.

   On HTTP `429` with `error_type: insufficient_quota`, stop and have the user check their balance and spend caps in [Billing](https://app.routerplus.com/console/billing). Retry **once** after they resolve the cause — never in a loop. The full retry discipline per error class is in [Errors](/docs/errors).

5. **Wire the user's stack.** Apply every branch that matches this environment: the OpenAI SDK, Anthropic SDK, and raw-HTTP changes from the table above; Claude Code exactly as configured earlier on this page, and Codex CLI only when its release is from before February 2026 (see [Codex CLI](#codex-cli)).

6. **Verify billing** — the done-when condition:

   ```bash
   curl -s -H "Authorization: Bearer $TM_API_KEY" https://api.routerplus.com/v1/usage
   ```

   The test call must appear in `recent_attempts` with its token counts and `cost_usd`.

7. **Optional, recommended:** add attribution headers to the user's app — `HTTP-Referer: https://the-users-app.example` and `X-Title: The App Name`. Content-free; they identify the app for future per-app analytics and expose no request data.

Finally, report to the user: the org id, where the key is stored, which stacks were wired, and the cost of the test call.

## /llms.txt — start here if you are an agent

```bash
curl -s https://app.routerplus.com/llms.txt
```

It carries the gateway base URL, browser signup instructions, links to every doc page in raw-markdown form, and the machine-readable model catalog. Fetch it first; everything else on this page is reachable from it. Its first link is the [Agent integration guide](https://app.routerplus.com/docs/agent-integration.md), the one page to read before you build the gateway into a product. To load every page with one fetch, use [https://app.routerplus.com/llms-full.txt](https://app.routerplus.com/llms-full.txt).

## Signup requires the browser

Public signup and sign-in use Clerk at [Sign up](https://app.routerplus.com/signup) and
[Sign in](https://app.routerplus.com/login). Complete the authentication and email-verification
steps there. Local magic-link submission and programmatic signup are retired;
there is no `dev_verify_link` in a public signup response. After signup, agents
can use the existing `tm_vk_` key with the gateway normally.

## Next steps

- [Quickstart](/docs/quickstart) — the same flow by hand, with streaming examples on both surfaces
- [Migrate](/docs/migration) — the one-prompt migration for an existing codebase
- [Errors](/docs/errors) — every `error_type`, and the retry discipline agents should follow
- [Rate limits & spend caps](/docs/limits) — trial RPM, monthly caps, and the 429 with a reset time
