Blog

Claude Code "Invalid API key · Please run /login" with a Custom Base URL

Short answer

Invalid API key · Please run /login means the endpoint Claude Code sent your request to rejected the credential it was given. When you set ANTHROPIC_BASE_URL, that endpoint is your gateway or proxy, not Anthropic. So the usual cause is a credential mix-up on your machine: the gateway key is in a variable the gateway doesn't read, an old key or a saved claude.ai login is sent instead, or the key isn't one that gateway issued.

Running /login only helps if you want to use your Anthropic account directly. To use a gateway, set the gateway's key as ANTHROPIC_AUTH_TOKEN (sent as Authorization: Bearer), remove any leftover ANTHROPIC_API_KEY, start claude again from the same shell, and run /status to confirm which base URL and credential are active.

If you are setting up TeamoRouter, the two variables are ANTHROPIC_BASE_URL=https://api.teamorouter.com and ANTHROPIC_AUTH_TOKEN=<your TeamoRouter key>. The TeamoRouter section below has the full commands and a key test.

What the error looks like

The wording depends on your Claude Code version and on which credential failed:

text
Invalid API key · Please run /login

This is the form in anthropics/claude-code#5167, reported on Claude Code 1.0.68. Current versions word it differently. The Claude Code error reference lists this message for a key from ANTHROPIC_API_KEY or an apiKeyHelper script that the API rejected:

text
Invalid API key · Fix external API key

Two related messages you may see instead:

text
Not logged in · Please run /login

This one means Claude Code found no usable credential at all. A gateway can also answer with its own 401, which Claude Code shows with the same /login hint. This example comes from a custom-endpoint setup in anthropics/claude-code#7452, with the request ID shortened:

text
API Error: 401 {"type":"error","error":{"type":"authentication_error","message":"Invalid bearer token"},"request_id":"req_011C..."} · Please run /login

Whichever one you get, the fix starts in the same place: find out which credential Claude Code sent, and to which URL.

No custom base URL at all? Then this page isn't your case. In #5167 the cause was a login that never reached the macOS keychain, often over SSH or inside tmux. Some users in that thread report that running security unlock-keychain ~/Library/Keychains/login.keychain-db before starting claude fixes it.

Why it happens with a custom base URL

When several credentials are present, Claude Code uses only one. According to its authentication precedence, it picks the first of these that is present:

  1. Cloud provider credentials, when CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX or CLAUDE_CODE_USE_FOUNDRY is set
  2. ANTHROPIC_AUTH_TOKEN, sent as Authorization: Bearer <token>
  3. ANTHROPIC_API_KEY, sent as X-Api-Key. In an interactive session you approve it once; in claude -p it is always used when set
  4. The output of an apiKeyHelper script
  5. CLAUDE_CODE_OAUTH_TOKEN
  6. Anthropic profile and federation credentials
  7. Your saved /login (Pro, Max, Team or Enterprise subscription)

ANTHROPIC_BASE_URL only changes where requests go. It doesn't change which credential is sent. These are the usual ways the wrong one ends up at your gateway:

  • The key is in a variable the gateway doesn't read. ANTHROPIC_AUTH_TOKEN and ANTHROPIC_API_KEY put the key in different headers. Anthropic's gateway guide says a credential in the wrong variable arrives in a header the gateway ignores, and the request fails with 401.
  • Only the base URL is set. With no gateway credential, a saved claude.ai login stays the active credential and is sent to the gateway, which usually can't accept it.
  • The key was declined at the approval prompt. A previously declined ANTHROPIC_API_KEY is ignored without asking again, so Claude Code falls back to your saved login. You can turn it back on under /config with Use custom API key.
  • A settings file overrides your shell. When an env block in a Claude Code settings file and a shell export set the same variable, the settings file wins. An old key in ~/.claude/settings.json beats the one you just exported.
  • A project .env loads a stale key. direnv, dotenv shell plugins and IDE terminals can set ANTHROPIC_API_KEY from a project file without you noticing.
  • The project settings haven't applied yet. An env block in a project's .claude/settings.json or .claude/settings.local.json only applies after the first-run setup and the folder trust prompt, so the first session can start with no credential and ask you to log in.
  • The pasted key has a hidden character. A line break or zero-width space copied from a chat or document makes the key invalid. Current versions name the variable and the character position after Fix external API key.
  • The key isn't valid on that gateway. It was revoked, mistyped, or it is an Anthropic Console key sent to a gateway that only accepts its own keys.

How to fix it

  1. See what Claude Code is using. Run /status. The Anthropic base URL line should show your gateway. An Auth token or API key line should name the variable you set. If it shows your claude.ai account instead, the gateway credential isn't reaching the session.
  2. List every Anthropic variable in that shell. Run env | grep ANTHROPIC (PowerShell: Get-ChildItem Env:ANTHROPIC*). Then check the env block in ~/.claude/settings.json and in the project's .claude/settings.local.json. Delete old keys you no longer use.
  3. Put the gateway key in the variable it expects. If the gateway authenticates with a bearer token, or you weren't told which kind, use ANTHROPIC_AUTH_TOKEN. Use ANTHROPIC_API_KEY only if the gateway reads x-api-key. Keep one of the two, not both.
  4. Retype the key if you pasted it. Copy it again from the gateway's dashboard, not from a chat message or a document.
  5. Test the gateway without Claude Code. A direct curl request with the same URL and key tells you whether the problem is the key or your Claude Code setup. A 401 there means the gateway itself rejects the key.
  6. Clear the old login if you only use the gateway. If startup warns that two credential sources are set, run /logout so that only the gateway credential remains.
  7. Start claude from the same shell. Shell exports don't reach an editor or terminal that was opened from the dock or Start menu. Restart, send a message, and run /status again.

Troubleshooting table

What you see Likely cause Fix
Invalid API key right after setting ANTHROPIC_BASE_URL The key is in the wrong variable for this gateway Move it to ANTHROPIC_AUTH_TOKEN, unset ANTHROPIC_API_KEY
/status shows your claude.ai account, not the gateway key No gateway credential reached the session Export ANTHROPIC_AUTH_TOKEN or put it in ~/.claude/settings.json
You exported a new key but the old one is still used A settings-file env block or a project .env overrides it Remove the old value from the settings file or .env
ANTHROPIC_API_KEY is set but ignored, with no prompt You declined it once /config → Use custom API key
Works in a terminal, fails in the IDE The IDE didn't inherit your shell exports Put the variables in ~/.claude/settings.json
Fix external API key followed by a character position A hidden character in the pasted key Retype the key
401 ... Invalid bearer token The gateway rejected the token Check the key on the gateway's side, or create a new one
Asked to log in on the first run in a new project Project env settings apply only after the trust prompt Export the variables in your shell or set them in ~/.claude/settings.json

If your base URL is TeamoRouter

TeamoRouter is an API gateway with one key for Claude, GPT, Gemini and DeepSeek. Claude runs on the native Anthropic protocol (/v1/messages), so Claude Code only needs a base URL and a key. Billing is pay-per-use with no subscription.

  1. Create an API key in the TeamoRouter console. It starts with sk-teamo-.
  2. Set the two variables. On macOS and Linux:
bash
export ANTHROPIC_BASE_URL=https://api.teamorouter.com
export ANTHROPIC_AUTH_TOKEN="your TeamoRouter API key"
unset ANTHROPIC_API_KEY
claude

Leave /v1 off the base URL: Claude Code adds the path itself. On Windows, set the same two variables with setx and reopen the terminal. Model settings and the full Windows commands are in Install and connect Claude Code.

  1. If it still fails, test the key on its own:
bash
curl https://api.teamorouter.com/v1/models \
  -H "Authorization: Bearer sk-teamo-..."

A model list means the key works, so look at your Claude Code variables and settings files again. A 401 means the key itself is wrong: copy it again from the console or create a new one.

Top up from $5. The top-up dialog takes cards. You can also click Pay with crypto and pay with USDT, USDC or ETH from Binance, OKX or any exchange app — the checkout shows which networks your amount supports (BEP20 works from $5). You don't need a wallet extension, and the invoice stays valid for 60 minutes. Step by step: Pay for Claude with USDT.

FAQ

Will running /login fix it? Only if you want to stop using the gateway and sign in to Anthropic directly. /login saves an Anthropic credential; it doesn't give you a gateway key. While a gateway credential variable is set, Claude Code uses that variable and leaves the saved login unused.

Should I use ANTHROPIC_AUTH_TOKEN or ANTHROPIC_API_KEY? It depends on the header your gateway reads: ANTHROPIC_AUTH_TOKEN sends Authorization: Bearer, ANTHROPIC_API_KEY sends x-api-key. Anthropic's guide suggests ANTHROPIC_AUTH_TOKEN when you aren't sure. TeamoRouter's Claude Code guide uses ANTHROPIC_AUTH_TOKEN.

Why does claude -p fail when the interactive session works? In -p mode, ANTHROPIC_API_KEY is always used when it's set. An interactive session may be ignoring a key you declined and using another credential. Make sure the shell or CI job that runs claude -p has only the gateway credential.

My key works in curl but Claude Code still asks me to log in. Why? A reachable base URL isn't a credential. Claude Code needs the key in one of its credential variables, set somewhere it reads before startup: a shell export, the env block in ~/.claude/settings.json, or managed settings.

Next steps

Ready to connect?Log in · top up · create an API key — three steps to start.