A Claude Code API key is more than a string. It determines whose identity the requests are billed to, which models can be called, and how much damage a leak can cause. Most 401 errors are not a failed key; they come from the variable name, the request header, or the configuration layer.

This article follows a practical sequence: the authentication chain, creating a key, environment variables versus configuration files, multiple profiles, rotation, leak prevention, CI and team use, and 401 troubleshooting. The exact variable names and settings depend on your current Claude Code version and gateway documentation.

Note: Claude and Anthropic are trademarks of their respective owners. This article is technical guidance with no affiliation to those vendors; interfaces, permissions, and prices follow each platform's official documentation and on-site pages.

1. Understand the Claude Code authentication chain

When Claude Code starts, it sends requests to ANTHROPIC_BASE_URL with credentials attached. Those credentials usually come from one of two variables:

  • ANTHROPIC_AUTH_TOKEN: sent as Authorization: Bearer, common for gateway access.
  • ANTHROPIC_API_KEY: sent as x-api-key, closer to Anthropic's native method.

The gateway receives the request, resolves the account from the key, then checks balance, quota, model permissions, and expiration. A failure at any link can surface as 401, 403, or 429. Do not stare only at the key string when troubleshooting.

Another common misunderstanding is binding a key to a model. The key is identity; the model is a request parameter. One key can usually call multiple models, depending on account permissions and gateway policy.

2. Create a key in five steps

  1. Open the ZSQH AI Gateway or the platform you use, register, and sign in to the console.
  2. Go to the API Keys page and create a new key. Name it with the environment and purpose, for example claude-code-work-mac.
  3. Set a quota and expiration date. Give test keys a low quota first, then adjust after confirming actual consumption.
  4. If the platform supports model allowlists or project scopes, select only the models Claude Code needs.
  5. Copy the full key immediately into a password manager or secrets service. Most consoles show the full value only once.

Keys often start with sk-, but the prefix proves neither authenticity nor permissions. Watch for leading or trailing spaces and line breaks when copying; these are a frequent cause of 401.

After creation, verify with a minimal curl request before distributing the key to team members. The method is described in the 401 troubleshooting section below.

3. Environment variables versus configuration files

Method Suitable for Advantages Cautions
Shell environment variables Personal machines, temporary switching Nothing written into the project, easy to switch New terminals or IDEs may not read them
User-level settings.json Long-term personal use Configure once, apply globally Key stored in plain text
Project-level settings.local.json Single-project overrides Does not affect other projects, can be gitignored Must be reconfigured on another machine
apiKeyHelper or secrets manager Teams, shared machines, compliance Key never appears directly in config Requires extra scripts and permission management
CI secret variables Automated pipelines Separate from code, auditable Pay attention to log redaction and branch permissions

Environment variables suit "I want to try this now"; settings.json suits "this machine works this way long term"; a secrets manager suits "the key must never appear in plain text on disk." The three can be combined, but know which one overrides which. Claude Code configuration precedence generally runs from enterprise managed settings, command-line arguments, local project, project, and user settings, with minor differences between versions; follow the official documentation.

One easy trap: variables exported in ~/.zshrc may not be visible to Claude Code launched from the Dock or an IDE. GUI applications inherit the login environment, which does not necessarily load your shell configuration. In that case, change settings.json or inject the values explicitly in the launch script.

4. Multiple profiles: separate personal, project, and team keys

Keep at least three keys: personal daily use, project-specific, and automation. Their quotas, permissions, and rotation cycles differ; mixing them makes both usage and failures hard to trace.

If you do not want to maintain multiple configuration files, use shell functions to inject settings per scenario:

# ~/.zshrc
claude_work() {
  ANTHROPIC_BASE_URL="https://ai.zhongshangqihang.com" \
  ANTHROPIC_AUTH_TOKEN="$ZSQH_WORK_KEY" \
  claude "$@"
}

claude_test() {
  ANTHROPIC_BASE_URL="https://ai.zhongshangqihang.com" \
  ANTHROPIC_AUTH_TOKEN="$ZSQH_TEST_KEY" \
  claude "$@"
}

Store real keys in ~/.zshrc.local or a secrets manager; the main configuration file only references variables. Switching environments then means changing the function name, not the project code.

Use .claude/settings.local.json for project isolation and confirm it is in .gitignore. The team-shared .claude/settings.json should contain only non-sensitive items such as Base URL, model name, and permissions, never keys.

5. Key rotation: when and how

Rotation is not a formality; it shortens the window in which a leaked key remains useful. Rotate when an employee leaves or changes roles, a device is lost, a leak is suspected, a vendor requires it, or on a fixed schedule. The interval can follow team compliance requirements, for example every 90 days.

  1. Create a new key in the console with a date in the name, for example claude-code-prod-2026-10.
  2. Write the new key into the secrets manager or environment variables first; do not delete the old key yet.
  3. Verify with both curl and Claude Code, confirming model, quota, and permissions.
  4. Review the old key's usage logs to confirm no forgotten script or member still uses it.
  5. Disable the old key, then watch the error rate for a day or two.
  6. Record the rotation time, owner, and scope for the next handover.

