Published on

Claude Code Environment Variables: Complete Reference

Authors

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

Claude Code reads environment variables from three sources:

  1. Your shell, for example ~/.zshrc or ~/.bashrc.
  2. The env block of a settings.json file.
  3. 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:

ScopeFileWho it affects
User~/.claude/settings.jsonYou, in every project on this machine
Project.claude/settings.jsonEveryone in the repo, because it is committed
Project local.claude/settings.local.jsonYou, in this one project, gitignored by default
Managedmanaged-settings.json and MDMEveryone 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

VariablePurposeAdded or changed
ANTHROPIC_BASE_URLOverride the API endpoint for a proxy or gatewayLong standing
ANTHROPIC_AUTH_TOKENCredential sent as Authorization: BearerLong standing
ANTHROPIC_API_KEYCredential sent as X-Api-KeyLong standing
ANTHROPIC_CUSTOM_HEADERSExtra request headers, newline separatedv2.1.227+
ANTHROPIC_MODELMain model alias or full nameLong standing
ANTHROPIC_DEFAULT_MODELModel new sessions start onv2.1.236+
ANTHROPIC_DEFAULT_OPUS_MODELWhat the opus alias resolves toLong standing
ANTHROPIC_DEFAULT_SONNET_MODELWhat the sonnet alias resolves toLong standing
ANTHROPIC_DEFAULT_HAIKU_MODELWhat the haiku alias resolves toReplaces ANTHROPIC_SMALL_FAST_MODEL
ANTHROPIC_DEFAULT_FABLE_MODELWhat the fable alias resolves toLong standing
ANTHROPIC_SMALL_FAST_MODELDeprecated background modelSuperseded
ANTHROPIC_CUSTOM_MODEL_OPTIONCustom entry in the /model pickerLong standing
CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERYPopulate the picker from the gatewayOff by default
CLAUDE_CODE_SUBAGENT_MODELModel for subagents and agent teamsForce flag v2.1.257+
CLAUDE_CODE_MAX_CONTEXT_TOKENSOverride the assumed context windowv2.1.93+
CLAUDE_CODE_API_KEY_HELPER_TTL_MSCredential helper cache lifetimeLong 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.

VariableHTTP headerNotes
ANTHROPIC_AUTH_TOKENAuthorization: Bearer <value>Use when the gateway says "bearer token" or "Authorization header"
ANTHROPIC_API_KEYX-Api-Key: <value>Use when the gateway says "API key" or "x-api-key"
apiKeyHelper outputBoth headersUse 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:

  1. /model <alias or name> during a session.
  2. claude --model <name> on the command line.
  3. ANTHROPIC_MODEL.
  4. The model key in a settings file.
  5. 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

SymptomLikely causeFix
401 from the gatewayCredential in the wrong variableMove it between ANTHROPIC_AUTH_TOKEN and ANTHROPIC_API_KEY
Picker still shows Claude modelsBase URL not appliedSet it in a settings file and confirm with /status
Model not foundAlias tiers unmappedSet ANTHROPIC_DEFAULT_*_MODEL for every tier
Picker empty on a gatewayDiscovery offSet CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1
Auth conflict warningGateway credential plus saved loginUnset the gateway variable, or log out
Custom headers rejectedInvalid characterRemove curly quotes, zero-width spaces, and non-ASCII values
Remote Control or voice unavailableGateway credential in useExpected; 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.

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