← Back to Blog

Claude Code 401 With a Custom Base URL: ANTHROPIC_API_KEY vs ANTHROPIC_AUTH_TOKEN

2026-07-05·4 min read·CodeRouter Team
claude code 401 base urlanthropic_base_url 401invalid x-api-key claude codeanthropic_auth_token vs anthropic_api_keyclaude code router proxy setupclaude code authentication_error

TL;DR — Claude Code sends credentials in two different HTTP headers depending on which environment variable you set: ANTHROPIC_API_KEY goes out as x-api-key (what Anthropic's own API expects), while ANTHROPIC_AUTH_TOKEN goes out as Authorization: Bearer (what most gateways and routers expect). Point ANTHROPIC_BASE_URL at a router but keep your credential in the wrong variable, and you get 401 authentication_error even though the key itself is valid. Rule of thumb: custom endpoint → ANTHROPIC_AUTH_TOKEN; api.anthropic.com directly → ANTHROPIC_API_KEY.

The error

You redirect Claude Code to a router, gateway, or proxy:

export ANTHROPIC_BASE_URL=https://www.coderouter.io/api/v1
export ANTHROPIC_API_KEY=<your router key>   # ← the mistake
claude

And every request fails with:

API Error: 401
{"type":"error","error":{"type":"authentication_error","message":"invalid x-api-key"}}

The key is correct — you can curl the router with it directly. So why 401?

The cause: two env vars, two headers

Claude Code distinguishes first-party and custom-endpoint authentication:

| Env var | Header sent | Intended for | |---|---|---| | ANTHROPIC_API_KEY | x-api-key: <key> | Anthropic's own API (api.anthropic.com) | | ANTHROPIC_AUTH_TOKEN | Authorization: Bearer <key> | Gateways, routers, proxies |

Most routers and gateways authenticate with a standard Authorization: Bearer header. When your key arrives in x-api-key instead, the router sees no credential where it looks for one and returns 401 — often echoing Anthropic-style error JSON, which makes it look like an upstream Anthropic rejection. (Both variables are documented in Claude Code's settings reference; LiteLLM's Claude Code guide shows the same ANTHROPIC_AUTH_TOKEN pattern for gateway setups.)

The fix

For any custom endpoint, use the token variable — and make sure the key variable isn't set at the same time:

export ANTHROPIC_BASE_URL=https://www.coderouter.io/api/v1
export ANTHROPIC_AUTH_TOKEN=<your coderouter key>
unset ANTHROPIC_API_KEY
claude

Or persistently, in ~/.claude/settings.json:

{
  "env": {
    "ANTHROPIC_BASE_URL": "https://www.coderouter.io/api/v1",
    "ANTHROPIC_AUTH_TOKEN": "<your coderouter key>"
  }
}

Then verify inside Claude Code with a trivial prompt, and confirm on the router dashboard that the request arrived and was routed.

Other 401/403 variants worth checking

If switching variables doesn't fix it:

Why route Claude Code at all?

Once the base URL points at a router, every Claude Code request becomes routable: planning-phase requests can go to a frontier model while bulk edit/implementation turns go to cheaper models, with per-request cost tracking — that's CodeRouter's phase-aware routing. The env-var setup above is the entire client-side integration; no plugin needed.

FAQ

Do I need both ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN?

No — set exactly one. Both set at once is the second most common broken state after "wrong one set", because which credential wins depends on the endpoint and tool version. Custom endpoint: ANTHROPIC_AUTH_TOKEN only.

My router logs show no request at all. Still an auth problem?

No — 401 with nothing in the router log means the request never reached the router: typo in ANTHROPIC_BASE_URL, missing /api/v1-style path prefix, or a shell where the export isn't active (new terminal, IDE-spawned process). Print the resolved env with claude /doctor or env | grep ANTHROPIC from the same shell.

Does this apply to the Claude Agent SDK too?

Yes — the SDK honors the same ANTHROPIC_BASE_URL / auth conventions as Claude Code, so the same header rule applies when pointing SDK agents at a gateway.


Sources: Claude Code settings reference, Claude Code corporate proxy docs, LiteLLM Claude Code quickstart.

Ready to Reduce Your AI API Costs?

CodeRouter routes every API call to the optimal model — automatically. Start saving today.

Get Started Free →

Get weekly AI cost optimization tips

Join 2,000+ developers saving on LLM costs