How to route Claude Code through an AI gateway

To route Claude Code through an AI gateway, set ANTHROPIC_BASE_URL to the gateway address and give it a credential in ANTHROPIC_AUTH_TOKEN, ANTHROPIC_API_KEY or an apiKeyHelper command. The base URL alone does not replace a saved claude.ai login. Then push the same values through managed settings.
Checked against the Claude Code LLM gateway, network configuration, environment variables and managed settings docs as of 2026-10-25. The docs name the variables used below but do not give a Claude Code CLI version for the basic setup. The one version gate is allowedProviders, which needs v2.1.285 or later.
Set the base URL and credential
Test in a shell first. Exported variables apply only to that terminal and to programs started from it, so this is a check, not the rollout. Replace the values with the ones your gateway team issued.
- Export
ANTHROPIC_BASE_URLwith the gateway’s base URL. - Export one credential variable,
ANTHROPIC_AUTH_TOKENorANTHROPIC_API_KEY, that matches the header your gateway reads. - Start
claudefrom the same shell and send a message.
export ANTHROPIC_BASE_URL=https://llm-gateway.example.com
export ANTHROPIC_AUTH_TOKEN=sk-gateway-key
When the same variable is set in a shell and in a settings file, the settings file value applies, so a shell export left over from testing will not override the file. Use /status to see which base URL and credential source the session uses.
Choose the credential variable
The three credential options send the key differently. The gateway team’s wording usually tells you which one to use. If the credential rotates or comes from a vault, apiKeyHelper is the only option that fetches it at run time.
| Option | Sent as | Use when |
|---|---|---|
ANTHROPIC_AUTH_TOKEN |
Authorization: Bearer header |
The gateway expects a bearer token |
ANTHROPIC_API_KEY |
X-Api-Key header |
The gateway expects an API key or x-api-key |
apiKeyHelper |
Both headers | The credential rotates or comes from a vault or SSO command |
For apiKeyHelper, the setting is a command that prints only the credential to stdout. Claude Code caches its output for five minutes by default, and CLAUDE_CODE_API_KEY_HELPER_TTL_MS changes that interval. Write the script so nothing else prints to stdout, because on v2.1.227 or later a stray banner makes the helper fail.
Verify the connection before Claude Code sees it
Send one request to the gateway with curl. This separates a gateway problem from a Claude Code configuration problem. A JSON response beginning {"id":"msg_ with a content array means the URL and credential work. The model name must be one your gateway routes. An error that names an unknown model still proves the credential was accepted.
curl -sS -w '\n%{http_code}\n' -X POST "$ANTHROPIC_BASE_URL/v1/messages" \
-H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model": "claude-sonnet-4-6", "max_tokens": 1, "messages": [{"role": "user", "content": "."}]}'
Then open /status in Claude Code. The Status tab should show an Anthropic base URL line with your gateway address, and an Auth token or API key line that names the variable you set. A Login method line naming a claude.ai account means the credential did not reach the session.
Pick where the settings live
The same env block works in several places. Each location reaches a different set of sessions, so choose by who should get the setting.
| Location | Reaches | Use for |
|---|---|---|
| Shell export | That terminal and programs started from it | A first test only |
~/.claude/settings.json env |
Every project on the machine, including background agents | A developer’s own setup |
.claude/settings.local.json env |
One project, not committed | A per-project credential, after adding the file to .gitignore |
| Managed settings file | Every project, above all other levels | An organization rollout |
claudeCode.environmentVariables in VS Code user settings |
The VS Code extension | VS Code users, which the CLI settings do not reach |
Do not put the credential in a project’s .claude/settings.json. That file is committed and shared with everyone who clones the repository. The docs also note that shell exports reach background agents unreliably, so use a settings file for any gateway that background agents must always use.
Roll it out with managed settings
For an organization, deliver the gateway address and credential in a managed settings file, pushed by MDM or configuration management. The file must sit in the system directory for each operating system. Add allowedProviders so a session cannot be pointed somewhere else.
- Write
managed-settings.jsonwith the gateway address in theenvblock. - Add
"allowedProviders": ["customEndpoint"], which refuses any other destination, including Anthropic directly. Requires Claude Code v2.1.285 or later. - Put the file at the path for each platform: macOS
/Library/Application Support/ClaudeCode/managed-settings.json, Linux and WSL/etc/claude-code/managed-settings.json, WindowsC:\Program Files\ClaudeCode\managed-settings.json. - Restart Claude Code and check
/statuson one machine before the wider push.
{
"env": {
"ANTHROPIC_BASE_URL": "https://llm-gateway.example.com"
},
"apiKeyHelper": "/usr/local/bin/get-gateway-key",
"allowedProviders": ["customEndpoint"]
}
Do not add forceLoginMethod, forceLoginOrgUUID or forceLoginGatewayUrl to this file. Those keys block gateway credentials at startup, and developers cannot get past the prompt. Server-managed settings also do not reach sessions routed through a gateway, so the file is the delivery path.
Know what still bypasses the gateway
Routing model requests does not cover everything Claude Code sends. The gaps below come from the docs’ network and gateway pages. Each one needs a decision before you trust the setup for audit or egress control.
- Fast mode check: it calls
api.anthropic.comdirectly and does not followANTHROPIC_BASE_URL./fastcan report fast mode as unavailable even when inference works. - Nonessential traffic:
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1removes it, but it also disables auto-updates, so plan another update path. - WebFetch: its domain safety check still calls
api.anthropic.comunlessskipWebFetchPreflightis set totruein settings. - Remote Control and voice dictation: both are unavailable while a gateway credential is set, and Remote Control is also disabled when
ANTHROPIC_BASE_URLpoints at a non-Anthropic host. - Cloud sessions and Slack: gateway variables set in a cloud session’s environment are not applied.
Corporate proxies work separately. Claude Code reads HTTPS_PROXY, HTTP_PROXY and NO_PROXY at startup and does not support SOCKS proxies. A proxy URL it cannot parse stops launch with an error that names the variable.
Troubleshoot the common failures
Most gateway failures come down to four causes. The table lists the symptom, the cause and the fix from the connect page.
| Symptom | Cause | Fix |
|---|---|---|
401 naming an invalid token |
Credential in the wrong variable, so the gateway reads a header it does not expect | Switch between ANTHROPIC_AUTH_TOKEN and ANTHROPIC_API_KEY |
| Login screen despite a working curl test | No credential reached the CLI before first-run setup | Set the credential in a shell export, ~/.claude/settings.json, or managed settings |
| Auth conflict warning at startup | A gateway credential and a saved login are both active | Unset the variable to use the login, or run /logout to use the gateway |
400 naming an unrecognized field |
The gateway forwards fields its upstream rejects | Set CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1, then forward headers and bodies unchanged |
The gateway itself must forward anthropic-beta, anthropic-version and the request body in both directions, stream responses without buffering, and return upstream errors unchanged. A gateway that wraps errors in its own envelope breaks Claude Code’s automatic recovery, which matches on error wording.
Enforcing this with AIControls
A settings file applies one machine at a time, and a gateway sits in front of every session that routes through it. AIControls supports Claude Code through its gateway for both the CLI and VS Code. It provides per-user tokens, per-user and per-session cost and budget limits, and holds PII for approval or redacts or blocks it. For the governance side of coding agents, see governance for AI coding agents, and read the AI gateway buyer’s guide for what to compare when you choose one. Download AIControls to run it in your own environment.
Frequently asked questions
Which environment variable points Claude Code at an AI gateway?
ANTHROPIC_BASE_URL. Claude Code's documentation describes it as the override for the API endpoint, used to route requests through a proxy or gateway. Set it to your gateway's base URL. On its own it sends requests to the gateway but does not replace a saved claude.ai login, so you also need a gateway credential in ANTHROPIC_AUTH_TOKEN, ANTHROPIC_API_KEY or an apiKeyHelper command.
Should the gateway credential go in ANTHROPIC_AUTH_TOKEN or ANTHROPIC_API_KEY?
Match the header your gateway reads. ANTHROPIC_AUTH_TOKEN is sent as an Authorization Bearer header. ANTHROPIC_API_KEY is sent as an X-Api-Key header. A credential in the wrong variable reaches the gateway in a header it does not read, and the request fails with a 401. If you are not sure, the connect page says to start with ANTHROPIC_AUTH_TOKEN and switch if the verification request returns 401.
Can developers override the gateway settings on their own machines?
Not when the values come from a managed settings file. Claude Code applies managed settings above user, project, local and command-line values, and the docs say a managed ANTHROPIC_BASE_URL cannot be overridden by a developer's shell export. Shell exports and project settings files are the weaker options for a rollout, because the project file is committed to the repository and must not hold a credential.
Does routing through a gateway stop all traffic to Anthropic?
No. Model requests go to the gateway, but some background traffic does not. The fast mode availability check calls api.anthropic.com directly, and the WebFetch domain safety check still calls it unless skipWebFetchPreflight is set. Setting CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC to 1 turns off that traffic, but it also turns off auto-updates.