What you need
- Claude Code installed (`claude` on your PATH).
- An UplinkSwitch key from the console, with a balance loaded.
Two variables
ANTHROPIC_API_KEY works in place of ANTHROPIC_AUTH_TOKEN. Set one, not both.
export ANTHROPIC_BASE_URL="https://api.uplinkswitch.com/v1"
export ANTHROPIC_AUTH_TOKEN="sk-uplink-live-..."
claudeANTHROPIC_BASE_URLpoints Claude Code at UplinkSwitch. Paste it with the/v1; the gateway accepts the path Claude Code builds from it.ANTHROPIC_AUTH_TOKENsends the key asAuthorization: Bearer.ANTHROPIC_API_KEYsends it asx-api-key. UplinkSwitch reads either header. A request that carries two different keys is refused with a400.- The base URL alone is not enough. Without one of the key variables, Claude Code keeps using a saved claude.ai login (Claude Code's gateway docs).
Make it stick
Add them to ~/.claude/settings.json under env. The model variables take any Claude id from the Models page. Claude Code speaks Anthropic's API format, and only the Claude models are served in it; the others answer through the OpenAI and Gemini SDKs.
{
"env": {
"ANTHROPIC_BASE_URL": "https://api.uplinkswitch.com/v1",
"ANTHROPIC_AUTH_TOKEN": "sk-uplink-live-...",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "claude-opus-5-5",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-5-5",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-haiku-5-5"
}
}~/.claude/settings.jsonapplies to every project..claude/settings.local.jsonapplies to one project.- Keep the key out of a project's
.claude/settings.json. That file is meant to be committed and shared. - When a shell export and a settings file set the same variable, the settings file wins.
- The VS Code extension checks credentials from its own setting,
claudeCode.environmentVariables, in VS Code's user settings:
{
"claudeCode.environmentVariables": [
{ "name": "ANTHROPIC_BASE_URL", "value": "https://api.uplinkswitch.com/v1" },
{ "name": "ANTHROPIC_AUTH_TOKEN", "value": "sk-uplink-live-..." }
]
}Picking a model
The opus, sonnet and haiku aliases resolve to whatever the three ANTHROPIC_DEFAULT_*_MODEL variables name. Setting the Haiku one also moves background work such as session titles to that model. Switch in a session with /model, at start with claude --model claude-opus-5-5, or for one session with ANTHROPIC_MODEL.
Use Claude ids only. A GPT, Gemini or DeepSeek id returns a 400 that says the model is served in the openai format, not anthropic. For those models, use an OpenAI-compatible tool such as OpenCode or Cline.
Check it
List the models your key can call:
curl https://api.uplinkswitch.com/v1/models -H "x-api-key: $ANTHROPIC_AUTH_TOKEN"Send one small message. -i prints the headers: x-uplink-request-id names the request and x-uplink-charge is what it cost in USD.
curl -i https://api.uplinkswitch.com/v1/messages \
-H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model": "claude-haiku-5-5", "max_tokens": 16, "messages": [{"role": "user", "content": "Say ok."}]}'Then run claude. The request shows in the console within seconds. Inside Claude Code, /status shows an Anthropic base URL line with the UplinkSwitch address and an Auth token or API key line naming the variable you set. If the base URL line is missing, the variable did not reach the session.
Caching and billing
Claude Code sends the whole conversation on every turn and marks it for the prompt cache. Tokens read from the cache bill at the cached rate on each model page, a fraction of the input rate. The cache lasts five minutes by default, so a turn after a longer break pays the input rate for the whole context once.
The cost Claude Code shows is its own estimate at Anthropic's list price. What you paid is on the console's Usage page. For one request, look it up by its id; it lands in the log within about a minute:
curl https://api.uplinkswitch.com/v1/requests/REQUEST_ID \
-H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN"The answer lists input_tokens, cache_read_tokens, output_tokens and charge_usd. A cache_read_tokens above zero means caching worked. The Claude Code cost breakdown works a day of use through at live prices.
Errors and fixes
invalid_api_key(401): the key is wrong or revoked, or it is in a variable Claude Code did not read. Check/status.insufficient_balance(402): top up in the console.monthly_limit_reached(402) means the key hit the monthly spend limit set on it.model_not_found(404): the id is not on the Models page. Check the model variables for typos.- Claude Code asks you to log in although the curl test works: set the key in a shell export or in
~/.claude/settings.json. A project settings file applies only after the first-run setup and the trust prompt. - A startup warning naming two credential sources: a saved login and the variable are both active. Run
/logoutto keep only the key. ANTHROPIC_API_KEYset but ignored: it needs a one-time approval. Turn on Use custom API key under/config, or useANTHROPIC_AUTH_TOKEN.
Good to know
- MCP tool search is off on a non-Anthropic host;
ENABLE_TOOL_SEARCH=trueturns it on. - Prompt caching works; cached input bills at the cached rate.
- Remote Control and voice dictation need a claude.ai login, so they are off while a key variable is set.
- To switch back:
unset ANTHROPIC_BASE_URL ANTHROPIC_AUTH_TOKEN, and remove them fromsettings.jsonif you put them there.