Claude Code
Run Claude Code against Deference with a base URL and your key.
Claude Code speaks the Anthropic Messages API. Point it at https://deference.si (no /v1) and give it your key as the auth token.
Set up
- Create a key in API keys and export it as
DEFERENCE_API_KEY. - Set the base URL, the token and model discovery in your shell profile.
export ANTHROPIC_BASE_URL="https://deference.si"
export ANTHROPIC_AUTH_TOKEN="$DEFERENCE_API_KEY"
export CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY="1"$env:ANTHROPIC_BASE_URL = "https://deference.si"
$env:ANTHROPIC_AUTH_TOKEN = $env:DEFERENCE_API_KEY
$env:CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY = "1"- Start
claude. If you were signed in to Claude before, run/logoutonce so the saved login does not compete with the token.
To keep the setup out of your shell profile, put it in the env block of your user file, ~/.claude/settings.json (on Windows, %USERPROFILE%\.claude\settings.json). The block does not expand variables, so the key goes in as text.
{
"env": {
"ANTHROPIC_BASE_URL": "https://deference.si",
"ANTHROPIC_AUTH_TOKEN": "sk-df-...",
"CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY": "1"
}
}Verify
- Check the route and the key with one request. A reply that starts with
{"id":"msg_means it works.
curl https://deference.si/v1/messages \
-H "Authorization: Bearer $DEFERENCE_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-5.5",
"max_tokens": 1,
"messages": [{ "role": "user", "content": "." }]
}'- Start
claude, send a short prompt, then run/status. It lists the Anthropic base URL ashttps://deference.siand names the auth token. A login method that names claude.ai means Claude Code did not pick up the token. - Run
claude --debugto see the model discovery lines in the debug log. - Open Activity. The request is the top row, and its client reads Claude Code.
Pick a model
Claude Code asks for a model class (Opus, Sonnet or Haiku) and resolves it to Anthropic's own model id. Pin each class to a Deference id so the request names a model in the catalog.
| Variable | Sets |
|---|---|
ANTHROPIC_MODEL | The model for the session |
ANTHROPIC_ | The id used for Sonnet, for instance anthropic/ |
ANTHROPIC_ | The id used for Haiku, for instance anthropic/ |
ANTHROPIC_ | The id used for Opus |
CLAUDE_ | The default id for subagents |
- A model named in a subagent's definition or invocation wins over
CLAUDE_. To pin every subagent to one id, also setCODE_ SUBAGENT_ MODEL CLAUDE_on Claude Code 2.1.257 or later.CODE_ SUBAGENT_ MODEL_ FORCE=1 - With discovery on,
/modellists the catalog ids that containclaudeoranthropic. Select any other model with/model <id>orclaude --model <id>, using its full id. - A model Claude Code does not recognize is assumed to have a 200K context window. Append
[1m]to the id, as inanthropic/, to ask for 1M. Deference strips that suffix, looks the model up without it, and sends the catalog id. The provider does not seeclaude-sonnet-5.5[1m] [1m]. - Claude Code is built for Claude models. Other models in the catalog answer, but tool use and thinking can behave differently.
- On a team, set
allowedProvidersto["customEndpoint"]in Claude Code's managed settings on v2.1.285 or later. The same file'senvblock must setANTHROPIC_BASE_URLtohttps://deference.si; Claude Code then refuses a session pointed anywhere else.
Use it in other Claude clients
The Claude Agent SDK and the Claude Code GitHub Action read the same variables. The VS Code extension reads them from its own setting, claudeCode.environmentVariables, not from settings.json. The Claude desktop app ignores ANTHROPIC_BASE_URL.
Connect the MCP server
Connect the MCP server and Claude Code checks your credit, runs models within a budget you set, and creates, rotates and revokes its own capped keys. You sign in once.
Troubleshooting
Messages errors carry a type and a message, not a code, so each row names the status, the type and how the message starts.
| You see | Cause | Fix |
|---|---|---|
| Claude Code asks you to log in | A saved login wins, or the variables are not set | Run /logout, and check the variables in the shell that starts claude |
| A warning names two credential sources | A saved login and a gateway token are both present | Run /logout, or unset one |
401 authentication_error | The token variable is empty or mistyped | Set ANTHROPIC_AUTH_TOKEN again from your saved key, or create a replacement. Keep the value out of logs and shared output |
ANTHROPIC_API_KEY is set but ignored | Claude Code asks for a one-time approval of that key and never re-asks | Use ANTHROPIC_AUTH_TOKEN instead |
404 not_found_error, "The model ... does not exist" | A class variable holds a short name | Use the full id, such as anthropic/ |
402 billing_error, "This account has no credit left" | No available credit | Add credit |
402 billing_error, "This account has only free credit" | The account has only free credit, which never pays for Claude models | Add credit, or select an open-weight text model |
402 billing_error, "This API key has reached its credit limit" | The key reached the credit limit set on it | Raise the key's limit in API keys, or use another key |
| The picker lacks a non-Claude model | Discovery lists only ids with claude or anthropic | Select it with /model and its full id |
| The picker is empty | Discovery is off, or /v1/models took over 3 seconds or redirected | Set CLAUDE_ |
400 naming anthropic-beta or an extra input | The model rejects a beta feature Claude Code sends | Set CLAUDE_ |
| Variables seem ignored | They were set in a project .env | Export them in your shell or in ~/.claude/settings.json |