Skip to content

Claude Code LLM Gateway: Routing, Credentials, and Headers

Core Concept LearningAugust 18, 202614 min readUpdated October 17, 2026

Many companies already run an LLM gateway, such as LiteLLM, a cloud API gateway, or an in-house proxy, between their developers and the model providers. Claude Code works behind one: point it at the gateway's URL, give it a gateway-issued credential, and every model request goes through the gateway instead of straight to Anthropic or your cloud provider.

The setup is two environment variables. The hard part is everything around them: which credential variable puts the key in which header, how to distribute the configuration so developers do not set it by hand, which headers and body fields the gateway must pass through untouched, and what still bypasses the gateway. This guide follows Anthropic's gateway documentation for each of those, and ends with the errors you are most likely to hit.

Anthropic also ships its own self-hosted gateway, the Claude apps gateway, aimed at organisations that run Claude through Bedrock, Google Cloud, or Foundry. It is covered in Claude Apps Gateway. For the managed settings used to distribute gateway configuration, see Claude Code Enterprise Setup.

An LLM gateway sits between Claude Code and the model provider: developers hold gateway credentials, the gateway holds the provider key
An LLM gateway sits between Claude Code and the model provider: developers hold gateway credentials, the gateway holds the provider key

What a gateway gives you, and what it costs

A gateway gives an organisation one place to manage five things:

  • Credentials: the provider key stays on the gateway. Developers hold a gateway credential, and offboarding someone revokes one key.
  • Usage tracking: usage is attributed by developer or team, whichever provider served the request.
  • Cost controls: budgets and rate limits are enforced in one place.
  • Audit logging: every model request can be logged for compliance.
  • Provider switching: change the upstream in the gateway's configuration, without touching laptops, as long as the gateway exposes one Anthropic-format endpoint whatever the upstream.

The cost is that the gateway becomes infrastructure you operate, and it has to keep up with Claude Code. New capabilities arrive as new anthropic-beta header values and new request fields. A gateway that strips or rejects them breaks the matching features, sometimes with an error and sometimes silently.

Billing changes too. While a gateway credential (or an apiKeyHelper) is active, requests carry that credential instead of a developer's claude.ai login, so subscription usage limits do not apply and the traffic is billed per token to whoever owns the key the gateway forwards, such as your Console organisation or your Bedrock account. Setting only ANTHROPIC_BASE_URL without a gateway credential routes traffic through the gateway but still bills the developer's subscription.

Quick reference

  • Anthropic does not endorse, maintain, or audit third-party gateway products, and does not support routing Claude Code to non-Claude models through a gateway.
  • Sessions that go through a gateway are not eligible for the HIPAA configuration.
  • A custom ANTHROPIC_BASE_URL also makes Claude Code skip fetching server-managed settings, so deliver policy for gateway users through MDM or a managed settings file.

Remember this

A gateway centralises keys, budgets, and logs, at the price of a compatibility surface you must maintain on every Claude Code release.

Connect one machine: base URL, credential, verify

Every connection needs two variables: the gateway's base URL and a credential. Which credential variable you use decides which HTTP header carries it:

  • ANTHROPIC_AUTH_TOKEN is sent as Authorization: Bearer .... Use it when the gateway team says "bearer token" or "Authorization header".
  • ANTHROPIC_API_KEY is sent as x-api-key: .... Use it when they say "API key" or "x-api-key".
  • apiKeyHelper is a command whose output is sent in both headers. Use it when the credential rotates or comes from a vault.

A credential in the wrong variable reaches the gateway in a header it does not read, and you get 401.

Test with shell exports first, before Claude Code is involved:

1export ANTHROPIC_BASE_URL=https://llm-gateway.example.com2export ANTHROPIC_AUTH_TOKEN=sk-gateway-key3 4curl -sS -w '\n%{http_code}\n' -X POST "$ANTHROPIC_BASE_URL/v1/messages" \5  -H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \6  -H "anthropic-version: 2023-06-01" \7  -H "content-type: application/json" \8  -d '{"model": "claude-sonnet-4-6", "max_tokens": 1, "messages": [{"role": "user", "content": "."}]}'

