Claude Code Router setup with one API key
claude-code-router puts GLM, DeepSeek and Kimi behind Claude Code’s Anthropic-format calls. One provider on this base URL, tested end to end; the Claude models need no router at all.
At the end of this page Claude Code runs GLM 5.3, DeepSeek V4 Pro and Kimi K3 through claude-code-router on one API key, with the Claude models left native. The config below is the one we tested on 2026-10-19: one request through the router to GLM 5.3 answered in 12.7 seconds and was charged $0.0178 at the live rate.
Do you need the router?
For the Claude models, no. They answer the Anthropic format on this base URL, so Claude Code on an API key is two environment variables and prompt caching keeps working. The router exists for the other models: a GLM, DeepSeek, Kimi, GPT or Gemini id sent in the Anthropic format returns a 400 that says the model is served in the openai format. Claude Code Router takes the Anthropic-format request from Claude Code and re-sends it in the OpenAI format to the provider you name.
Today 12 ids on the key answer the Anthropic format and 255 answer the OpenAI format only (wire_formats in GET https://api.uplinkswitch.com/v1/catalog). If you want the second group inside Claude Code, read on. If you only want them in a terminal agent, OpenCode and Kilo Code take them without a router.
Prerequisites
- Node.js 22 or newer and npm (the CLI's requirement, read 2026-10-19). We ran 22.23.1.
- Claude Code installed;
claudeon your PATH. - A key from the console, prepaid from $10.
- The ids you want, from the Models page or
GET https://api.uplinkswitch.com/v1/models. Only ids that answer the OpenAI format need the router.
Install claude-code-router
claude-code-router (musistudio, MIT) ships as a desktop app, an npm CLI and a Docker image. This guide uses the npm CLI, version 3.1.3 on 2026-10-19:
node --version # 22 or newer
npm install -g @musistudio/claude-code-router
ccr --helpThe CLI keeps its configuration in ~/.claude-code-router/config.sqlite and its request log in app-data/usage.sqlite next to it (CLI reference, read 2026-10-19). The management UI listens on port 3458 and the model gateway on 3456.
The provider block for one key
Version 3.1.3 edits providers in its browser UI, and reads an older-style config.json from ~/.claude-code-router once, on first start, and imports it. We wrote this file before the first start and the provider came through intact; the same fields are what the UI asks for under Providers, Add Provider, Other / custom API endpoint.
{
"APIKEY": "a-client-key-you-choose",
"HOST": "127.0.0.1",
"PORT": 3456,
"Providers": [
{
"name": "uplinkswitch",
"api_base_url": "https://api.uplinkswitch.com/v1/chat/completions",
"api_key": "sk-uplink-live-...",
"models": ["glm-5.3", "deepseek-v4-pro-0813", "kimi-k3"]
}
]
}api_base_urlis the full chat-completions path. The router detected the OpenAI Chat protocol from it; pick it by hand under Advanced settings if detection misses.api_keyis your UplinkSwitch key. It goes to the router only; Claude Code never sees it.APIKEYis the client key Claude Code will present to the router. The import stored it on the API Keys page as "API Key 1".modelslists the ids to route. Any id whosewire_formatsincludesopenaiworks here; the Claude ids can be listed too, but they do not need to be.
In older versions a Router object with default, background, think and longContext keys picked the model per task. The import dropped those keys in our test; in 3.1.3 that routing lives under Routing in the UI as ordered rules, and the model Claude Code asks for is used as it is. The simplest route is no rule at all and --model on the command line, which is what we tested.
Start the router
ccr serve --no-open
# CCR web management is running at http://127.0.0.1:3458/?ccr_web_token=...
curl -s http://127.0.0.1:3456/health
# {"runtimeId":"...","status":"ok","timestamp":"..."}ccr serve stays in the foreground and prints errors; ccr start runs the same service in the background and ccr ui opens the browser. The management URL carries a token: treat it as a password. /health on port 3456 answers only after a provider and a model are configured; on an empty configuration the gateway refuses to start and says so.
Check it works
Send the router one Anthropic-format request with the client key, the same shape Claude Code sends:
curl -s http://127.0.0.1:3456/v1/messages \
-H "x-api-key: a-client-key-you-choose" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model": "glm-5.3", "max_tokens": 64, "messages": [{"role": "user", "content": "Reply with the single word ok."}]}'
# {"type":"message","role":"assistant","model":"glm-5.3","content":[{"type":"thinking","thinking":"..."},{"type":"text","text":"ok"}],"stop_reason":"end_turn","usage":{"input_tokens":19,"output_tokens":16}}That is the answer we got on 2026-10-19: GLM 5.3 thinks briefly, then writes ok; set max_tokens high enough for the thinking block. Then run Claude Code against the router:
export ANTHROPIC_BASE_URL="http://127.0.0.1:3456"
export ANTHROPIC_API_KEY="a-client-key-you-choose"
claude --model glm-5.3Our run: claude -p "Reply with the single word ok." --model glm-5.3 returned "ok" after 12.7 seconds of model time. Claude Code printed a notice that it did not recognize the model name, then used it. The router's log recorded request e946d593-b69f-4c0d-8c7f-0e7d3c3a6044 at 2026-10-19 19:32:44 UTC: provider uplinkswitch, model glm-5.3, status 200, 53,368 input, 768 cached and 259 output tokens. Claude Code's system prompt and tool list are the input; the prompt itself is a few words.
The router does not forward our x-uplink-request-id header to Claude Code, so match the request in the console usage log by time and token count; it lands there within about a minute, with its signed receipt. The router also generated a Claude Code profile and a wrapper script under ~/.claude-code-router/bin that exports the same two variables, so ccr followed by the profile name launches Claude Code already pointed at the gateway.
Keep the Claude models native
For Claude Sonnet, Opus and Haiku, skip the router: point Claude Code at this base URL directly and the Anthropic format, prompt caching and the ANTHROPIC_DEFAULT_*_MODEL variables all work as Anthropic sends them. Two shells, two sets of variables, one key.
# No router: the Claude models answer the Anthropic format here
export ANTHROPIC_BASE_URL="https://api.uplinkswitch.com/v1"
export ANTHROPIC_AUTH_TOKEN="sk-uplink-live-..."
claude --model claude-sonnet-5-5The Claude Code guide has the settings.json form, the VS Code setting and the model variables; Anthropic's setup docs list every variable Claude Code reads.
What it costs
The router bills nothing. The model bills per token at the rate on its page, whichever path the request took:
| Model | Path | Input / cached / output per 1M | Developer list, in / out | Under list, out | One Claude Code turn |
|---|---|---|---|---|---|
| Claude Sonnet 5.5 | native, no router | $1.20 / $0.075 / $3.00 | $2.00 / $10.00 | 70% | $0.0129 |
| Claude Haiku 5.5 | native, no router | $0.06 / $0.01 / $0.15 | $0.10 / $0.50 | 70% | $0.0011 |
| GLM 5.3 | router | $0.3276 / $0.068 / $1.0296 | $1.092 / $3.432 | 70% | $0.0076 |
| DeepSeek V4 Pro 0813 | router | $0.792 / $0.0625 / $1.188 | $1.32 / $3.96 | 70% | $0.0084 |
| Kimi K3 | router | $0.90 / $0.12 / $4.50 | $3.00 / $15.00 | 70% | $0.0182 |
USD, live from GET /v1/catalog. A Claude Code turn is 80,000 cached, 2,000 input and 1,500 output tokens, the late-session shape from the Claude Code pricing post.
The test request above, 53,368 input, 768 cached and 259 output tokens on GLM 5.3, is $0.0178 at the live rate and $0.0593 at Z.ai's list. The two estimates the tools printed are neither: the router guessed $0.0279 from the public list price, and Claude Code guessed $0.2188 with a cost basis it labelled unknown. The receipt in the console is the bill. The same turn shape on Claude Sonnet 5.5, native, is $0.0129 here against $0.027 at list. The Claude Code pricing post works a day and a month at these rates.
Today's real-model verdicts for the five: Claude Sonnet 5.5, same fingerprint since oct 12; Claude Haiku 5.5, same fingerprint since oct 19; GLM 5.3, same fingerprint since oct 12; DeepSeek V4 Pro 0813, same fingerprint since oct 12; Kimi K3, same fingerprint since oct 12, live from the daily real-model check.
Troubleshooting
400saying the model is served in the openai format: a non-Claude id reached this base URL in the Anthropic format. Send it through the router, or use a Claude id natively.- "No available models. Configure at least one provider with a model before starting CCR Gateway": the router's own message when the provider list is empty; the management UI still starts. Add the provider, then start the Server.
401from the router: the client key inANTHROPIC_API_KEYdoes not match the API Keys page.401 invalid_api_keyfrom this base URL: the provider key is wrong or revoked, and a key in the URL is refused.402 insufficient_balance: top up in the console.402 monthly_limit_reached: the key hit the monthly spend limit set on it.403 scope_denied: the key is allowlisted to other models; add the id or use another key.- "model not found" in the router log: the id Claude Code asked for is not in the provider's models list; the router compares the three places the name appears (its Q&A, read 2026-10-19).
- A thinking-only answer cut at
max_tokens: GLM and DeepSeek think before they write; raise the limit in a hand-made request. Claude Code sets its own.
Docker, GLM, Ollama, OpenAI
Docker: the repository's Compose file runs the gateway and the UI behind one Nginx port, 3458, with data under /data, and the provider and client key are configured the same way (its Docker guide, read 2026-10-19). GLM: the block above is the GLM 5.3 setup, and GLM API pricing has every GLM id. Ollama: a local model on your machine, which the router also supports as a provider; outside this page, which is about hosted models on one key. OpenAI: the OpenAI Chat protocol is the one the router uses for this provider, and GPT ids such as GPT-6.1 Sol go in the same models list.
The same ids without any router: the five tools in Claude Code alternatives and the LLM API pricing comparison for every chat model on the key. Get a key: prepaid from $10, no subscription, 30-day price lock, in the console.
Questions
- What does a Claude Code router do?
- Claude Code Router is a local model gateway and control plane for coding agents (its README, read 2026-10-19): Claude Code sends its Anthropic-format requests to a local port, and the router forwards them to the provider and model you configured, in that provider's own format, with logs, routing rules and fallbacks in between. On this key it is the way to run GLM, DeepSeek, Kimi or GPT inside Claude Code, because those models answer the OpenAI format and Claude Code only speaks Anthropic's.
- Can I use Claude Code with an OpenRouter?
- Yes, through the router: Claude Code Router ships an OpenRouter preset among its providers, and a custom endpoint works the same way. This guide uses a custom endpoint on https://api.uplinkswitch.com/v1, which serves the same ids in the OpenAI format at the rates in the table above and no fee on the credit; the OpenRouter alternatives page compares the two.
- Can Claude Code go on the internet?
- Claude Code has web fetch and web search tools of its own, and they still work when its model requests go through the router. What changes is only where the model request goes; the tools run on your machine.
- How do I connect the router to Claude Code?
- Two environment variables point Claude Code at the local gateway: ANTHROPIC_BASE_URL=http://127.0.0.1:3456 and ANTHROPIC_API_KEY set to the client key you chose in the router. Then run claude with --model and an id from your provider block. The router also generates a Claude Code profile and a wrapper script that sets the same variables; ccr <profile-name> launches it.
- What goes in the Claude Code Router config.json?
- Version 3.1.3 keeps its configuration in config.sqlite under ~/.claude-code-router and edits it in the browser UI. It still reads an older-style config.json from that folder once on first start and imports it: the Providers array (name, api_base_url, api_key, models) and APIKEY came through in our test, the old Router.default keys did not. The block on this page is that file.
- Can Claude Code Router use GLM, DeepSeek or Kimi?
- Yes. Any id on this key that answers the OpenAI format goes in the provider's models list; GLM 5.3, DeepSeek V4 Pro 0813 and Kimi K3 are the three in the block above, and the test run on 2026-10-19 went to GLM 5.3. The price table above has their rates next to the developer's list.
- Do I need the router for Claude models?
- No. The Claude models answer the Anthropic format on this base URL, so Claude Code reaches them with ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN alone, prompt caching included. 12 ids on the key take that format today. The router is for the other 255.
- Is there an alternative to Claude Code Router?
- For Claude models, none is needed: two variables. For other models in a terminal agent, OpenCode and Kilo Code take an OpenAI-compatible provider directly and run the same ids without a router; the Claude Code alternatives post compares them.
- Does Claude Code Router run in Docker?
- Yes: the repository ships a Compose file (npm run docker:compose:up) that publishes the management UI and the gateway through one Nginx port, 3458 by default, with the data under /data (its Docker guide, read 2026-10-19). The provider and client key are set the same way; point Claude Code at the published port.
Related
- Claude Code pricing
- Cheaper Claude Code on Opus 5.5
- Claude Code setup
- Claude Code alternatives compared
- OpenCode Zen vs one key
- Kilo Code API key
- Cline setup
- Coding plans vs pay-per-token API
- Claude Sonnet 5.5
- GPT-5.3-Codex
- Kimi K2.7 Code
- GLM 5.3
- GLM API pricing
- DeepSeek API pricing
- Kimi API pricing
- SDK setup
- Daily real-model check
- Compare LLM API prices and work out your bill