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.

CCR Desktop
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-5
Hand-editing config.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.
The API endpoint here is the bare origin, 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

  1. Create a key at /app/keys and copy it — it is shown once.
  2. In CCR Desktop open ProvidersAdd provider, choose the preset Other / custom API endpoint, and fill in Name, API endpoint and API key.
  3. Add model ids under Models — use Search models to pull the catalog, or Custom models to type ids in.
  4. 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.
  5. Open Agent ConfigAdd 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.

This is the short version. The full walkthrough — model choice, what a real session costs, and the failure modes — is in the Claude Code Router guide.

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 idKunavo in / outWhere it fits in Claude Code Router
claude-opus-5$2.00 / $10.00the Opus tier — planning and hard edits
claude-sonnet-5$2.00 / $10.00the Sonnet tier and the profile default
claude-haiku-4-5$0.40 / $2.00the Haiku tier, which is where subagent volume lands
gemini-3-1-pro$0.70 / $4.20a long-context route, reachable through the same provider entry
Billing is per token from a prepaid balance with no monthly fee — see billing. On repeated context — which is most of what an editor or a chat client sends — prompt caching moves the bill more than the model choice does.

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.