Console
Developer tools

Coding agents

Set up Claude Code, Codex, Cursor and other coding agents.

Point a coding agent at RouterPlus to run it on any catalog model, billed to one balance. Each tool below has the same parts: requirements, setup steps, a config snippet and its limits through the gateway.

Tools: Claude Code, Codex, Cursor, Cline, Kilo Code, OpenCode, Hermes Agent and other tools.

Every docs page is served twice: /docs/<slug> rendered for people, and /docs/<slug>.md as raw markdown for agents. The machine index is https://demo.routerplus.com/llms.txt.

Before you start

  1. 01

    Get a key. Open Sign up, complete Clerk authentication and email verification, and save the first key shown after sign-in. Buy credits in Billing. Signup 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.
    • To create more keys, open Access > API keys in the console (API keys). A key looks like tm_vk_.... Give each tool its own key.
  2. 02

    Pick the base URL. Tools that speak OpenAI's format use https://demo-api.routerplus.com/v1. Tools that speak Anthropic's format (Claude Code) use https://demo-api.routerplus.com, without /v1.

  3. 03

    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://demo.routerplus.com/api/models.json.

    Model idName in CursorContextMax outputInput /1MCached /1MCache write /1MOutput /1M
    claude-opus-5-5rp-opus-5-51,000,000128,000$4$0.20$5$20
    claude-fable-5-1rp-fable-5-11,000,000128,000$10$0.25$12.50$50
    claude-sonnet-5-5rp-sonnet-5-51,000,000128,000$2$0.10$2.50$10
    claude-haiku-5-5rp-haiku-5-51,000,000128,000$0.10$0.01$0.125$0.50
    gpt-6-astragpt-6-astra1,050,000128,000$10$1$12.50$50
    gpt-6.1-solgpt-6.1-sol1,050,000128,000$2$0.10$2.50$10
    gpt-6-lunagpt-6-luna1,050,000128,000$0.10$0.01$0.125$0.50
    gpt-5.6-terragpt-5.6-terra1,050,000128,000$2$0.20$2.50$12
    gpt-6-solgpt-6-sol1,050,000128,000$2$0.20$2.50$10
    gpt-5.6-solgpt-5.6-sol1,050,000128,000$4$0.40$5$20
    gpt-5.6-lunagpt-5.6-luna1,050,000128,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

  • Full-length answers. When an agent sends no output limit, the model gets its own maximum: 128,000 tokens on the models above, fitted to the context window on the chat surfaces. The hold counts at most 32,768 of them.
  • Prompt caching on Claude. When a conversation carries no cache marks, the gateway turns on Claude's automatic caching. The x-tm-auto-cache response header says whether it did.
  • 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.
  • Compaction. 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. A 502 or 504 is the exception: it is Cloudflare's own short error page, without the message or x-request-id (see 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. The request does not fail.
  • Cancels. When you stop an answer (Esc, Stop), you pay for the input and the output already streamed. You never pay the full hold.
  • Hidden thinking. The Claude 5 models do not show their thinking. 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 the input plus the output limit. A limit that the tool sends is held in full. With no limit, the hold counts 32,768 output tokens. Agents often run several requests at once. The output part of the hold per request:

ModelHold for 32,768 output tokens
Claude Fable 5.1, GPT-6 Astra$1.64
Claude Opus 5.5, GPT-5.6 Sol$0.66
GPT-5.6 Terra$0.39
Claude Sonnet 5.5, GPT-6.1 Sol, GPT-6 Sol$0.33
GPT-5.6 Luna$0.04
Claude Haiku 5.5, GPT-6 Luna$0.02
Warning

You pay for what a request used, so a long answer can cost more than its hold. A small balance can refuse a request (insufficient_quota) before it starts. Then pick a cheaper model, or keep the tool's output limit small (each tool's section shows how).

When you hit a rate limit

A request over one of your limits gets a 429, or a 503 when the gateway as a whole is full. Its retry-after header gives the seconds to wait, from 1 to 59:

  • For a one-minute limit: the time until its window has room again.
  • For a limit on requests at once: 10 seconds. The limit frees when one of your running requests ends.

