Skip to content
This page is a translation of the authoritative Chinese source and may lag behind.View the original

Claude Code via the gateway

Claude Code is Anthropic's official command-line AI coding assistant. By default it calls https://api.anthropic.com, but by pointing its base URL at the gateway via the ANTHROPIC_BASE_URL environment variable, you can route all requests through the gateway — either to an Anthropic upstream (same protocol, sent directly) or cross-protocol to OpenAI / Gemini / Bedrock and other upstreams (translated by the gateway).

What you'll build

  • An anthropic upstream + a model aligned with Claude Code's default model ID (this tutorial uses claude-sonnet-4-5; cross-protocol uses gpt-4o etc.)
  • A gateway access key
  • Claude Code calling successfully through the gateway and seeing a reply

Prerequisites

  • The gateway is running (http://localhost:7890) and you can log in to the Console
  • ENCRYPTION_KEY is set — the upstream API key and access key saved below are encrypted before being stored; if it's not set, saving reports encryption_key not set in config. See Docker single node → Prerequisites
  • An Anthropic API key (or, if the upstream is OpenAI / Gemini / Bedrock etc., the corresponding credentials)
  • Claude Code installed (npm install -g @anthropic-ai/claude-code or similar)

1. Create an anthropic upstream

Console → UpstreamsNew:

FieldValueDescription
NameanthropicUnique upstream identifier
ProtocolanthropicDetermines the executor and request schema
Base URLhttps://api.anthropic.comThe real upstream address, no trailing /
API KeyAnthropic keyClick "Add" to add multiple keys, distributed by weight
Enabled

Save.

2. Create a claude model

On the anthropic upstream row, click Expand → model sub-table → New model:

FieldValueDescription
Nameclaude-sonnet-4-5The model name exposed to clients
UpstreamanthropicSelect the upstream you just created
Upstream model IDclaude-sonnet-4-5The real Anthropic model name
Enabled

Save.

Why name the model directly claude-sonnet-4-5? Claude Code sends requests with its own configured default model ID (e.g. claude-sonnet-4-5), not an arbitrary gateway name you made up. If the gateway model has a different name (e.g. claude-sonnet), Claude Code's first message will 404 model_not_found. Naming the gateway model the model ID Claude Code will actually request is the easiest way to align — you can also skip this and use ANTHROPIC_MODEL to align, see Step 5. The "upstream model ID" must be a model name that actually exists on Anthropic; see the Anthropic official model list for the available list.

3. Configure a key group to allow access

Console → Access KeysKey Groups tab → New:

FieldValueDescription
NamedefaultGroup name
ModelsSelect claude-sonnet-4-5, or * (all)Determines which models this group's keys can call
Enabled

4. Issue an access key

Console → Access KeysNew:

FieldValueDescription
Nameclaude-code-keyThe key's identifier, used for management and audit
API keyClick "Generate"Auto-generates a string; the credential clients send when calling
GroupdefaultDetermines which models this key can access
Enabled

5. Configure Claude Code

Claude Code reads the following environment variables:

bash
export ANTHROPIC_BASE_URL=http://localhost:7890
export ANTHROPIC_API_KEY=<your access key>

# Note: fill base_url to the root (without /v1), because Claude Code appends /v1/messages itself

Or write it into your shell config (~/.zshrc / ~/.bashrc) to persist.

Align the model name (key step): Claude Code sends requests with its own configured default model ID, not an arbitrary gateway model name. The two must match, otherwise the first message 404s model_not_found. Choose one of two ways to align:

  • Method A (recommended, zero extra config): name the gateway model directly as the model ID Claude Code will request. Step 2 of this tutorial does exactly this (claude-sonnet-4-5), no further variables needed.

  • Method B: if the gateway model uses a custom name (e.g. claude-sonnet), set ANTHROPIC_MODEL to point to that gateway name:

    bash
    export ANTHROPIC_MODEL=claude-sonnet  # your custom model name on the gateway

    (You can also switch with the /model command inside Claude Code, but the environment variable is less hassle.)

Start Claude Code:

bash
claude

Send a message and see the model reply, and it's working. All of Claude Code's requests go through the gateway.

Cross-protocol upstream

If the upstream is OpenAI / Gemini / Bedrock, protocol translation is needed — Claude Code speaks the Anthropic protocol (/v1/messages), the gateway translates to the upstream protocol and sends it upstream, then translates the response back into Anthropic format.

For example, using an OpenAI upstream as the Claude Code backend:

  1. Create an upstream openai (protocol openai, URL https://api.openai.com/v1)
  2. Create a model claude-sonnet-4-5 (upstream openai, upstream model ID gpt-4o) — the client's Anthropic requests are automatically translated by the gateway into the OpenAI upstream protocol, with no model-level protocol override needed. Still recommend aligning the model name with Claude Code's default model ID (as in Step 2), otherwise align with ANTHROPIC_MODEL.

Combinations where the client and upstream protocols differ need to be a supported direction in the Protocol interop matrix. Anthropic → OpenAI via chat translation is supported.

When crossing protocols, note:

  • Tool calls: tool_call_id must keep its original value across the cross-protocol round trip
  • Streaming: the gateway translates the upstream SSE stream into an Anthropic SSE stream; when the upstream takes long to reason, it inserts :keep-alive comments
  • Stream errors: when the upstream stream breaks mid-way, it inserts a _gateway_warning extension field telling you the reason for the interruption

Inject a session cache key (optional)

Claude Code injects an x-claude-code-session-id header in the conversation. You can use a request_payload expression to inject that header value into the upstream's private cache-key field, so multiple requests of the same session hit the upstream cache:

json
[
  {
    "path": "prompt_cache_key",
    "mode": "overwrite",
    "value": "{{header:x-claude-code-session-id|system_prompt_hash}}"
  }
]

Degrades level by level: has a session header → use the header (same session, same key); no header but a system prompt exists → use the system hash; both empty → omit the write. See Template variable reference for the full variable list.

FAQ

Q: Claude Code reports connection refused? Check that ANTHROPIC_BASE_URL points to the correct gateway address and that the gateway is listening. For a Docker-deployed gateway, use http://host.docker.internal:7890 or the LAN IP.

Q: Claude Code reports 401?ANTHROPIC_API_KEY isn't set correctly. Check that it's the gateway access key (not Anthropic's sk-...).

Q: Claude Code reports 404 model_not_found? The model name isn't aligned. Claude Code sends its own default model ID (e.g. claude-sonnet-4-5), and the gateway must have a model with the same name. Two fixes: ① name the gateway model the model ID Claude Code will request; ② set ANTHROPIC_MODEL=<your gateway model name>. See Step 5.

Q: Claude Code reports 403 model_access_denied? The key group the key belongs to doesn't include claude-sonnet-4-5 in its "Models" list. Go back to the key group, add that model, or change it to *.

Q: Claude Code reports 400 unsupported_feature? The cross-protocol combination has no translator. Check the supported directions in the Protocol interop matrix.

Q: Tool calls get lost in cross-protocol calls?tool_call_id must keep its original value across the cross-protocol round trip — check that the tool_call_id returned in multi-turn tool conversations exactly matches what the gateway gave you.

Q: How do I configure model switching for plan mode? See Switch models by Claude Code plan mode with a script. Claude Code's plan mode injects Plan mode is active / Exited Plan Mode markers into the conversation, which a script can use to compare the last position and switch routing.

Next: Endpoints · auth · protocol interop for the full endpoint list; Client integration and gateway differences for SDK integration and gateway-specific behavior; Protocol interop matrix for all protocol-pair support.