Do not rotate during peak production traffic. Running two keys in parallel for a while is much safer than delete-then-recreate.

6. Leak prevention: from developer machines to repositories

Keys rarely leak through hacker attacks; they leak through self-commits, screenshots, screen recordings, group chats, and logs. Follow these practices:

  • Cover .env, .env.*, .claude/settings.local.json, *.pem, and similar files in .gitignore.
  • Run secret scanning or a pre-commit hook for patterns such as sk- before committing.
  • Never hardcode a default key, and do not debug with echo $ANTHROPIC_AUTH_TOKEN.
  • Redact Authorization, x-api-key, and similar headers in logs.
  • Clear terminal history or the screen before screen sharing and screenshots.
  • Set file permissions on developer machines, for example chmod 600 ~/.claude/settings.json.
  • Use keys with expiration dates and quotas to limit the damage of a single leak.

If a leak is confirmed, the order is: disable or delete the key, create a new one, then investigate usage logs and repository history. Changing a password or deleting a file is not enough, because the old key may already have been copied elsewhere.

7. CI and team use

The principle for CI environments is "keys never enter code, images, or logs." In practice:

  • Inject through the platform's secret or environment variable feature; never write them in plain text in YAML.
  • Restrict secrets to protected branches or trusted workflows.
  • Confirm logs will not print request headers; most HTTP libraries do not by default, but custom logging might.
  • Use a separate key for automation with its own quota, making anomalies easier to locate.
  • One key per team member, disabled on the day they leave; do not take the shortcut of a shared key.
  • Export usage regularly and reconcile it by member, project, and model.

If the platform supports short-lived credentials or OIDC, prefer them to reduce long-lived key storage. Availability depends on platform capabilities; check the documentation before integrating.

8. 401 troubleshooting: check in this order

A 401 means authentication failed; it does not necessarily mean the key is wrong. Work through this order, and you can usually locate the cause in minutes:

  1. Confirm which Base URL the request goes to with echo $ANTHROPIC_BASE_URL. An empty value or an old address will fail.
  2. Confirm the key has no leading or trailing spaces, line breaks, or stray quotes; copy it again from the console.
  3. Confirm the variable name: is it ANTHROPIC_AUTH_TOKEN or ANTHROPIC_API_KEY? Do not set both.
  4. Confirm the request header matches the gateway requirement: Bearer or x-api-key.
  5. Confirm the key is not expired or disabled and the account has balance.
  6. Confirm the model name exists in the gateway catalog; some platforms return 401 or 403 for models outside your permissions.
  7. If a proxy is involved, check whether it strips or rewrites the Authorization header.
  8. Reproduce with a minimal curl request to rule out Claude Code version or configuration-layer interference.

Common error reference:

Error Common cause Action
401 auth failure Wrong key, variable name, or header Re-copy; keep only one auth variable
403 Forbidden Key lacks model permission or IP restriction Check allowlists and model permissions
404 Not Found Wrong Base URL or path Test the root address and /v1 variants one by one
429 Too Many Requests Concurrency or quota exceeded Reduce concurrency; check the key's limit
insufficient quota Insufficient balance Top up or switch keys

If curl works but Claude Code still returns 401, focus on the launch environment: IDE-integrated terminals, Docker, systemd, and launchd may not inherit your shell variables. Writing the configuration into settings.json or a launch script usually solves it.

FAQ

Is the Claude Code key the same as a Claude web subscription?

No. A web subscription is a chat product plan; an API key is an interface credential. Claude Code makes API calls and cannot use a web subscription in place of a key.

Can one key serve both Claude Code and Cursor?

Technically yes, as long as both tools support the same gateway protocol and model names. Still, separate keys per tool make quota limits, troubleshooting, and revocation easier.

Is it safe to store the key in settings.json?

On a personal machine it is acceptable because the file stays local. Do not put plain-text keys on shared machines, in repositories, or in CI; use environment variables, apiKeyHelper, or a secrets manager instead.

Does key rotation require downtime?

No. Create and verify the new key, switch the configuration, then disable the old key. Running both keys in parallel for a while avoids interrupted requests.

Why did it work yesterday but return 401 today?

Common causes include key expiration, insufficient balance, exhausted quota, an administrator disabling the key, a gateway changing its authentication method, or a launch environment that did not load the latest variables. Work through the 401 checklist item by item.

Next steps

If you do not have a key yet, create a low-quota test key at the sign-up page, then configure and verify it in the order described here. See model pricing for models, quotas, and billing; prices change with model versions and upstream policy, and the live page takes precedence.

Related reading: