Docs
Claude Code Router
CCR sits between Claude Code and whatever serves the models, so different request classes can go to different places. Add Kunavo as a custom endpoint, then let the Agent Config map each Claude tier onto a model id.
CCR is a desktop app now, not a config.json: add Kunavo as a custom API endpoint, then let its routing rules send each request class to a different model.
Providers → Add provider
Preset provider Other / custom API endpoint
Name Kunavo
API endpoint https://api.kunavo.com
API key sk-kn-...
Models claude-sonnet-5, claude-opus-5, claude-haiku-4-5
Agent Config → Add profile → Claude Code
Model Kunavo/claude-sonnet-5
Opus model Kunavo/claude-opus-5
Haiku model Kunavo/claude-haiku-4-5config.json no longer does anything. CCR keeps its runtime configuration in ~/.claude-code-router/config.sqlite and reads a legacy config.json exactly once, as a migration source, when no SQLite config exists. After that first run, edits to the JSON file are silently ignored. Most write-ups on the internet — and older versions of our own guide — still describe the JSON file.https://api.kunavo.com: CCR probes the protocol against it and Kunavo answers Anthropic Messages natively at /v1/messages. If you would rather CCR speak the OpenAI-compatible format, give it https://api.kunavo.com/v1 instead — both surfaces are live on the same key.Step by step
- Create a key at
/app/keysand copy it — it is shown once. - In CCR Desktop open Providers → Add provider, choose the preset
Other / custom API endpoint, and fill in Name, API endpoint and API key. - Add model ids under Models — use Search models to pull the catalog, or Custom models to type ids in.
- Run Check Connection on two or three models. It sends real requests, so select only what you need to verify rather than the whole list.
- Open Agent Config → Add profile → Claude Code, set Model and the per-tier Opus / Sonnet / Haiku overrides, save, and launch Claude Code from CCR.
Checked against CCR's provider configuration page on September 6, 2026. Third-party settings move; if a field name here no longer matches what you see, that page is the authority, not this one.
Verify before you debug the client
One request settles whether a failure is the endpoint, the key, or the configuration file. If this returns JSON, the same base URL and key work in Claude Code Router.
# Settles whether a failure is the endpoint, the key, or the client.
curl -sS https://api.kunavo.com/v1/messages \
-H "Authorization: Bearer sk-kn-..." \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"claude-sonnet-5","max_tokens":16,"messages":[{"role":"user","content":"ping"}]}'Which model id to put in the field
Every text model is reachable as a model id — the live list is GET /v1/models, and the catalog with prices is on the models page. Rates are USD per 1M tokens, input / output.
| Model id | Kunavo in / out | Where it fits in Claude Code Router |
|---|---|---|
claude-opus-5 | $2.00 / $10.00 | the Opus tier — planning and hard edits |
claude-sonnet-5 | $2.00 / $10.00 | the Sonnet tier and the profile default |
claude-haiku-4-5 | $0.40 / $2.00 | the Haiku tier, which is where subagent volume lands |
gemini-3-1-pro | $0.70 / $4.20 | a long-context route, reachable through the same provider entry |
Why the per-tier map is the point
Claude Code picks a model per tier rather than per request: the main loop asks for the Sonnet or Opus tier, and background work — subagents, search, summarisation — asks for the small/fast one. CCR's Agent Config exposes those tiers as separate fields, so the expensive model only serves the requests that need it while the high-volume tier goes to a cheap id. That split is the whole reason to run a router in front of Claude Code, and it is invisible from Claude Code's own settings.
FAQ
Where does Claude Code Router store its configuration?
In a SQLite database: ~/.claude-code-router/config.sqlite on macOS and Linux, %APPDATA%\claude-code-router\config.sqlite on Windows. A legacy config.json is read only once, as a migration source, when no SQLite configuration exists yet; after that migration, editing config.json has no effect on the running configuration. Change settings through the desktop UI instead.
How do I add a custom API endpoint to Claude Code Router?
Open Providers, click Add provider, and select the preset "Other / custom API endpoint" — that preset accepts any OpenAI-, Anthropic- or Gemini-compatible upstream. Fill in a unique Name, the API endpoint base URL and the API key, then add model ids either by fetching them or by typing them under Custom models. Check Connection sends real test requests to confirm the endpoint, key, protocol and ids all work together.
Can Claude Code Router send different Claude tiers to different models?
Yes, and it is the main reason to run it. In Agent Config, a Claude Code profile has a default Model plus optional Fable, Opus, Sonnet and Haiku overrides. Claude Code requests a tier rather than a specific id, so mapping the Haiku tier to a cheap model and the Opus tier to a strong one splits the bill along the way the agent already behaves — high-volume background work on the cheap id, planning on the expensive one.
Does Claude Code Router work with an Anthropic-format gateway?
Yes. The custom-endpoint preset probes the protocol against the URL you supply and supports Anthropic Messages as one of its protocols, so a gateway exposing /v1/messages can be added directly with its origin as the API endpoint. A gateway that also exposes an OpenAI-compatible surface can be added either way; the difference is only which wire format CCR uses to talk to it.