Most coding agents wait and try again by themselves:

ToolWhat it does on a 429
Claude Codewaits at least retry-after and tries again, up to 10 times (CLAUDE_CODE_MAX_RETRIES, at most 15)
Codexwaits 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]
Cursordoes not try again. It shows the error, so send your message again after the wait
Clinewaits 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, OpenCodewait 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 retries can wait it out. If not, add credits in Billing. Codex stops on it at once. Claude Code stops at once on a monthly spend cap, because that 429 says not to retry.

Claude Code

Claude Code speaks Anthropic's format, which the gateway's /v1/messages surface accepts as sent. 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

Requirements: the claude CLI and a tm_vk_... key.

Setup:

  1. 01

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

    json
    {
      "env": {
        "ANTHROPIC_BASE_URL": "https://demo-api.routerplus.com",
        "ANTHROPIC_AUTH_TOKEN": "tm_vk_..."
      }
    }
  2. 02

    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.

  3. 03

    At the folder trust question, choose Yes, I trust this folder. The default, No, exit, closes Claude Code.

  4. 04

    Run /status to check 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://dev2-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", and the default No opens the login screen. If that happened, choose the custom API key in /config. You do not need a claude.ai sign-in: ANTHROPIC_AUTH_TOKEN comes first. For headless or CI use, give Claude Code a fresh config directory: CLAUDE_CONFIG_DIR=$(mktemp -d) ANTHROPIC_BASE_URL=https://demo-api.routerplus.com ANTHROPIC_AUTH_TOKEN=$TM_API_KEY claude -p "..."

How the gateway handles Claude Code:

  • ANTHROPIC_AUTH_TOKEN goes as Authorization: Bearer …, which the gateway accepts everywhere, as it does x-api-key.
  • Query strings (/v1/messages?beta=true) pass through. The gateway routes on the path.
  • Dated ids (claude-haiku-4-5-20251001) resolve to their model, and the original id goes to the provider (see Models & catalog). An unknown id gets a 404 that names it.
  • The gateway forwards the anthropic-beta values Claude Code needs on the Claude 5 models (Opus 5.5, Fable 5.1, Sonnet 5.5, Haiku 5.5): effort inside a message, context editing (context_management), and tools added during a session. Wire compatibility lists them all.
  • Claude Code's own cache marks work as on Anthropic's API.
  • Web search works, at Anthropic's price per search (see Pricing & billing).
  • A conversation that outgrows the window gets Anthropic's prompt is too long error, which Claude Code compacts on.
  • Every request appears in https://demo-api.routerplus.com/v1/usage with its token counts and cost_usd.
  • Claude Code does not know the context windows of open models and assumes 200,000 tokens. Set CLAUDE_CODE_MAX_CONTEXT_TOKENS to the model's window, for example CLAUDE_CODE_MAX_CONTEXT_TOKENS=1000000 for moonshotai/kimi-k3.

Limits:

  • Remote Control does not work through the gateway. It needs a claude.ai subscription sign-in. Claude Code turns it off when ANTHROPIC_BASE_URL points at a host other than api.anthropic.com, or when ANTHROPIC_AUTH_TOKEN or ANTHROPIC_API_KEY is set. To use Remote Control, start that session without the gateway variables and sign in with claude.ai.
  • Voice dictation is off while a gateway key is in use.
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. Any other path that an authenticated tool probes gets a well-formed 404 with error_type: not_found in the caller's own dialect. It does not hang or return an HTML page.

Claude Code in VS Code

Requirements: VS Code 1.94 or later and the Claude Code extension.

Setup: the setting must be in your user settings. Run Preferences: Open User Settings (JSON) and add:

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

claudeCode.disableLoginPrompt stops the sign-in prompt. The extension reads ~/.claude/settings.json only for the process it starts, not for its own sign-in check, so put the key in claudeCode.environmentVariables.

Limits: through a gateway, the extension shows no plan usage bars, no voice dictation and no Web tab.

Claude Code in JetBrains IDEs

Requirements: the Claude Code CLI. The plugin for JetBrains IDEs (IntelliJ IDEA, PyCharm, WebStorm and the others) does not include it.

