# 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://dev.routerplus.com/llms.txt](https://dev.routerplus.com/llms.txt).

This page has one section per tool, each with a setup to copy and paste and the tool's limits through the gateway: [Claude Code](#claude-code), [Codex](#codex), [Cursor](#cursor), [Cline](#cline), [Kilo Code](#kilo-code), [OpenCode](#opencode) and [other tools](#other-tools). Apps built with Replit, Lovable, Bolt or v0 have [their own page](/docs/app-builders). The [Playground](#playground) needs no setup at all. The page ends with an [installation runbook](#the-installation-runbook) that a coding agent can follow. To build the gateway into a product instead, give your agent the [Agent integration guide](agent-integration.md).

## Before you start

1. **Get a key.** Open [Sign up](https://dev.routerplus.com/signup), complete Clerk authentication and email verification, and save the first key shown after sign-in. Buy credits in [Billing](https://dev.routerplus.com/console/billing): signup alone does not add credit. An invitation link from RouterPlus (for example, at a hackathon) adds its credit and makes the account count as paid, with higher limits. Create more keys at [API keys](https://dev.routerplus.com/console/keys). A key looks like `tm_vk_...`; give each tool its own.
2. **Pick the base URL.** Tools that speak OpenAI's format use `https://dev-api.routerplus.com/v1`. Tools that speak Anthropic's format (Claude Code) use `https://dev-api.routerplus.com`, without `/v1`.
3. **Pick a model.** These ids work in every tool; in Cursor, use the name in the second column. The live list, with every price, is [https://dev.routerplus.com/api/models.json](https://dev.routerplus.com/api/models.json).

   | Model id | Name in Cursor | Context | Max output | Input /1M | Cached /1M | Cache write /1M | Output /1M |
   |---|---|---|---|---|---|---|---|
   | `claude-opus-5-5` | `rp-opus-5-5` | 1,000,000 | 128,000 | $4 | $0.20 | $5 | $20 |
   | `claude-fable-5-1` | `rp-fable-5-1` | 1,000,000 | 128,000 | $10 | $0.25 | $12.50 | $50 |
   | `claude-sonnet-5-5` | `rp-sonnet-5-5` | 1,000,000 | 128,000 | $2 | $0.10 | $2.50 | $10 |
   | `claude-haiku-5-5` | `rp-haiku-5-5` | 1,000,000 | 128,000 | $0.10 | $0.01 | $0.125 | $0.50 |
   | `gpt-6-astra` | `gpt-6-astra` | 1,050,000 | 128,000 | $10 | $1 | $12.50 | $50 |
   | `gpt-6.1-sol` | `gpt-6.1-sol` | 1,050,000 | 128,000 | $2 | $0.10 | $2.50 | $10 |
   | `gpt-6-luna` | `gpt-6-luna` | 1,050,000 | 128,000 | $0.10 | $0.01 | $0.125 | $0.50 |
   | `gpt-5.6-terra` | `gpt-5.6-terra` | 1,050,000 | 128,000 | $2 | $0.20 | $2.50 | $12 |
   | `gpt-6-sol` | `gpt-6-sol` | 1,050,000 | 128,000 | $2 | $0.20 | $2.50 | $10 |
   | `gpt-5.6-sol` | `gpt-5.6-sol` | 1,050,000 | 128,000 | $4 | $0.40 | $5 | $20 |
   | `gpt-5.6-luna` | `gpt-5.6-luna` | 1,050,000 | 128,000 | $0.20 | $0.02 | $0.25 | $1.20 |

   The other chat models in the catalog work too: `claude-sonnet-5`, `claude-opus-5`, `claude-fable-5`, `claude-sonnet-4-5` and `claude-haiku-4-5` (in Cursor `rp-sonnet-5`, `rp-opus-5`, `rp-fable-5`, `rp-sonnet-4-5` and `rp-haiku-4-5`), and `gpt-4o`, `gpt-4o-mini` and `gpt-4.1-mini`.

### What the gateway does for coding agents

- **No cut-off answers.** Most agents send no output limit. The model then gets its own maximum (128,000 tokens on the models above; on the chat surfaces the gateway fits it to the context window), so a long file or a long tool call is not cut short. The balance hold counts at most 32,768 output tokens of it.
- **Prompt caching on Claude.** For an agent's conversation that carries no cache marks, the gateway turns on Claude's automatic caching, so later turns read the long prompt at the cache price. The `x-tm-auto-cache` response header says whether it did. See [Automatic caching on Claude](/docs/compat#automatic-caching-on-claude).
- **Screenshots and PDFs.** Images and PDFs reach Claude from tools that speak OpenAI's format, and reach GPT models from tools that speak Anthropic's format.
- **Long conversations get compacted.** A prompt longer than the model's window gets the standard error that agents compact on: `context_length_exceeded` on the OpenAI format, `prompt is too long` on the Anthropic format.
- **The provider's own words.** An error carries the provider's message, so an agent can see what the model refused and retry without it. A 502 or 504 is the exception: it arrives as Cloudflare's own short error page, without the message or `x-request-id` (see [Errors](/docs/errors)). Agents retry it by themselves.
- **Default sampling only.** The Claude 5, GPT-6 and GPT-5.6 models take only their default sampling. When a tool sends another `temperature`, or a `top_p` or `top_k`, the gateway drops it and names it in `x-tm-dropped-params`, instead of failing.
- **Fair cancels.** When you stop an answer (Esc, Stop), you pay for the input and the output already streamed, never the full hold.
- **Silent thinking.** The Claude 5 models think before they answer, and they do not show it. Nothing reaches the tool until the first word or tool call, so a hard turn can look stuck for a minute or more.

### Your balance and the hold

While a request runs, the gateway holds balance for its cost: the input, plus the output limit. A limit that the tool sends is held in full. When a tool sends no limit, the model still gets its maximum of 128,000 tokens, but the hold counts at most 32,768 output tokens: about $1.64 per request on Claude Fable 5.1 and GPT-6 Astra, $0.66 on Claude Opus 5.5 and GPT-5.6 Sol, $0.39 on GPT-5.6 Terra, $0.33 on Claude Sonnet 5.5, GPT-6.1 Sol and GPT-6 Sol, $0.04 on GPT-5.6 Luna, and $0.02 on Claude Haiku 5.5 and GPT-6 Luna. Agents often run several requests at once.

> [!WARNING]
> You pay for what a request really used, never the hold, so a long answer can cost
> more than its hold. A small balance can refuse a request (`insufficient_quota`) before
> it starts. On a small balance, pick a cheaper model, and do not let the tool send a
> large output limit: its section below shows how.

### When you hit a rate limit

A request over one of your limits gets a 429 (a 503 when the gateway as a whole is full). Its `retry-after` header says how many seconds to wait, from 1 to 59: the time until the limit's one-minute window has room again, or 10 seconds for a limit on requests at once, which frees when one of your running requests ends. Most coding agents wait and try again by themselves:

| Tool | What it does on a 429 |
|---|---|
| Claude Code | waits at least `retry-after` and tries again, up to 10 times (`CLAUDE_CODE_MAX_RETRIES`, at most 15) |
| Codex | waits `retry-after` and tries again, up to `stream_max_retries` times (5 by default), showing `Reconnecting... 1/5`; to wait longer, add `stream_max_retries = 10` to `[model_providers.routerplus]` |
| Cursor | does not try again: it shows the error, so send your message again after the wait |
| Cline | waits `retry-after` and tries again, up to 5 times, with no message while it waits: a turn can pause for up to a minute |
| Kilo Code, OpenCode | wait `retry-after` and try again, up to 5 times, showing the error with a countdown |

When the tries run out, the task stops with the error: tell the agent to continue. Out of credit (`insufficient_quota`) is also a 429. If your own requests in flight hold the balance, it frees as they end, and the agents' retries can ride it out; if not, add credits in [Billing](https://dev.routerplus.com/console/billing). Codex stops on it at once. On a monthly spend cap, Claude Code stops at once too, because that 429 says not to retry.

## Claude Code

Claude Code speaks Anthropic's format, which the gateway's `/v1/messages` surface accepts as it is. It works with Claude Code's default model (Claude Opus 5.5, sent as `claude-opus-5-5`) and with every Claude id in the catalog.

### Claude Code CLI

Put the gateway in your user settings, `~/.claude/settings.json`:

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

Then run `claude`. There is no login screen: the first run shows the theme, the security notes and the folder trust question, then a session on Opus 5.5 with API usage billing. At the folder trust question, choose **Yes, I trust this folder**: the default answer, **No, exit**, closes Claude Code. `/status` shows the base URL and `ANTHROPIC_AUTH_TOKEN`. Do not put the key in a project's `.claude/settings.json`: that file is committed, and its `env` block applies only after the first-run screens, so the login screen still appears. For one shell only, export the same two values:

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

> [!WARNING]
> Use `ANTHROPIC_AUTH_TOKEN`, not `ANTHROPIC_API_KEY`. With `ANTHROPIC_API_KEY`,
> Claude Code asks once whether to use "a custom API key", shows it masked as if
> it were an Anthropic key, and its default answer is **No**: press Enter and it
> opens the login screen instead. If that happened, choose the custom API key in
> `/config`. You do not need to sign in to claude.ai: `ANTHROPIC_AUTH_TOKEN` comes
> before a claude.ai sign-in. For headless or CI use, give Claude Code a fresh
> config directory so that no earlier setting interferes:
> `CLAUDE_CONFIG_DIR=$(mktemp -d) ANTHROPIC_BASE_URL=https://dev-api.routerplus.com ANTHROPIC_AUTH_TOKEN=$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.
- Claude Code often sends **dated** ids (`claude-haiku-4-5-20251001`); those resolve to their model 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.
- The gateway forwards the `anthropic-beta` values that Claude Code needs on the Claude 5 models (Opus 5.5, Fable 5.1, Sonnet 5.5, Haiku 5.5): the effort setting inside a message, context editing (`context_management`), and tools added during a session. [Wire compatibility](/docs/compat) lists every value it forwards.
- Claude Code sends its own cache marks, so its prompts are cached as on Anthropic's API. Its web search works, at Anthropic's price per search (see [Pricing & billing](/docs/pricing#web-search)).
- When a conversation outgrows the model's window, the gateway answers with Anthropic's own `prompt is too long` error, the one Claude Code reads to compact the conversation.
- Every request Claude Code makes lands in `https://dev-api.routerplus.com/v1/usage` with its token counts and `cost_usd`, so you can watch what a session costs.

Limits: Remote Control is off whenever the base URL is not Anthropic's, and voice dictation is off while a gateway key is in use.

Each new interactive session starts with one failed request, at no charge. Claude Code first asks for a beta feature that the gateway does not forward (`thinking-display-updates-2026-08-18`), Anthropic refuses it, and Claude Code sends the request again at once without it. `/v1/usage` shows the failed attempt; the session is not affected.

> [!NOTE]
> The gateway serves these buyer endpoints — `/v1/chat/completions`,
> `/v1/responses` and `/v1/responses/compact`, `/v1/messages`,
> `/v1/messages/count_tokens` (unbilled, models with an Anthropic-dialect
> deployment), `/v1/models`, `/v1/images/generations`, `/v1/decisions`,
> `/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.

### Claude Code in VS Code

The Claude Code extension for VS Code (VS Code 1.94 or later) takes the same two values in its own setting, which must be in your **user** settings. Run **Preferences: Open User Settings (JSON)** and add:

```json
{
  "claudeCode.environmentVariables": [
    { "name": "ANTHROPIC_BASE_URL", "value": "https://dev-api.routerplus.com" },
    { "name": "ANTHROPIC_AUTH_TOKEN", "value": "tm_vk_..." }
  ],
  "claudeCode.disableLoginPrompt": true
}
```

`claudeCode.disableLoginPrompt` stops the extension from asking you to sign in. The extension also reads `~/.claude/settings.json`, but only for the Claude Code process it starts, not for its own sign-in check, so the key belongs in `claudeCode.environmentVariables`. Through a gateway the extension shows no plan usage bars, no voice dictation and no Web tab.

### Claude Code in JetBrains IDEs

The Claude Code plugin for JetBrains IDEs (IntelliJ IDEA, PyCharm, WebStorm and the others) runs the `claude` command in the IDE's terminal, so it uses the CLI's `~/.claude/settings.json` above. Install the CLI first: the plugin does not include it. If the IDE cannot find it, set its path in **Settings → Tools → Claude Code [Beta] → Claude command**.

### Claude desktop app

The Claude desktop app (macOS and Windows) can send its requests to a gateway instead of claude.ai, in third-party mode:

1. **Help → Troubleshooting → Enable Developer Mode**. On Windows the Help menu is under ☰, at the top left of the sign-in screen. The app restarts with a **Developer** menu.
2. **Developer → Configure Third-Party Inference…**
3. Under **Connection**, set **Inference provider** to **Gateway**.
4. Under **Gateway credentials**: **Gateway base URL** `https://dev-api.routerplus.com` (without `/v1`), **Gateway API key** your `tm_vk_...` key, **Credential kind** Static API key, and **Gateway auth scheme** Bearer.
5. **Apply Changes**, then **Save & Restart**.
6. On the sign-in screen, start in third-party mode. Do not sign in to claude.ai or create an Anthropic account.

Limits: in third-party mode, Remote Control, Anthropic's cloud sessions, the mobile apps, voice mode, computer use and the connectors made by Anthropic do not work. Local MCP servers do, and so does web search, which the gateway passes to Anthropic. An administrator can set the same values for a whole company with managed settings (`inferenceProvider: "gateway"`, `inferenceGatewayBaseUrl`, `inferenceGatewayApiKey`, `inferenceGatewayAuthScheme: "bearer"`).

### Output limit, auto mode and the advisor

- **Output limit and your balance.** Claude Code asks the Claude 5 models for up to 128,000 output tokens (64,000 on Fable 5.1), and the gateway accepts up to each model's own maximum, `max_output_tokens` in the catalog. While a request runs, the gateway holds balance for its cost: the input, plus that output, because Claude Code sends the limit itself. The output part is about $2.56 per request on Opus 5.5 and $3.20 on Fable 5.1. When a request ends, you pay for the tokens the provider reports. If you interrupt a request (Esc), you pay for its input and for the output already streamed to you. The Claude 5 models do not show their thinking, so an interrupt while the model thinks costs the input only. On a small balance, set a lower limit:

  ```bash
  export CLAUDE_CODE_MAX_OUTPUT_TOKENS=32000
  ```

- **Auto mode.** Claude Code starts in auto mode. In auto mode and plan mode, it checks some tool calls before it runs them (a web search, for example; file edits and simple commands needed none in our tests). Each check is a separate request to `claude-sonnet-5` that carries the conversation, and the gateway bills it as a normal request, at the full input price: one check of a 47,000-token conversation cost about $0.12. The first check shows a notice that auto mode keeps working: press Enter. To avoid the checks, press Shift+Tab to change to another permission mode. To stop the notice, set `CLAUDE_CODE_AUTO_MODE_SERVER=0`.
- **Advisor.** Do not turn on the advisor (`/advisor`). It runs a second model that bills at its own rates, so the gateway does not forward its beta, and Anthropic refuses the request with a 400 that names `Input tag 'advisor_…'`. Claude Code 2.1.280 or later then sends the request again without the advisor, and leaves the advisor off until it exits.

### Pinning which models Claude Code uses

Claude Code picks its own model ids; steer them with the standard variables, in the shell or in the `env` block of `settings.json`, using any Claude id from the catalog:

```bash
export ANTHROPIC_MODEL=claude-sonnet-5-5               # main model
export ANTHROPIC_DEFAULT_HAIKU_MODEL=claude-haiku-5-5  # background and fast tasks
```

Set `ANTHROPIC_DEFAULT_HAIKU_MODEL`: behind a gateway, Claude Code otherwise runs its background tasks on the main model, which is Opus 5.5 by default. Its aliases resolve as on Anthropic's API (`opus` is `claude-opus-5-5`, `sonnet` is `claude-sonnet-5-5`, `haiku` is `claude-haiku-5-5`, `fable` is `claude-fable-5-1`), and `ANTHROPIC_DEFAULT_OPUS_MODEL`, `ANTHROPIC_DEFAULT_SONNET_MODEL`, `ANTHROPIC_DEFAULT_FABLE_MODEL` and `CLAUDE_CODE_SUBAGENT_MODEL` pin the others.

`ANTHROPIC_MODEL` applies again at every launch, over what you pick with `/model`. To set only the model that new sessions start on, and keep your `/model` choice, use `ANTHROPIC_DEFAULT_MODEL` instead (Claude Code 2.1.236 or later).

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

## Codex

Codex — the CLI, the IDE extension and the desktop app (Codex in the ChatGPT desktop app) — reads one file, `~/.codex/config.toml`, and calls the Responses API, which the gateway serves at [POST /v1/responses](/docs/api-responses). Add the gateway as a provider. Keys such as `model` must come before the first `[table]`:

```toml
# ~/.codex/config.toml
model = "gpt-6-luna"
model_provider = "routerplus"

[model_providers.routerplus]
name = "RouterPlus"
base_url = "https://dev-api.routerplus.com/v1"
env_key = "TM_API_KEY"
wire_api = "responses"
```

Then start Codex with the key in the environment:

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

Use any GPT-6 or GPT-5.6 model as `model` (`gpt-6-astra`, `gpt-6.1-sol`, `gpt-6-sol`, `gpt-6-luna`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`), or start Codex with `codex -m gpt-6-astra`. The CLI needs no sign-in for this provider. `wire_api = "responses"` is Codex's default, so you can also leave it out; with `wire_api = "chat"`, current Codex does not start ("`wire_api = "chat"` is no longer supported"). Do not name the provider `OpenAI`: Codex then treats it as OpenAI's own service and changes how it compacts a long conversation.

**The desktop app** may not see variables from your shell when you start it from the Dock or Finder. Put the key in the provider block instead of `env_key`. Use one or the other, never both: when `env_key` names a variable that is missing, Codex fails.

```toml
[model_providers.routerplus]
name = "RouterPlus"
base_url = "https://dev-api.routerplus.com/v1"
wire_api = "responses"
experimental_bearer_token = "tm_vk_..."
```

The file then holds your key: never commit it or share it. To keep the key out of the file on a Mac, keep `env_key`, run `launchctl setenv TM_API_KEY tm_vk_...`, and quit and reopen the app; do it again after a restart. The desktop app's model picker lists only OpenAI's own models, so set `model` in the file.

**Claude models (preview).** Codex can run Claude through the gateway's preview translation:

```toml
model = "claude-sonnet-5-5"
model_provider = "routerplus"
model_context_window = 272000
web_search = "disabled"
```

Codex has no metadata for a Claude id, and it says so: "Model metadata for `claude-sonnet-5-5` not found. Defaulting to fallback metadata". The warning stays; only a full model catalog of your own (`model_catalog_json`) removes it. For an id it does not know, Codex caps `model_context_window` at 272,000 tokens, so set that. `model_max_output_tokens` no longer exists in Codex: it is ignored, with a warning. `web_search = "disabled"` stops Codex from sending its hosted web search tool, which does not run on Claude (the gateway drops it and names it in `x-tm-dropped-params`). Do not set `model_reasoning_effort` for a Claude model: Claude refuses it through this translation with a 400, and Codex stops.

> [!WARNING]
> Do not sign in to ChatGPT in Codex while you use the gateway. A known bug in the
> desktop app ([openai/codex#48369](https://github.com/openai/codex/issues/48369)) disables
> the send button when the ChatGPT plan's usage runs out, even for a custom provider
> such as this one.

Limits:

- Stored-response retrieval is unsupported: `store` is always false, and `previous_response_id` is a 400. Codex sends `store: false`, never sends `previous_response_id` to a custom provider, and sends the whole conversation on every turn, so neither affects it. It also compacts a long conversation itself, with an ordinary `/v1/responses` request.
- Claude through Codex is a preview: Claude's reasoning is not carried from turn to turn.
- Codex sends no output limit: OpenAI gives the model its maximum, and the [hold](#your-balance-and-the-hold) counts at most 32,768 output tokens.
- When your balance runs out, Codex stops with "Quota exceeded. Check your plan and billing details.": that is the gateway's `insufficient_quota`. Add credits in [Billing](https://dev.routerplus.com/console/billing). Codex retries a rate limit only when the 429 carries `retry-after`, as the gateway's do.

## Cursor

Cursor's Chat and Agent can call the gateway with an OpenAI key and a base URL. You need a paid Cursor plan (Pro, Pro+, Ultra or Teams): on the free plan, outside keys do not work even when they are set up.

1. Open **Cursor Settings → Models**, and expand **API Keys** at the bottom.
2. Under **OpenAI API Key**, paste your `tm_vk_...` key and turn on **Use OpenAI API Key**.
3. Turn on **Override OpenAI Base URL** and enter `https://dev-api.routerplus.com/v1`.
4. Add the models by name in the model field on the same page: GPT models such as `gpt-6-astra`, `gpt-6.1-sol`, `gpt-6-luna` and `gpt-5.6-terra`, and the Claude models by their `rp-` names: `rp-sonnet-5-5`, `rp-opus-5-5`, `rp-haiku-5-5` and `rp-fable-5-1`.
5. Restart Cursor, open a new chat, and pick one of these models in Chat or Agent.

Use `rp-sonnet-5-5`, not `claude-sonnet-5-5`: Cursor sends a model name that starts with `claude-` with its Anthropic key, never to your base URL, and without an Anthropic key the request fails with "Model name is not valid". Each `rp-` name is exactly one Claude model, at that model's price (see [Claude names for Cursor](/docs/models#claude-names-for-cursor)).

Limits:

- Only Chat and Agent use your key; a subagent runs on its chat's model. Tab completion, Auto, the Cursor CLI and cloud agents always use Cursor's own models.
- While the override is on, Cursor sends every model that is not a Claude or Gemini model to the gateway: its own GPT models arrive under Cursor's own names, which the gateway may answer with a 404 that names them, and its Composer and Grok models fail. Turn **Use OpenAI API Key** off to use them again; your key and URL stay saved.
- If Cursor says that a name you add "is already available", the name is one of Cursor's own models; with the override on, that model also comes to the gateway, under Cursor's own name.
- Cursor calls the gateway from Cursor's servers, not from your computer. It sends no output limit, so the model gets its maximum and the [hold](#your-balance-and-the-hold) counts at most 32,768 output tokens. You cannot set a context window or a reasoning effort for a custom model.
- On a Teams or Enterprise plan, Cursor charges its own fee per token on requests with your key, and an admin can hide the API Keys section.
- Cursor edits files on GPT models with a custom (free-form) tool. The gateway supports custom tools on the GPT-6 and GPT-5.6 models; `gpt-4o`, `gpt-4o-mini` and `gpt-4.1-mini` take none, so pick a GPT-6 or GPT-5.6 model for Agent.

## Cline

Cline runs in VS Code, in JetBrains IDEs, as Cline Desktop and as a command-line tool. They share their settings in `~/.cline`. Use the **OpenAI Compatible** provider in each:

| Field | Value |
|---|---|
| API Provider | OpenAI Compatible |
| Base URL | `https://dev-api.routerplus.com/v1` |
| OpenAI Compatible API Key | `tm_vk_...` |
| Model ID | `claude-sonnet-5-5`, or any id from the catalog (**Use custom model ID…** if the list does not show it) |

Open **Model Configuration** too. Cline does not know the gateway's models, so it assumes a context window of 128,000 tokens:

- **Context Window Size:** the model's window, 1,000,000 for `claude-sonnet-5-5`.
- **Supports Images:** on, for the Claude 5, GPT-6 and GPT-5.6 models.
- **Max Output Tokens:** leave it empty. The model then gets its maximum, so a long answer or tool call is not cut short, and the [hold](#your-balance-and-the-hold) counts at most 32,768 output tokens. A number that you set is sent, and the hold counts all of it. The Cline CLI's file editor takes at most 6,000 characters in one edit, so there the model writes a long file in several edits, which can take several requests.
- **Input Price** and **Output Price** (per 1M tokens): the model's prices, if you want Cline's cost display to match your bill.

In JetBrains IDEs, install **Cline** from **Settings → Plugins → Marketplace** and open it from **View → Tool Windows → Cline**. In Cline Desktop, **Add Provider → OpenAI-Compatible Provider** takes the same base URL, key and model ids.

The Cline CLI (Node 20 or later) takes the same values:

```bash
npm install -g cline
cline auth --provider openai-compatible --apikey tm_vk_... --modelid claude-sonnet-5-5 --baseurl https://dev-api.routerplus.com/v1
cline "Add a README for this project"
```

Limits:

- Cline sends no cache marks; the gateway's [automatic caching](/docs/compat#automatic-caching-on-claude) covers it on Claude.
- On a rate limit Cline waits and tries again by itself, with no message while it waits ([When you hit a rate limit](#when-you-hit-a-rate-limit)).
- Pick the OpenAI Compatible provider, not Cline's own Anthropic or OpenAI providers: those send requests to the providers' own servers.

## Kilo Code

In Kilo Code for VS Code, open **Settings** (the gear icon) → **Providers**. Find **Custom provider** and click **Connect**:

| Field | Value |
|---|---|
| Provider ID | `routerplus` |
| Display name | RouterPlus |
| Provider API | OpenAI Compatible |
| Base URL | `https://dev-api.routerplus.com/v1` |
| API key | `tm_vk_...` |
| Models | `claude-sonnet-5-5`, `gpt-6-luna` and any other catalog id; turn on **Image** for the Claude 5, GPT-6 and GPT-5.6 models |

Then **Submit**. In JetBrains IDEs: **Settings → Kilo Code → Providers → Add custom provider**. Enter the Provider ID, Display name, Base URL and API key (or the name of an environment variable that holds the key). Type the model ids, separated by commas, in **Model IDs**, and click **Add**. This dialog has no Image switch: turn images on in `kilo.jsonc` (below).

The settings screen has no context window or output limit. Without a context window, Kilo Code compacts a long conversation only after the gateway refuses the prompt as too long. Set both in `~/.config/kilo/kilo.jsonc`, which the VS Code extension, the JetBrains plugin and the Kilo CLI (`npm install -g @kilocode/cli`, then `kilo`) all read:

```json
{
  "provider": {
    "routerplus": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "RouterPlus",
      "options": {
        "baseURL": "https://dev-api.routerplus.com/v1",
        "apiKey": "tm_vk_..."
      },
      "models": {
        "claude-sonnet-5-5": { "name": "Claude Sonnet 5.5", "modalities": { "input": ["text", "image"], "output": ["text"] }, "limit": { "context": 1000000, "output": 128000 } },
        "gpt-6-luna": { "name": "GPT-6 Luna", "modalities": { "input": ["text", "image"], "output": ["text"] }, "limit": { "context": 1050000, "output": 128000 } }
      }
    }
  },
  "model": "routerplus/claude-sonnet-5-5"
}
```

Keep `modalities` on each model: without it, Kilo Code sends no image to the model, and screenshots do not reach it.

Kilo Code sends `limit.output` as `max_tokens`, up to 32,000 unless you set `KILO_EXPERIMENTAL_OUTPUT_TOKEN_MAX` (128,000 is the models' whole maximum). A lower number keeps the [hold](#your-balance-and-the-hold) small.

> [!NOTE]
> Roo Code was shut down in May 2026, and its repository is archived. Use Kilo Code or
> Cline instead.

## OpenCode

OpenCode (the CLI and the desktop app) reads providers from `opencode.json`: globally at `~/.config/opencode/opencode.json`, or in a project's root. The desktop app reads the same file. Add the gateway with the OpenAI-compatible package, and list the models you want with their limits:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "routerplus": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "RouterPlus",
      "options": {
        "baseURL": "https://dev-api.routerplus.com/v1",
        "apiKey": "{env:TM_API_KEY}"
      },
      "models": {
        "claude-sonnet-5-5": { "name": "Claude Sonnet 5.5", "attachment": true, "modalities": { "input": ["text", "image"], "output": ["text"] }, "limit": { "context": 1000000, "output": 128000 } },
        "claude-opus-5-5": { "name": "Claude Opus 5.5", "attachment": true, "modalities": { "input": ["text", "image"], "output": ["text"] }, "limit": { "context": 1000000, "output": 128000 } },
        "gpt-6-luna": { "name": "GPT-6 Luna", "attachment": true, "modalities": { "input": ["text", "image"], "output": ["text"] }, "limit": { "context": 1050000, "output": 128000 } }
      }
    }
  },
  "model": "routerplus/claude-sonnet-5-5"
}
```

Export `TM_API_KEY` before you start OpenCode (the desktop app reads your login shell's variables), or store the key: run `/connect` in OpenCode (or `opencode auth login` in a shell), choose **Other**, enter the provider id `routerplus`, paste the key, and leave `apiKey` out of the file. Pick a model with `/models`, or start with `opencode -m routerplus/claude-sonnet-5-5`.

Limits:

- Screenshots need both `"attachment": true` and `"modalities": { "input": ["text", "image"], "output": ["text"] }` on the model. Without `modalities`, OpenCode sends no image, and the model answers that it cannot see one.
- OpenCode asks for at most 32,000 output tokens, even when `limit.output` is higher, unless you set `OPENCODE_EXPERIMENTAL_OUTPUT_TOKEN_MAX`. That also keeps the hold small.
- `@ai-sdk/openai-compatible` calls `/v1/chat/completions`, which serves every model.

## Other tools

Most tools that speak "OpenAI-compatible" take the same two values: **base URL** `https://dev-api.routerplus.com/v1` and **API key** `tm_vk_...`. Where a tool asks for the model's limits, use the table in [Before you start](#before-you-start).

### Goose

In the Goose desktop app: **Settings → Models → Configure providers → Add Custom Provider**. Choose the provider type **OpenAI Compatible**, a display name such as RouterPlus, the API URL `https://dev-api.routerplus.com/v1/chat/completions`, your key, and the model ids you want (for example `claude-sonnet-5-5, gpt-6-luna`), with streaming on. Then **Create Provider**. In the CLI, `goose configure` → **Custom Providers** → **Add A Custom Provider** asks for the same values.

Goose stores each custom provider as a file in `~/.config/goose/custom_providers/`. This one reads the key from `TM_API_KEY`:

```json
{
  "name": "custom_routerplus",
  "engine": "openai",
  "display_name": "RouterPlus",
  "description": "RouterPlus gateway",
  "api_key_env": "TM_API_KEY",
  "base_url": "https://dev-api.routerplus.com/v1/chat/completions",
  "models": [
    { "name": "claude-sonnet-5-5", "context_limit": 1000000 },
    { "name": "gpt-6-luna", "context_limit": 1050000 }
  ],
  "supports_streaming": true,
  "requires_auth": true
}
```

Start a session with `goose session --provider custom_routerplus --model claude-sonnet-5-5`. Goose calls GPT-6 and GPT-5 models on `/v1/responses` by itself, which the gateway serves. Set `GOOSE_MAX_TOKENS` to give Goose an output limit.

### Zed

Zed's agent takes an OpenAI-compatible provider in its `settings.json`. `max_tokens` is the model's context window:

```json
{
  "language_models": {
    "openai_compatible": {
      "routerplus": {
        "api_url": "https://dev-api.routerplus.com/v1",
        "available_models": [
          {
            "name": "claude-sonnet-5-5",
            "display_name": "Claude Sonnet 5.5",
            "max_tokens": 1000000,
            "max_output_tokens": 128000,
            "capabilities": { "tools": true, "images": true }
          },
          {
            "name": "gpt-6-luna",
            "display_name": "GPT-6 Luna",
            "max_tokens": 1050000,
            "max_output_tokens": 128000,
            "capabilities": { "tools": true, "images": true }
          }
        ]
      }
    }
  }
}
```

Enter the key in **Settings → AI → LLM Providers** (Zed keeps it in the system keychain), or set `ROUTERPLUS_API_KEY` in the environment. Do not put the key in `settings.json`. For Claude in Anthropic's format, Zed also has `anthropic_compatible` providers: the same shape, with `api_url` set to `https://dev-api.routerplus.com`, without `/v1`.

### VS Code chat with your own key

VS Code's built-in chat takes your own key, with no GitHub account and no Copilot plan (VS Code 1.122 or later). In the model picker, choose **Manage Language Models** → **Add Models** → **Custom Endpoint**, give it a name and your key, and pick the API type. VS Code then opens `chatLanguageModels.json`, where the models go:

```json
[
  {
    "name": "RouterPlus",
    "vendor": "customendpoint",
    "apiKey": "${input:routerplusApiKey}",
    "models": [
      {
        "id": "claude-sonnet-5-5",
        "name": "Claude Sonnet 5.5",
        "url": "https://dev-api.routerplus.com/v1/messages",
        "apiType": "messages",
        "toolCalling": true,
        "vision": true,
        "maxInputTokens": 872000,
        "maxOutputTokens": 128000
      },
      {
        "id": "gpt-6-luna",
        "name": "GPT-6 Luna",
        "url": "https://dev-api.routerplus.com/v1/responses",
        "apiType": "responses",
        "toolCalling": true,
        "vision": true,
        "maxInputTokens": 922000,
        "maxOutputTokens": 128000
      }
    ]
  }
]
```

`maxInputTokens` plus `maxOutputTokens` must fit the model's context window, and `toolCalling: true` puts a model in agent mode. Without a GitHub account, inline suggestions and semantic search do not work; set `chat.utilityModel` to one of these models so that titles and commit messages still work.

### Continue

In Continue's `~/.continue/config.yaml`:

```yaml
name: RouterPlus
version: 1.0.0
schema: v1
models:
  - name: Claude Sonnet 5.5
    provider: openai
    model: claude-sonnet-5-5
    apiBase: https://dev-api.routerplus.com/v1
    apiKey: tm_vk_...
    roles: [chat, edit, apply]
    capabilities: [tool_use]
    defaultCompletionOptions:
      contextLength: 1000000
      maxTokens: 32000
```

`tool_use` is what Agent mode needs. To keep the key out of the file, put `TM_API_KEY=tm_vk_...` in `~/.continue/.env` and refer to it from `apiKey` with Continue's secrets syntax.

### aider

```bash
export OPENAI_API_BASE=https://dev-api.routerplus.com/v1
export OPENAI_API_KEY=tm_vk_...
aider --model openai/claude-sonnet-5-5
```

aider warns that it does not know the model. To give it the limits, put a `.aider.model.metadata.json` in your home folder or the repository:

```json
{
  "openai/claude-sonnet-5-5": {
    "max_tokens": 128000,
    "max_input_tokens": 1000000,
    "max_output_tokens": 128000,
    "litellm_provider": "openai",
    "mode": "chat"
  }
}
```

aider sends no output limit, so the model gets its maximum, and the [hold](#your-balance-and-the-hold) counts at most 32,768 output tokens. For aider's diff edits, add `.aider.model.settings.yml`:

```yaml
- name: openai/claude-sonnet-5-5
  edit_format: diff
  use_repo_map: true
```

### Anything else

If a tool has a "base URL" box next to its OpenAI key box, those two values are the whole integration. Tool settings move from version to version; the two values do not.

## Apps from Replit, Lovable, Bolt and v0

These builders write your app with their own AI agents, which run on the builder's own models. The app they build can call RouterPlus with your key, for its own AI features. [Apps from Replit, Lovable, Bolt and v0](/docs/app-builders) has the prompt to paste and where the key goes.

## Playground

The [Playground](https://dev.routerplus.com/playground) runs in the browser: nothing to install. Pick any catalog model, and compare answers, costs and providers side by side. You can look around without an account; sending a prompt asks you to sign in or create an account. See [Playground](/docs/playground).

## SDKs inside the project your agent is editing

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

Full streaming examples for both surfaces are in the [Quickstart](/docs/quickstart); the Responses API is on [POST /v1/responses](/docs/api-responses); 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://dev.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://dev-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://dev.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://dev.routerplus.com/console/billing). Existing customers sign in at
   [https://dev.routerplus.com/login](https://dev.routerplus.com/login) with the same verified email and
   create a key at [API keys](https://dev.routerplus.com/console/keys), or copy an existing one from its row.
   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://dev.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://dev-api.routerplus.com/v1/chat/completions \
     -H "Authorization: Bearer $TM_API_KEY" \
     -H "content-type: application/json" \
     -d '{"model":"claude-haiku-5-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://dev.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, and each coding tool the user has, exactly as its section on this page shows (Claude Code, Codex, Cursor, Cline, Kilo Code, OpenCode, the others). Edit a tool's settings file only with the user's consent, and never write the key into a file that is committed.

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

   ```bash
   curl -s -H "Authorization: Bearer $TM_API_KEY" https://dev-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 and tools were wired, and the cost of the test call.

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

```bash
curl -s https://dev.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://dev.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://dev.routerplus.com/llms-full.txt](https://dev.routerplus.com/llms-full.txt).

## Signup requires the browser

Public signup and sign-in use Clerk at [Sign up](https://dev.routerplus.com/signup) and
[Sign in](https://dev.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
- [Apps from Replit, Lovable, Bolt and v0](/docs/app-builders) — the prompt that wires an app you build there
- [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
