Skip to content

Claude Code returns 401 or 403 — the fix checklist

A 401 or 403 from Claude Code means a server received your request and refused it — which is actually good news, because the cause is almost always one of five local things: a missing environment variable, the wrong base URL, a stale login session, a disabled key, or a network path that the official endpoint refuses. Match the exact message first, then work through this checklist in order; each step takes under a minute.

Match the exact error message

Claude Code's error reference (https://code.claude.com/docs/en/errors) lists these messages for sign-in and credential problems. Here is what each one means when Claude Code points at Router One, and which step below fixes it:

Match the exact error message
MessageWhat it means hereFix
Not logged in · Please run /loginNo usable credential reached this Claude Code session: neither a login nor ANTHROPIC_AUTH_TOKEN.Do not run /login for Router One; it signs in to Anthropic's own service. Set ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN (step 1) and restart Claude Code.
Invalid API keyThe value in ANTHROPIC_API_KEY was refused. It is often an old key left in a shell profile or in ~/.claude/settings.json.Unset ANTHROPIC_API_KEY (it is not required for Router One), remove it from your profile files, and put your Router One key in ANTHROPIC_AUTH_TOKEN (step 1).
Invalid auth token · Fix external auth tokenThe value in ANTHROPIC_AUTH_TOKEN was refused.Paste your Router One key again in full (sk- followed by 64 hex characters, no quotes or trailing space), then confirm in Dashboard → API Keys that the key is enabled and not past its expiry (step 4).
API Error: 401 Invalid authentication credentialsThe endpoint Claude Code called refused the credentials it sent.Check that ANTHROPIC_BASE_URL is exactly https://api.router.one (step 2) and that the key being sent is your current Router One key (steps 1 and 4).
Login expired · Please run /loginClaude Code is still using a stored login session, usually an earlier sign-in to the official service, instead of your gateway variables.Run /logout in Claude Code, confirm ANTHROPIC_AUTH_TOKEN is set in the same session, and restart (step 3).

Step 1 — Set the base URL and the auth token

Claude Code authenticates against a third-party gateway with ANTHROPIC_AUTH_TOKEN, not ANTHROPIC_API_KEY. Setting only ANTHROPIC_API_KEY is the single most common cause of 403/401. ANTHROPIC_API_KEY is not required, and on current builds it triggers an extra approval prompt; if you set it earlier, unset it. Export these two, then restart the terminal so the session actually picks them up:

claude-code-env.sh
export ANTHROPIC_BASE_URL=https://api.router.one
export ANTHROPIC_AUTH_TOKEN=sk-your-router-one-key
unset ANTHROPIC_API_KEY

Step 2 — Check the base URL, character by character

The Anthropic-compatible endpoint is https://api.router.one — no /v1 suffix. Appending /v1 (copied from OpenAI-style configs) produces requests against paths that don't exist on the Anthropic-compatible surface. If you previously pointed Claude Code at another relay, also check for a leftover ANTHROPIC_BASE_URL in ~/.zshrc, ~/.bashrc, or your shell profile that overrides the one you just set.

Step 3 — Clear stale credentials

If you ever logged Claude Code into the official service on this machine, that stored session can take precedence over your environment variables — you think you're calling one endpoint while the tool authenticates against another. Sign out inside Claude Code with /logout (or remove its stored credentials), restart the terminal, and confirm the env vars are visible in the same session with echo $ANTHROPIC_BASE_URL.

Step 4 — Verify the key itself

In Dashboard → API Keys, confirm the key is enabled and its spend cap (maxSpend) isn't exhausted — an exhausted or disabled key refuses requests regardless of your local config. Dashboard → Logs helps you tell where the failure sits. If nothing appears there, read the status Claude Code printed: the request either never reached the gateway or was refused before any model was called — at the key check (401: go back to steps 1–3), for funds (402: top up or raise maxSpend) or by your key's or account's rate limits (429) — and none of those writes a usage record. If requests appear with an error status, the record's status and error message point at the cause.

The Mainland China case

Calling the official Anthropic endpoint directly from Mainland China commonly fails with 403 or connection errors because of regional restrictions on the provider side. Router One's gateway is reachable from Mainland China without a VPN, so the same two environment variables above are also the fix for the China-access case — there is no separate setup.

FAQ

Claude Code says Not logged in · Please run /login. Should I run /login?

Not for Router One. /login signs in to Anthropic's own service, and a stored login can later take precedence over your environment variables. The message means no usable credential reached the session, so set ANTHROPIC_BASE_URL to https://api.router.one and ANTHROPIC_AUTH_TOKEN to your Router One key in ~/.claude/settings.json or the shell that launches Claude Code, then restart it.

Do I also need ANTHROPIC_API_KEY?

No. ANTHROPIC_AUTH_TOKEN is the variable Claude Code uses for a third-party gateway. ANTHROPIC_API_KEY is not required, and on current builds it triggers an extra approval prompt on launch; if you set it earlier, unset it in the same shell (and remove it from ~/.zshrc or ~/.bashrc). Router One's one-click installer writes only ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN into ~/.claude/settings.json.

I set the variables but Claude Code still gets 403.

Print them in the same terminal session that launches Claude Code: echo $ANTHROPIC_BASE_URL. If it's empty, the export lives in a different shell or profile file. Also check for a stored official-service login that overrides env vars (step 3).

Does the base URL end with /v1?

No — for Claude Code the Anthropic-compatible base URL is https://api.router.one without /v1. The /v1 suffix belongs to the OpenAI-compatible endpoint used by Codex CLI and OpenAI SDKs.

How do I confirm requests are actually reaching the gateway?

Dashboard → Logs records the requests the gateway sent to a model, failed ones included, and filters them by API key. If your Claude Code attempts don't show up there at all, treat that as a clue rather than proof: the request may never have reached the gateway, or it was refused before any model was called — at the key check (401), for funds (402) or by your key's or account's rate limits (429) — and none of those writes a usage record. Check the status Claude Code printed; for a 401, go back to steps 1–3. If they show up with an error status, the record's status and error message point at the cause.

Will this setup work from Mainland China?

Yes. The gateway is reachable from Mainland China without a VPN, and the configuration is identical to the global setup — the same two environment variables.