A JSON body starting with {"id":"msg_ means the URL and credential work. An "unknown model" error also proves the credential works, since the gateway authenticated the request before rejecting the model. A 401 means switch to the other credential variable.

Then start claude from the same shell and run /status. The Anthropic base URL row should show the gateway, and an Auth token or API key row should name your variable. If you see a Login method row with a claude.ai account instead, the credential did not reach the session.

Connecting Claude Code to a gateway: set the base URL and credential, test with curl, then confirm in /status
Connecting Claude Code to a gateway: set the base URL and credential, test with curl, then confirm in /status

Quick reference

  • To persist the values, put them in the env block of ~/.claude/settings.json. A settings-file value wins over a shell export of the same variable.
  • Never put the credential in a project's .claude/settings.json: that file is committed and shared with everyone who clones the repository.
  • ANTHROPIC_AUTH_TOKEN takes over from a saved login immediately; ANTHROPIC_API_KEY asks for a one-time approval in interactive mode first.
  • Shell exports do not reliably reach background agents or an editor launched from the dock. Use a settings file for anything that must always route through the gateway.

Remember this

Pick the credential variable by the header your gateway reads, prove it with curl, and confirm with /status.

Roll it out: per-developer keys and managed settings

For an organisation, the sequence is the same whichever gateway product you run:

1. Deploy the gateway and give it the provider credential. 2. Issue each developer their own gateway credential, so usage is attributed and offboarding revokes one key. 3. Distribute the base URL through a managed settings file and the credential through your secrets tooling, so developers configure nothing. 4. Have each developer check /status before they depend on it.

For rotating credentials, an apiKeyHelper is a command that prints the current key. Claude Code caches its output for five minutes by default (CLAUDE_CODE_API_KEY_HELPER_TTL_MS changes that) and sends it in both credential headers:

1{2  "apiKeyHelper": "~/bin/get-gateway-key.sh",3  "env": {4    "ANTHROPIC_BASE_URL": "https://llm-gateway.example.com",5    "CLAUDE_CODE_API_KEY_HELPER_TTL_MS": "900000"6  }7}

The helper must print nothing but the key; since v2.1.227 a banner or log line alongside it makes the helper fail.

To make the gateway the only allowed destination on managed machines, set allowedProviders to ["customEndpoint"] in the managed settings file and put the gateway's ANTHROPIC_BASE_URL in that file's env block (Claude Code v2.1.285 or later). Claude Code then refuses sessions pointed anywhere else, including Anthropic directly or a developer's own proxy.

Quick reference

  • VS Code: set the variables in claudeCode.environmentVariables in VS Code's user settings; values only in ~/.claude/settings.json do not reach the extension's own login check.
  • Desktop app: gateway routing comes from its third-party inference configuration, not from ANTHROPIC_BASE_URL. An admin can distribute it, or a user can set it under Developer mode.
  • GitHub Actions: put ANTHROPIC_BASE_URL in the workflow env; the action passes anthropic_api_key as x-api-key. For a bearer-token gateway, also set ANTHROPIC_AUTH_TOKEN in env.
  • Cloud sessions on the web and Claude in Slack are not part of a gateway deployment, and Remote Control is unavailable while a gateway credential is active. If traffic must stay on the gateway, do not enable those surfaces.

Remember this

One credential per developer, configuration through managed settings, and allowedProviders if the gateway must be the only route.

What the gateway must pass through

An Anthropic-format gateway serves POST /v1/messages (Claude Code sends /v1/messages?beta=true, so match on the path) and optionally /v1/messages/count_tokens. Without token counting, Claude Code falls back to a character-based estimate of context use.

The rules from Anthropic's compatibility guide:

  • Forward anthropic-version and anthropic-beta unchanged. Do not allowlist individual beta values; the set changes with every release.
  • Forward request body fields unchanged, as an open list. Many capabilities are a pair: a beta header plus a body field. Strip one half and you get a hard 400; strip both and the feature turns off quietly.
  • Keep cache_control markers wherever they appear, and do not flatten block-form system content into a string. Breaking this produces no error; every turn is just billed as uncached input.
  • Stream without buffering. Claude Code reads server-sent events as they arrive and expects the full sequence through message_stop. A gateway that buffers stalls the client, and one that drops SSE ping events can trip the idle timeout during long thinking pauses.
  • Forward error bodies unmodified. Claude Code's automatic recovery, such as retrying without a rejected capability, matches on the upstream's error wording.

Headers you may consume rather than forward include the credential headers and x-claude-code-session-id, which identifies all requests from one session. On requests from subagents, x-claude-code-agent-id identifies the agent, which helps attribute the cost of parallel agents.

What an Anthropic-format gateway must forward unchanged and what it may consume
What an Anthropic-format gateway must forward unchanged and what it may consume

Quick reference

  • If the gateway translates Anthropic-format requests to Bedrock or Google Cloud, it must bridge the schema difference. The simpler option is to expose that provider's own format and have clients use ANTHROPIC_BEDROCK_BASE_URL or ANTHROPIC_VERTEX_BASE_URL with the matching CLAUDE_CODE_USE_* and skip-auth variables.
  • CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 stops most pre-release capabilities and their body fields when the upstream rejects them, at the cost of those features (MCP tool search among them).
  • Claude Code prepends an attribution block to the system prompt. Keep the system array in order; if the gateway must reshape it, set CLAUDE_CODE_ATTRIBUTION_HEADER=0 on the client instead of stripping the block.

Remember this

Forward Anthropic headers, body fields, cache markers, and SSE events untouched. Allowlists break on the next release.

The errors you will most likely hit

Most gateway problems show up in one of two places: at authentication, as 401 or an unexpected login screen, or on the first real request, as a 400 naming a field the upstream does not accept. The curl test from the connect section separates them. If curl works and Claude Code does not, the problem is in how Claude Code receives the configuration, or in fields that only real sessions send.

The WAF case is worth remembering because it is confusing. A short curl test passes, but real prompts contain XML-style tags and source code that match cross-site-scripting body rules, so a firewall in front of the gateway blocks them before the gateway logs anything.

Common gateway failures, from Anthropic's troubleshooting table
SymptomCauseFix
401 invalid tokenCredential in a header the gateway does not read, or revokedSwitch between ANTHROPIC_AUTH_TOKEN and ANTHROPIC_API_KEY; reissue the key
400 naming context_management or Extra inputs are not permittedUpstream rejects fields Claude Code sends to Anthropic-format endpointsForward both halves, or set CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1
403 HTML page, nothing in gateway logsA WAF in front of the gateway blocks the body as cross-site scriptingExempt /v1/messages from body inspection (AWS WAF: CrossSiteScripting_Body)
Stalls mid-responseGateway buffers the stream or drops ping eventsRelay SSE event by event, including pings
400 with the gateway's own context-limit wordingGateway enforces a smaller window; Claude Code does not recognise itRun /compact; set CLAUDE_CODE_AUTO_COMPACT_WINDOW to the gateway's limit
TLS errors while curl worksCorporate TLS inspection; Node does not trust the CASet NODE_EXTRA_CA_CERTS to the CA bundle
Login screen although curl worksNo credential Claude Code can read before first-run setupSet the credential in a shell export, ~/.claude/settings.json, or managed settings

Quick reference

  • Start claude --debug and read ~/.claude/debug/<session-id>.txt for the request that failed.
  • /status shows the active base URL and credential source; check it before changing gateway configuration.
  • Test every new Claude Code release against your gateway before it reaches the whole organisation.

Remember this

Use curl to tell gateway problems from client problems, and suspect a WAF when real sessions fail but curl works.

What still does not go through the gateway

A gateway carries model requests. It is not a full egress control for Claude Code:

  • Background traffic such as version checks, telemetry, and release notes goes to Anthropic and to services like GitHub, outside the gateway path. Since v2.1.246, Claude Code does not attach the gateway credential to that traffic. CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 turns most of it off, but it also disables auto-updates, so plan another update path.
  • The fast-mode availability check and the WebFetch domain safety check call api.anthropic.com directly. On a network that blocks it, /fast reports a connectivity error while inference keeps working. skipWebFetchPreflight: true turns the WebFetch check off.
  • Tools Claude runs are not model requests at all. A curl or npm install in the Bash tool uses the machine's normal network. Use the sandbox's network allowlist for that.

And the gateway only controls what reaches it. A developer who unsets the variables talks to Anthropic directly, unless managed settings pin allowedProviders and the network blocks other routes.

Quick reference

  • If egress must be gateway-only, combine allowedProviders: ["customEndpoint"], CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1, the sandbox network allowlist, and firewall rules.
  • Gateway credentials are long-lived secrets on laptops. Prefer an apiKeyHelper that fetches short-lived keys from your vault or SSO.
  • Slack and web cloud sessions run on Anthropic infrastructure and ignore gateway variables; disable them for users whose traffic must stay on the gateway.

Remember this

The gateway covers model calls. Background traffic, a few direct checks, and the commands Claude runs need their own controls.

Hands-on: route a session through a gateway

Use a gateway you control, or a local LiteLLM proxy pointed at your own API key.

1. Export ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN, run the curl test, and confirm a msg_ response. 2. Swap the token into ANTHROPIC_API_KEY instead and rerun curl with the Authorization header. Note the 401; this is the most common misconfiguration. 3. Start claude, run /status, and confirm the base URL and credential rows. 4. Ask Claude a question that reads a few files, then check the gateway logs for the x-claude-code-session-id header and the anthropic-beta values it received. 5. Move the two variables into ~/.claude/settings.json, open a new terminal without the exports, and confirm /status still shows the gateway.

Pass criterion: the curl test and a real session both succeed, you can find one session's requests in the gateway logs by session ID, and you can say which header your gateway reads the credential from.

Quick reference

  • If step 4 shows the gateway rewriting or dropping anthropic-beta, fix that before any wider rollout.
  • If the session stalls on long answers, check whether the gateway buffers streaming responses.
  • Write down the gateway and Claude Code versions you tested; retest when either changes.

Remember this

Prove the header mapping, the session ID in logs, and persistent config on one machine before rolling out.

Key takeaway

Running Claude Code through an LLM gateway takes two variables, ANTHROPIC_BASE_URL and a credential, but the credential variable decides the header (ANTHROPIC_AUTH_TOKEN for Authorization: Bearer, ANTHROPIC_API_KEY for x-api-key, apiKeyHelper for both). Roll it out with one key per developer, the base URL in managed settings, and allowedProviders if the gateway must be the only route.

On the gateway side, forward anthropic-beta, anthropic-version, body fields, cache_control, and SSE events unchanged, and forward error bodies as they are. Then remember the gateway's limits: background traffic, a few direct checks, and the commands Claude runs do not pass through it. For Anthropic's own gateway with SSO sign-in and per-group policy, see Claude Apps Gateway; for the sandbox that limits what commands can reach, see Claude Code Sandboxing and Isolation.

Practice (40 min): complete the five steps above, then write the managed settings file you would distribute, with the base URL, apiKeyHelper, and allowedProviders.

Share:

References

  1. Claude Code docs: Other LLM gateways — checked Oct 17, 2026
  2. Claude Code docs: Connect Claude Code to an LLM gateway — checked Oct 17, 2026
  3. Claude Code docs: Gateway compatibility guide — checked Oct 17, 2026
SH

Shoaib Hossain

Lead Author & Systems Architect

Software engineer and distributed systems architect specializing in backend scalability, cloud-native infrastructure, databases, and AI engineering workflows. Author and maintainer of Core Concept Learning.

Human-Engineered & Fact-CheckedOriginal Visual DiagramsEditorial Standards →Send Feedback

Related Articles

When a few engineers use Claude Code, each person's ~/.claude/settings.json is enough. When a company rolls it out to hu…

Read

Claude Code can run shell commands, edit files, and fetch URLs. Permission rules decide which of those actions run witho…

Read

Claude Code cloud sessions normally run on Anthropic-managed VMs. A self-hosted environment keeps the same developer exp…

Read

Keep learning

Follow a structured path or browse all courses to go deeper.