Setup:

  1. 01
    Set up the CLI as in Claude Code CLI. The plugin runs the claude command in the IDE's terminal and uses ~/.claude/settings.json.
  2. 02
    If the IDE cannot find the CLI, set its path in Settings → Tools → Claude Code [Beta] → Claude command.

Claude desktop app

Requirements: the Claude desktop app on macOS or Windows. The app sends its requests to a gateway in third-party mode.

Setup:

  1. 01
    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. 02
    Developer → Configure Third-Party Inference…
  3. 03
    Under Connection, set Inference provider to Gateway.
  4. 04
    Under Gateway credentials, set:
    • Gateway base URL: https://demo-api.routerplus.com (without /v1)
    • Gateway API key: your tm_vk_... key
    • Credential kind: Static API key
    • Gateway auth scheme: Bearer
  5. 05
    Apply Changes, then Save & Restart.
  6. 06
    On the sign-in screen, start in third-party mode. Do not sign in to claude.ai or create an Anthropic account.

An administrator can set the same values for a whole company with managed settings: inferenceProvider: "gateway", inferenceGatewayBaseUrl, inferenceGatewayApiKey, inferenceGatewayAuthScheme: "bearer".

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 work. Web search works, and the gateway passes it to Anthropic.

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 max_output_tokens. The hold is the input plus that output: about $2.56 per request on Opus 5.5 and $3.20 on Fable 5.1.

    • You pay for the tokens the provider reports.
    • An interrupt (Esc) costs the input and the output already streamed. An interrupt while the model thinks costs the input only, because the Claude 5 models do not show their thinking.
    • 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; in tests, file edits and simple commands needed no check).

    • Each check is a separate request to claude-sonnet-5 with the conversation, billed 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 stop the notice, set CLAUDE_CODE_AUTO_MODE_SERVER=0.
    • To avoid the checks, press Shift+Tab to change to another permission mode.
  • Advisor. Do not turn on /advisor. It runs a second model 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 retries without the advisor and leaves it off until it exits.

Pinning which models Claude Code uses

Claude Code picks its own model ids. Set them with the standard variables, in the shell or in the env block of settings.json, with 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. Otherwise, behind a gateway, background tasks run on the main model (Opus 5.5 by default).
  • 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.
  • ANTHROPIC_DEFAULT_OPUS_MODEL, ANTHROPIC_DEFAULT_SONNET_MODEL, ANTHROPIC_DEFAULT_FABLE_MODEL and CLAUDE_CODE_SUBAGENT_MODEL pin the others.
  • ANTHROPIC_MODEL overrides your /model choice at every launch. To set only the starting model, use ANTHROPIC_DEFAULT_MODEL (Claude Code 2.1.236 or later).
  • Inside a session, /model accepts any catalog id.

Spend from every session appears per request in the console under Usage (Usage) and in https://demo-api.routerplus.com/v1/usage.

Codex

Codex calls the Responses API, which the gateway serves at POST /v1/responses.

Requirements: Codex (the CLI, the IDE extension, or the desktop app, which is Codex in the ChatGPT desktop app). All of them read one file, ~/.codex/config.toml. The CLI needs no sign-in for this provider.

Setup:

  1. 01

    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://demo-api.routerplus.com/v1"
    env_key = "TM_API_KEY"
    wire_api = "responses"
  2. 02

    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.
  • wire_api = "responses" is Codex's default, so you can 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 your shell's variables when started from the Dock or Finder. Put the key in the provider block instead of env_key, never both: Codex fails when env_key names a missing variable.

toml
[model_providers.routerplus]
name = "RouterPlus"
base_url = "https://demo-api.routerplus.com/v1"
wire_api = "responses"
experimental_bearer_token = "tm_vk_..."
  • The file then holds your key. Do not 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 warns "Model metadata for claude-sonnet-5-5 not found. Defaulting to fallback metadata". Only a full model catalog of your own (model_catalog_json) removes the warning.
  • Codex caps model_context_window at 272,000 tokens for an unknown id, so set that.
  • Codex ignores model_max_output_tokens, with a warning.
  • web_search = "disabled" stops Codex from sending its hosted web search tool, which does not run on Claude (the gateway would drop it and name it in x-tm-dropped-params).
  • model_reasoning_effort becomes Claude's output_config.effort. minimal becomes low. none turns thinking off on Claude Haiku 5.5, Sonnet 5 and Opus 5, and is low on the other Claude models. On Claude Sonnet 4.5 and Haiku 4.5 it is dropped and named in x-tm-dropped-params.
