- Published on
Claude Code Environment Variables: Complete Reference
- Authors

- Name
- Rakesh Tembhurne
- @tembhurnerakesh
Claude Code talks to the Anthropic Messages API. When you point it at a custom model, a third-party provider, or an internal LLM gateway, environment variables are the entire configuration surface. There is no plugin file and no separate provider config. You set a base URL, a credential, and the model names the endpoint understands.
This reference lists every variable for custom models and providers, with exact syntax, precedence rules, and the errors each one prevents. It covers Claude Code v2.1.x on the current release channel.
If you want the step-by-step setup first, read How to Add Custom Model Provider to Claude Code. This page is the lookup table.
Table of Contents
Table of Contents
- The three places variables can live
- Quick reference
- Base URL and credentials
- ANTHROPIC_BASE_URL
- ANTHROPIC_AUTH_TOKEN compared with ANTHROPIC_API_KEY
- apiKeyHelper in settings.json
- Custom request headers
- ANTHROPIC_CUSTOM_HEADERS
- Model selection variables
- Alias families
- Custom model in the /model picker
- Gateway model discovery
- Subagent model
- A complete settings.json example
- Other settings keys that affect custom models
- Provider-specific gateway variables
- Amazon Bedrock
- Google Cloud Agent Platform (Vertex)
- Microsoft Foundry
- Verify what is active
- Troubleshooting
- What Anthropic does and does not support
- Frequently asked questions
- What is ANTHROPIC_BASE_URL in Claude Code?
- How do ANTHROPIC_AUTH_TOKEN and ANTHROPIC_API_KEY differ?
- How do I add custom headers to Claude Code requests?
- How do I make a custom model appear in /model picker?
- Where should I put Claude Code credentials?
- Related reading
- Closing
The three places variables can live
Claude Code reads environment variables from three sources:
- Your shell, for example
~/.zshrcor~/.bashrc. - The
envblock of asettings.jsonfile. - Provider-specific flags such as the Bedrock, Vertex, and Foundry switches.
A settings-file env value wins over a shell export of the same variable. The file applies to every launch, including background agents. A shell export applies only to terminals where you exported it.
The settings.json scopes are:
| Scope | File | Who it affects |
|---|---|---|
| User | ~/.claude/settings.json | You, in every project on this machine |
| Project | .claude/settings.json | Everyone in the repo, because it is committed |
| Project local | .claude/settings.local.json | You, in this one project, gitignored by default |
| Managed | managed-settings.json and MDM | Everyone your organization deploys to |
File precedence, highest first: managed, --settings, .claude/settings.local.json, .claude/settings.json, ~/.claude/settings.json.
Security note: never put a credential in .claude/settings.json. That file is committed and shared with everyone who clones the repository. Put credentials in ~/.claude/settings.json or .claude/settings.local.json, and add the local file to your gitignore before you write to it.
Quick reference
| Variable | Purpose | Added or changed |
|---|---|---|
ANTHROPIC_BASE_URL | Override the API endpoint for a proxy or gateway | Long standing |
ANTHROPIC_AUTH_TOKEN | Credential sent as Authorization: Bearer | Long standing |
ANTHROPIC_API_KEY | Credential sent as X-Api-Key | Long standing |
ANTHROPIC_CUSTOM_HEADERS | Extra request headers, newline separated | v2.1.227+ |
ANTHROPIC_MODEL | Main model alias or full name | Long standing |
ANTHROPIC_DEFAULT_MODEL | Model new sessions start on | v2.1.236+ |
ANTHROPIC_DEFAULT_OPUS_MODEL | What the opus alias resolves to | Long standing |
ANTHROPIC_DEFAULT_SONNET_MODEL | What the sonnet alias resolves to | Long standing |
ANTHROPIC_DEFAULT_HAIKU_MODEL | What the haiku alias resolves to | Replaces ANTHROPIC_SMALL_FAST_MODEL |
ANTHROPIC_DEFAULT_FABLE_MODEL | What the fable alias resolves to | Long standing |
ANTHROPIC_SMALL_FAST_MODEL | Deprecated background model | Superseded |
ANTHROPIC_CUSTOM_MODEL_OPTION | Custom entry in the /model picker | Long standing |
CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY | Populate the picker from the gateway | Off by default |
CLAUDE_CODE_SUBAGENT_MODEL | Model for subagents and agent teams | Force flag v2.1.257+ |
CLAUDE_CODE_MAX_CONTEXT_TOKENS | Override the assumed context window | v2.1.93+ |
CLAUDE_CODE_API_KEY_HELPER_TTL_MS | Credential helper cache lifetime | Long standing |
Base URL and credentials
ANTHROPIC_BASE_URL
ANTHROPIC_BASE_URL changes where requests are sent. It does not change which model answers them. Set it to an Anthropic-compatible endpoint and Claude Code sends the same Messages API requests there.
export ANTHROPIC_BASE_URL="https://llm-gateway.example.com"
export ANTHROPIC_AUTH_TOKEN="sk-gateway-key"
When the base URL is a non-first-party host, MCP tool search is disabled by default. Set ENABLE_TOOL_SEARCH=true if your proxy forwards tool_reference blocks. Starting in v2.1.196, Remote Control is also disabled when the base URL points at a host other than api.anthropic.com, matching the behavior on Bedrock, Vertex, and Foundry.
Setting only ANTHROPIC_BASE_URL without a gateway credential does not replace your Claude subscription. Requests route through the gateway, but a saved claude.ai login stays the active credential, so its usage limits and billing still apply.
ANTHROPIC_AUTH_TOKEN compared with ANTHROPIC_API_KEY
They land in different HTTP headers. A gateway that reads one rejects the other with a 401.
| Variable | HTTP header | Notes |
|---|---|---|
ANTHROPIC_AUTH_TOKEN | Authorization: Bearer <value> | Use when the gateway says "bearer token" or "Authorization header" |
ANTHROPIC_API_KEY | X-Api-Key: <value> | Use when the gateway says "API key" or "x-api-key" |
apiKeyHelper output | Both headers | Use for rotating credentials |
A credential placed in the wrong variable reaches the gateway in a header it does not read and fails. If you are unsure which one a gateway expects, start with ANTHROPIC_AUTH_TOKEN.
ANTHROPIC_API_KEY also changes subscription behavior. When it is set, it is used instead of a Claude Pro, Max, Team, or Enterprise subscription, even if you are logged in. In non-interactive -p mode the key is always used. In interactive mode you approve it once. To go back to your subscription, run unset ANTHROPIC_API_KEY.
A gateway credential always takes precedence over a saved login. If both are present, startup prints an auth conflict warning. Unset the gateway variable to return to the saved login.
apiKeyHelper in settings.json
For short-lived or rotating credentials, use apiKeyHelper. Claude Code runs the command through the system shell and sends the output in both the Authorization and X-Api-Key headers, so it works whichever header the gateway reads.
{
"apiKeyHelper": "~/bin/get-gateway-key.sh"
}
The output is cached for 5 minutes by default. Change that with CLAUDE_CODE_API_KEY_HELPER_TTL_MS. Claude Code re-runs the helper after a 401 or 403, and before a request when the cached value is an expired JWT. Both re-run behaviors apply only when ANTHROPIC_AUTH_TOKEN is not set.
From project or local settings, the helper does not run until you accept the workspace trust prompt.
Custom request headers
ANTHROPIC_CUSTOM_HEADERS
Some gateways route or tag requests with a header in addition to the credential, for example a tenant identifier or a routing key. ANTHROPIC_CUSTOM_HEADERS adds those headers to every request. Each entry is a Name: Value pair, newline separated. This variable requires Claude Code v2.1.227 or later.
Shell form:
export ANTHROPIC_CUSTOM_HEADERS="X-Org-Route: prod
X-Tenant: example"
Settings-file form. JSON strings cannot span multiple lines, so use \n between pairs:
{
"env": {
"ANTHROPIC_CUSTOM_HEADERS": "X-Org-Route: prod\nX-Tenant: example"
}
}
If a name or value contains a character an HTTP header cannot carry, such as a curly quote or a zero-width space, the request fails with an error that identifies the pair by position. The characters that fail include line breaks, NUL, and anything above U+00FF. The check runs for direct API and LLM gateway connections, but not before sending to a third-party cloud provider such as Bedrock. When a custom header has a non-empty value, it is sent in place of a built-in header with the same name, case-insensitively.
If you are on managed settings and trying to add headers that name a credential, an org or tenant selector, or an API-behavior header such as Authorization, X-Api-Key, Host, or anthropic-beta, those require approval. Headers that only tag requests, such as Accept-Language, apply without a prompt.
Model selection variables
Claude Code resolves a model from several sources, highest priority first:
/model <alias or name>during a session.claude --model <name>on the command line.ANTHROPIC_MODEL.- The
modelkey in a settings file. ANTHROPIC_DEFAULT_MODEL.
ANTHROPIC_MODEL accepts an alias such as sonnet, or a full model name. Behind a custom base URL or gateway, the provider defines the names, so Claude Code passes any string through without validating it. The "not a recognized model id" check runs only on the Anthropic API.
Alias families
The alias tiers map to family variables. Set these whenever a non-Anthropic endpoint is active. Otherwise Claude Code sends built-in names the endpoint does not know, and you get silent model-not-found failures.
export ANTHROPIC_DEFAULT_OPUS_MODEL="your-opus-class-model"
export ANTHROPIC_DEFAULT_SONNET_MODEL="your-sonnet-class-model"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="your-haiku-class-model"
export ANTHROPIC_DEFAULT_FABLE_MODEL="your-fable-class-model"
ANTHROPIC_SMALL_FAST_MODEL is deprecated. It was the Haiku-class background model and is superseded by ANTHROPIC_DEFAULT_HAIKU_MODEL. New setups should use the ANTHROPIC_DEFAULT_* family.
ANTHROPIC_DEFAULT_MODEL sets the model new sessions start on. It requires v2.1.236 or later. It is ignored if set to default, inherit, opusplan, or haiku, and it applies only when no command-line flag, ANTHROPIC_MODEL, settings key, or organization default selects a model.
Each family variable has companion display and capability variables. _NAME and _DESCRIPTION control the label in the /model picker and also apply behind a gateway. _SUPPORTED_CAPABILITIES declares features such as effort, thinking, and interleaved_thinking so Claude Code does not disable them for a model ID it cannot match.
export ANTHROPIC_DEFAULT_OPUS_MODEL_NAME="Opus (internal gateway)"
export ANTHROPIC_DEFAULT_OPUS_MODEL_DESCRIPTION="Routed through the company gateway"
export ANTHROPIC_DEFAULT_OPUS_MODEL_SUPPORTED_CAPABILITIES="effort,thinking"
Custom model in the /model picker
If the endpoint exposes a model that is not in the built-in list, add it to the picker with ANTHROPIC_CUSTOM_MODEL_OPTION. Claude Code skips validation for this ID, so any string your endpoint accepts works.
export ANTHROPIC_CUSTOM_MODEL_OPTION="my-gateway/claude-opus-5"
export ANTHROPIC_CUSTOM_MODEL_OPTION_NAME="Opus via Gateway"
export ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION="Custom deployment routed through the internal LLM gateway"
The custom entry appears at the bottom of the /model picker. The name and description are optional. If omitted, the model ID is used as the name and the description defaults to Custom model (<id>).
A custom ID that embeds a family name, such as my-gateway/claude-opus-5, counts as a specific entry for that family and disables its wildcard. If you use an allowlist, include the custom ID or it is filtered from the picker.
Gateway model discovery
Instead of listing models one by one, you can populate the picker from the gateway's own model list. Set CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1 when ANTHROPIC_BASE_URL points at an Anthropic-compatible gateway such as LiteLLM, Kong, or an internal proxy.
export CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1
Discovery is off by default because a gateway backed by a shared API key would otherwise show every user every model the key can access. It calls GET /v1/models?limit=1000 with a 3-second timeout, then keeps entries whose ID contains claude or anthropic, case-insensitively. Discovered models are still filtered by an availableModels allowlist.
Subagent model
CLAUDE_CODE_SUBAGENT_MODEL sets the model for subagents, agent-team teammates, and workflow agents that are not assigned a model another way. It accepts an alias or a full name. Two sources override it: a model Claude passes when it spawns the agent, and a model field in the agent's definition. Set CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1 to force one model onto all of them.
A complete settings.json example
This file points Claude Code at a gateway, supplies a rotating credential, tags requests with a routing header, and adds a custom picker entry. Put it in ~/.claude/settings.json so it applies to every project and to background agents.
{
"env": {
"ANTHROPIC_BASE_URL": "https://llm-gateway.example.com",
"ANTHROPIC_CUSTOM_HEADERS": "X-Org-Route: prod\nX-Tenant: example",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "gateway/opus-class",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "gateway/sonnet-class",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "gateway/haiku-class",
"ANTHROPIC_CUSTOM_MODEL_OPTION": "gateway/experimental-1",
"ANTHROPIC_CUSTOM_MODEL_OPTION_NAME": "Gateway Experimental",
"CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY": "1"
},
"apiKeyHelper": "~/bin/get-gateway-key.sh",
"model": "gateway/sonnet-class"
}
The apiKeyHelper output is sent in both credential headers, so this file does not need ANTHROPIC_AUTH_TOKEN. If the gateway expects a static bearer token instead, drop the helper and add ANTHROPIC_AUTH_TOKEN to the env block.
Other settings keys that affect custom models
modelOverrides maps an Anthropic model ID to a provider-specific ID. Use it on Bedrock, Vertex, or Foundry when each picker entry should call a different deployment.
{
"modelOverrides": {
"claude-opus-4-7": "arn:aws:bedrock:us-east-2:123456789012:application-inference-profile/opus-prod",
"claude-sonnet-4-6": "arn:aws:bedrock:us-east-2:123456789012:application-inference-profile/sonnet-prod"
}
}
modelPicker controls the order and labels of /model rows directly. It is a user or managed setting only, ignored in project and local files, and requires v2.1.242 or later.
{
"modelPicker": {
"options": [
{ "model": "gateway/sonnet-class", "label": "Sonnet (production)", "description": "Day-to-day work" },
{ "model": "gateway/opus-class", "label": "Opus (production)" }
]
}
}
Set replaceBuiltInOptions: true to hide the built-in rows, the discovery rows, the allowlist rows, and the ANTHROPIC_CUSTOM_MODEL_OPTION entry.
Provider-specific gateway variables
These are the switches for the three cloud providers Anthropic supports natively. They replace ANTHROPIC_BASE_URL with a provider base URL and a use flag.
Amazon Bedrock
export CLAUDE_CODE_USE_BEDROCK=1
export ANTHROPIC_BEDROCK_BASE_URL="https://bedrock-runtime.us-east-1.amazonaws.com"
export ANTHROPIC_MODEL="us.anthropic.claude-sonnet-4-6-v1:0"
Add CLAUDE_CODE_SKIP_BEDROCK_AUTH=1 when the gateway holds the AWS credentials.
Google Cloud Agent Platform (Vertex)
export CLAUDE_CODE_USE_VERTEX=1
export ANTHROPIC_VERTEX_BASE_URL="https://REGION-aiplatform.googleapis.com"
export ANTHROPIC_VERTEX_PROJECT_ID="your-project-id"
export CLOUD_ML_REGION="us-east1"
Add CLAUDE_CODE_SKIP_VERTEX_AUTH=1 when the gateway signs requests.
Microsoft Foundry
export CLAUDE_CODE_USE_FOUNDRY=1
export ANTHROPIC_FOUNDRY_BASE_URL="https://your-resource.services.ai.azure.com"
export ANTHROPIC_FOUNDRY_API_KEY="your-foundry-key"
Add CLAUDE_CODE_SKIP_FOUNDRY_AUTH=1 when the gateway injects the Authorization header itself. An optional ANTHROPIC_FOUNDRY_AUTH_TOKEN sends a bearer token and takes precedence over the API key.
Verify what is active
/status is the fastest check. When a gateway address is set, it shows the base URL and the credential source, for example Auth token: ANTHROPIC_AUTH_TOKEN. If it shows a saved login instead, your credential variable is not being read.
claude --debug prints gateway discovery lines, which helps when the picker is empty. A discovery failure is silent in normal mode.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| 401 from the gateway | Credential in the wrong variable | Move it between ANTHROPIC_AUTH_TOKEN and ANTHROPIC_API_KEY |
| Picker still shows Claude models | Base URL not applied | Set it in a settings file and confirm with /status |
| Model not found | Alias tiers unmapped | Set ANTHROPIC_DEFAULT_*_MODEL for every tier |
| Picker empty on a gateway | Discovery off | Set CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1 |
| Auth conflict warning | Gateway credential plus saved login | Unset the gateway variable, or log out |
| Custom headers rejected | Invalid character | Remove curly quotes, zero-width spaces, and non-ASCII values |
| Remote Control or voice unavailable | Gateway credential in use | Expected; both are disabled behind gateway credentials |
What Anthropic does and does not support
Anthropic documents the gateway mechanism and names LiteLLM and Kong as examples of Anthropic-compatible gateways. Anthropic also states that it does not endorse, maintain, or audit third-party gateway products, and does not support routing Claude Code to non-Claude models through any gateway.
In practice that means the base URL and credential variables are stable, documented interfaces, while the behavior of any given third-party model behind them is the provider's responsibility. If tool calls break or a model ignores the system prompt, that is a compatibility problem at the endpoint, not a Claude Code bug.
Frequently asked questions
What is ANTHROPIC_BASE_URL in Claude Code?
ANTHROPIC_BASE_URL overrides the API endpoint. Point it at an Anthropic-compatible gateway such as https://llm-gateway.example.com and Claude Code sends the same Messages API requests there. It does not change which model answers. See the Anthropic gateway docs.
How do ANTHROPIC_AUTH_TOKEN and ANTHROPIC_API_KEY differ?
ANTHROPIC_AUTH_TOKEN sends Authorization: Bearer, ANTHROPIC_API_KEY sends X-Api-Key. A gateway that reads one rejects the other with 401. If unsure, start with ANTHROPIC_AUTH_TOKEN. Both override a saved claude.ai login.
How do I add custom headers to Claude Code requests?
Use ANTHROPIC_CUSTOM_HEADERS (requires v2.1.227+). One Name: Value per line. In JSON use \n between pairs: "ANTHROPIC_CUSTOM_HEADERS": "X-Org-Route: prod\nX-Tenant: example".
How do I make a custom model appear in /model picker?
Use ANTHROPIC_CUSTOM_MODEL_OPTION for one entry, or enable CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1 to populate the picker from the gateway's /v1/models endpoint (v2.1.248+ for both credential headers).
Where should I put Claude Code credentials?
In ~/.claude/settings.json for all projects or .claude/settings.local.json for one project. Never in .claude/settings.json, which is committed. The file's env block wins over shell exports and applies to background agents.
Related reading
- How to Add Custom Model Provider to Claude Code
- Extending Claude Code with Multiple Models
- Building a Claude Code Router
Sources: Claude Code environment variables · Model configuration · LLM gateway · Settings files
Closing
Customizing Claude Code is an environment variable problem. Set the base URL, pick the credential header the gateway reads, map the alias tiers, and add any headers or picker entries you need. Keep credentials out of committed files, and confirm the result with /status before you debug anything else.
Related Posts
How to Change Model in Claude Code: /model, --model, Aliases
Learn to change and switch models in Claude Code with /model, --model, ANTHROPIC_MODEL, and aliases. Persist defaults and show gateway models in picker.
How to Add Custom Model Provider to Claude Code: 2026 Guide
Discover how to point Claude Code at custom providers — OpenRouter, DeepSeek, Kimi, Z.ai, Ollama, and LiteLLM. Complete working settings.json recipes inside.
The AI Developer Toolkit in 2026: From Claude Code to DeepSeek
A practical breakdown of 1000+ Twitter insights on AI tools, frameworks, and strategies that are reshaping how solo developers and indie hackers build products in 2026.