Agent Model Connector

Fix 401 Unauthorized in Claude Code and Codex CLI

Step-by-step fixes for the "401 Unauthorized" error when connecting Claude Code or Codex CLI to DeepSeek, OpenRouter, and other providers.

Error output

Error: 401 Unauthorized {"error":{"message":"Invalid Authentication: Bearer token is invalid or expired"}}
Common variations
anthropic: Request to Anthropic API failed with status 401: {"type":"error","error":{"type":"authentication_error","message":"invalid x-api-key"}}
Error: Invalid API key. Check your key at https://platform.deepseek.com/api_keys

The exact text varies by agent version and provider. Match the status code and the message above.

Quick diagnosis

Run this command and check what the token variable actually contains — the failure is almost always visible there.

Claude Code
echo $ANTHROPIC_AUTH_TOKEN
Codex CLI
echo $DEEPSEEK_API_KEY $OPENROUTER_API_KEY

Common causes

  • The API key is wrong, expired, or was regenerated after the config was set.
  • The key was exported in an old terminal session and the new value never took effect.
  • The provider account has no balance, which some providers report as 401.
  • An unexpected ANTHROPIC_API_KEY reroutes traffic back to Anthropic (OpenRouter setups).

Fix by scenario

1 Fails right after the initial setup

  • Open a NEW terminal after editing your shell profile — variables from the old session are stale.
  • Is the key pasted without extra spaces, quotes, or a trailing newline?
  • Does the key start with the expected prefix (sk- for DeepSeek, sk-or- for OpenRouter)?
  • Is an old ANTHROPIC_API_KEY still set, overriding the routing?

2 Fails after replacing the API key

  • Providers invalidate a key the moment a new one is generated — the old key dies instantly.
  • Is the new key exported everywhere the old one was (shell profile, settings.json, CI)?
  • Restart the terminal or re-export before retrying.

3 Worked before, now fails

  • Did the provider rotate or retire the key? Check the dashboard.
  • Is the account balance exhausted? Some providers report 401 instead of 402.
  • Did anything touch the shell profile or settings.json recently (new tool, dotfiles sync)?

Agent-specific fixes

Claude Code

Fix
Set ANTHROPIC_AUTH_TOKEN to the provider key. With OpenRouter, keep ANTHROPIC_API_KEY="" (explicitly empty). Re-export and open a new terminal.
Verify
`claude /status` should show your provider endpoint and a connected state.

Codex CLI

Fix
Export the key named by env_key in config.toml (DEEPSEEK_API_KEY or OPENROUTER_API_KEY). Never put the key in the toml itself.
Verify
`codex exec "hi"` succeeds and the request appears in the provider dashboard.

Claude Code vs Codex CLI at a glance

Claude Code Codex CLI
Authentication variable ANTHROPIC_AUTH_TOKEN env_key in config.toml
Where the key lives Shell profile or settings.json env block Exported env var referenced by env_key
Verify command claude /status codex exec "hi"

Prevent it from happening again

  • Store keys in a password manager and rotate them on a schedule.
  • Never commit keys to dotfiles repos or config files.
  • Keep a working config snapshot so a broken change is easy to roll back.

Related errors

Related setup guides

Frequently asked questions

I created a new key but still get 401 — why?

The most common cause is a stale terminal session: exports only apply to sessions started after the export. Open a fresh terminal, or re-export and run the verify command again.

Does a Claude Pro or Max subscription fix 401 errors?

No. This setup authenticates with a provider API key and bills to that provider. Subscriptions cannot be combined with a third-party endpoint, so the 401 remains until the key is fixed.

Why do I get 401 with OpenRouter even though the key is correct?

Claude Code falls back to Anthropic authentication when ANTHROPIC_API_KEY is unset or holds a real value. Set it to an explicitly empty string so all traffic goes through OpenRouter.

All error guides