Warning

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

Limits:

  • Stored responses are not supported: store is always false, and previous_response_id is a 400. Codex is not affected: it sends store: false and the full conversation on every turn, and compacts with an ordinary /v1/responses request.
  • Claude through Codex is a preview. Claude's reasoning does not carry from turn to turn.
  • Codex sends no output limit (see the hold).
  • When your balance runs out, Codex stops with "Quota exceeded. Check your plan and billing details." This is the gateway's insufficient_quota. Add credits in Billing.
  • Codex retries a rate limit only when the 429 carries retry-after. The gateway's 429s do.

Cursor

Cursor's Chat and Agent can call the gateway with an OpenAI key and a base URL.

Requirements: a paid Cursor plan (Pro, Pro+, Ultra or Teams). On the free plan, outside keys do not work even when they are set up.

Setup:

  1. 01
    Open Cursor Settings → Models, and expand API Keys at the bottom.
  2. 02
    Under OpenAI API Key, paste your tm_vk_... key and turn on Use OpenAI API Key.
  3. 03
    Turn on Override OpenAI Base URL and enter https://demo-api.routerplus.com/v1.
  4. 04
    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.
    • Claude models by their rp- names: rp-sonnet-5-5, rp-opus-5-5, rp-haiku-5-5 and rp-fable-5-1.
  5. 05
    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 name that starts with claude- with its Anthropic key, never to your base URL, and without that key it fails with "Model name is not valid". Each rp- name is one Claude model at its price (see 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 Claude or Gemini to the gateway. Its own GPT models arrive under Cursor's names and may get a 404. Its Composer and Grok models fail. Turn Use OpenAI API Key off to use them; your key and URL stay saved.
  • If Cursor says a name you add "is already available", it is one of Cursor's own models, and with the override on it comes to the gateway under Cursor's name.
  • Cursor calls the gateway from Cursor's servers, not from your computer.
  • Cursor sends no output limit (see the hold).
  • 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, which the gateway supports on the GPT-6 and GPT-5.6 models. gpt-4o, gpt-4o-mini and gpt-4.1-mini take none, so use a GPT-6 or GPT-5.6 model for Agent.

Cline

Requirements: Cline in VS Code, in a JetBrains IDE, as Cline Desktop, or as the Cline CLI (Node 20 or later). All of them share their settings in ~/.cline.

Setup:

  1. 01

    Pick the OpenAI Compatible provider and set these fields:

    FieldValue
    API ProviderOpenAI Compatible
    Base URLhttps://demo-api.routerplus.com/v1
    OpenAI Compatible API Keytm_vk_...
    Model IDclaude-sonnet-5-5, or any id from the catalog (Use custom model ID… if the list does not show it)
  2. 02

    Open Model Configuration. Cline assumes a 128,000-token context window for unknown models. Set:

    • 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, so the model gets its maximum and the hold stays at 32,768 output tokens. A number that you set is sent and held in full.
    • Input Price and Output Price (per 1M tokens): the model's prices, if you want Cline's cost display to match your bill.

Where to set it in each Cline:

  • JetBrains IDEs: install Cline from Settings → Plugins → Marketplace and open it from View → Tool Windows → Cline.
  • Cline Desktop: Add Provider → OpenAI-Compatible Provider takes the same base URL, key and model ids.
  • Cline CLI takes the same values:
bash
npm install -g cline
cline auth --provider openai-compatible --apikey tm_vk_... --modelid claude-sonnet-5-5 --baseurl https://dev2-api.routerplus.com/v1
cline "Add a README for this project"

Limits:

  • Cline sends no cache marks. The gateway's automatic caching 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).
  • The Cline CLI's file editor takes at most 6,000 characters per edit, so a long file takes several edits and requests.
  • Cline's own Anthropic and OpenAI providers go to those providers' servers. Use OpenAI Compatible.

Kilo Code

Requirements: Kilo Code for VS Code, the Kilo Code plugin for JetBrains IDEs, or the Kilo CLI (npm install -g @kilocode/cli, then kilo).

Setup in VS Code: open Settings (the gear icon) → Providers. Find Custom provider, click Connect, fill in these fields and click Submit:

FieldValue
Provider IDrouterplus
Display nameRouterPlus
Provider APIOpenAI Compatible
Base URLhttps://demo-api.routerplus.com/v1
API keytm_vk_...
Modelsclaude-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

Setup in JetBrains IDEs: open Settings → Kilo Code → Providers → Add custom provider.

  1. 01
    Enter the Provider ID, Display name, Base URL and API key (or the name of an environment variable that holds the key).
  2. 02
    Type the model ids, separated by commas, in Model IDs, and click Add.
  3. 03
    This dialog has no Image switch. Turn images on in kilo.jsonc (below).

Config: set the context window and output limit in ~/.config/kilo/kilo.jsonc, which the VS Code extension, the JetBrains plugin and the Kilo CLI all read. The settings screen has neither, and without a context window Kilo Code compacts only after the gateway refuses a prompt as too long:

json
{
  "provider": {
    "routerplus": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "RouterPlus",
      "options": {
        "baseURL": "https://demo-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"
}

Limits:

  • Keep modalities on each model. Without it, Kilo Code sends no images.
  • 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' maximum). A lower number keeps the hold small.
Note

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

OpenCode

Requirements: OpenCode, the CLI or the desktop app. Both read providers from opencode.json, globally at ~/.config/opencode/opencode.json or in a project's root.

Setup:

  1. 01

    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://demo-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"
    }
  2. 02

    Give OpenCode the key in one of two ways:

    • Export TM_API_KEY before you start OpenCode. The desktop app reads your login shell's variables.
    • 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.
  3. 03

    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.
  • 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.

Hermes Agent

Requirements: Hermes Agent. It reads its endpoint from config.yaml in its home folder (~/.hermes, or the folder in HERMES_HOME).

Setup:

  1. 01

    Add the gateway as a custom endpoint in config.yaml:

    yaml
    model:
      provider: custom
      base_url: https://demo-api.routerplus.com/v1
      api_key: ${TM_API_KEY}
      default: claude-sonnet-5-5
  2. 02

    Run Hermes with the key in the environment:

    bash
    export TM_API_KEY=tm_vk_...
    hermes
  • Hermes calls /v1/chat/completions with the key as a bearer token. Every catalog model works, for example moonshotai/kimi-k3 or deepseek/deepseek-v4.1-flash.
  • Hermes reads each model's context window from GET /v1/models. To set it yourself, add context_length: with the model's window.
  • To call Claude on /v1/messages, set base_url: https://demo-api.routerplus.com and add api_mode: anthropic_messages.
  • For one task without a session, run hermes chat -q "...". Add --yolo only if you accept that shell commands run without a prompt.

Limits: Hermes sends no output limit, so the hold counts at most 32,768 output tokens.

Other tools

Most tools that speak "OpenAI-compatible" take the same two values: base URL https://demo-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.

Goose

Requirements: the Goose desktop app or the Goose CLI.

Setup in the desktop app: open Settings → Models → Configure providers → Add Custom Provider.

  1. 01
    Choose the provider type OpenAI Compatible.
  2. 02
    Enter a display name such as RouterPlus, the API URL https://demo-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.
  3. 03
    Click Create Provider.

Setup in the CLI: goose configure → Custom Providers → Add A Custom Provider asks for the same values.

Config: 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://demo-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.

Limits:

  • 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

Requirements: Zed's agent.

Setup:

  1. 01
    Add an OpenAI-compatible provider to Zed's settings.json (below). max_tokens is the model's context window.
  2. 02
    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.
json
{
  "language_models": {
    "openai_compatible": {
      "routerplus": {
        "api_url": "https://demo-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 }
          }
        ]
      }
    }
  }
}

For Claude in Anthropic's format, Zed also has anthropic_compatible providers. They have the same shape, with api_url set to https://demo-api.routerplus.com, without /v1.

VS Code chat with your own key

Requirements: VS Code 1.122 or later. VS Code's built-in chat takes your own key, with no GitHub account and no Copilot plan.

Setup:

  1. 01
    In the model picker, choose Manage Language Models → Add Models → Custom Endpoint.
  2. 02
    Give it a name and your key, and pick the API type.
  3. 03
    VS Code opens chatLanguageModels.json. Add the models there:
json
[
  {
    "name": "RouterPlus",
    "vendor": "customendpoint",
    "apiKey": "${input:routerplusApiKey}",
    "models": [
      {
        "id": "claude-sonnet-5-5",
        "name": "Claude Sonnet 5.5",
        "url": "https://demo-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://demo-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.
  • toolCalling: true puts a model in agent mode.

Limits: without a GitHub account, inline suggestions and semantic search do not work. Set chat.utilityModel to one of these models for titles and commit messages.

Continue

Requirements: Continue. Agent mode needs tool_use.

Config: in ~/.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://demo-api.routerplus.com/v1
    apiKey: tm_vk_...
    roles: [chat, edit, apply]
    capabilities: [tool_use]
    defaultCompletionOptions:
      contextLength: 1000000
      maxTokens: 32000

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

Setup:

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

Config: 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"
  }
}

For aider's diff edits, add .aider.model.settings.yml:

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

Limits: aider sends no output limit (see the hold).

Anything else

If a tool has a "base URL" box next to its OpenAI key box, set those two values.

Playground

The Playground runs in the browser. Compare any catalog models' answers, costs and providers side by side. Sending a prompt needs an account. See Playground.

SDKs inside the project your agent is editing

ClientChange
OpenAI SDK (any language)base_url = "https://demo-api.routerplus.com/v1", api_key = TM_API_KEY
Anthropic SDK (any language)base_url = "https://demo-api.routerplus.com", api_key = TM_API_KEY
Raw HTTPhost → https://demo-api.routerplus.com, key in Authorization: Bearer or x-api-key

The installation runbook

A coding agent can run this section. Give it to your agent (read https://demo.routerplus.com/docs/install.md and get me set up), or follow 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 that has a cost field, and https://demo-api.routerplus.com/v1/usage shows the request.

  1. 01

    Get a key (skip if TM_API_KEY is already set).

    • The user opens Sign up, completes Clerk authentication and email verification, and saves the first key shown after sign-in.
    • Signup does not grant free credit. The user adds paid credits in Billing.
    • Existing customers sign in at https://demo.routerplus.com/login with the same verified email. They create a key at API keys, or copy an existing one from its row.
    • Account creation has no terminal API. Signup and sign-in use Clerk in the browser, and a public signup response has no dev_verify_link. Do not call the retired POST /v1/signup or local POST /login routes, or the retired magic-link submission. Continue client setup when the key is available.
  2. 02

    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. 03

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

    bash
    curl -s https://demo.routerplus.com/api/models.json
  4. 04

    Make the test call on the OpenAI-compatible surface. It works for every chat model, including Claude models, because the gateway translates:

    bash
    curl -N https://dev2-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 that ends with a usage chunk with a cost field, then data: [DONE].

    On HTTP 429 with error_type: insufficient_quota, stop. Ask the user to check their balance and spend caps in Billing. Retry once after they fix the cause, never in a loop. Errors gives the retry rules for each error class.

  5. 05

    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
    • each coding tool the user has, 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. Never write the key into a file that is committed.

  6. 06

    Verify billing. This is the done-when condition:

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

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

  7. 07

    Optional, recommended: add attribution headers to the user's app: HTTP-Referer: https://the-users-app.example and X-Title: The App Name. They identify the app for per-app analytics and carry no content.

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://demo.routerplus.com/llms.txt

/llms.txt has the gateway base URL, browser signup instructions, a raw-markdown link to every doc page, and the model catalog. Its first link is the Agent integration guide. https://demo.routerplus.com/llms-full.txt has every page in one fetch.

Next steps

For agents: /docs/install.md and /llms.txt