Claude Code
Route Claude Code through the Zuplo AI Gateway. The gateway authenticates, meters, and routes every session.
The gateway authenticates to Anthropic in one of two ways:
| Approach | The gateway sends Anthropic | Claude Code sends the gateway |
|---|---|---|
| Provider key | The Anthropic API key saved on your provider | Your personal API key, or an app's API key, as ANTHROPIC_AUTH_TOKEN |
| Claude subscription | Your claude.ai login, such as a Claude Max plan | An app's API key in a zp-gateway-api-key header, plus your login |
Prerequisites
Create an Anthropic provider in the AI Gateway, then get a gateway URL and key in one of two ways:
- Use your personal API key (recommended). Claude Code runs on your own machine, so call the project's User App. Open the My Keys tab of your AI Gateway project, copy the Gateway URL, and create a key under My API keys. Your requests count against your own budget.
- Use an app. For a shared or automated setup, and for the Claude subscription approach, create a pool and an app for Claude Code, then copy the app's API URL and API Key.
The rest of this guide calls these your gateway URL and gateway key.
Configure Claude Code
Replace the provider name
The examples assume your provider is named anthropic. Replace that prefix with
the name of your provider before copying anything. A provider named
my-anthropic routes my-anthropic/claude-sonnet-5; a Bedrock provider named
bedrock routes bedrock/anthropic.claude-sonnet-5. The model part must be an
ID that provider serves. Check your provider's page
in the Portal.
Claude Code reads ~/.claude/settings.json, or .claude/settings.json in a
project. Add the block for your approach, then restart Claude Code.
Rules
ANTHROPIC_BASE_URLis your gateway URL without/v1. Claude Code appends/v1/messages.- Set every
ANTHROPIC_*_MODELvariable. Claude Code's built-in model names have no prefix, and the variables map theopus,sonnet,haiku, andfablealiases to your provider's prefixed model IDs. - To select an exact model ID, such as
--model claude-fable-5-1, add amodelOverridesentry that maps it to the prefixed ID, as the examples do for Fable. Add one entry for each exact ID you use. - The Model Filtering policy on the User App or the app controls which models you can use.
Use a provider key
The gateway calls Anthropic with the key saved on your provider. Anthropic bills that key's account. Your Claude subscription is not used.
This example uses a personal API key and the User App's gateway URL. For an app, use the app's API key and API URL instead.
Code
ANTHROPIC_AUTH_TOKEN replaces your claude.ai login.
Add "CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY": "1" to env to add your
gateway's Claude models to the /model picker. See Claude Code's
gateway model discovery
docs for details.
Use your Claude subscription
This approach is shown with an app. On the User App, turning on passthrough would change authentication for everyone who uses it, so use an app for subscription logins.
Claude Code stays signed in to claude.ai. The gateway forwards that login to
Anthropic and reads the app's API key from a separate zp-gateway-api-key
header, so it still authenticates the app, runs its policies, and meters usage.
Model discovery (CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY) doesn't work with
a subscription login; list the models you need with the ANTHROPIC_*_MODEL
variables and Claude Code's
modelPicker
setting instead. Put modelPicker in ~/.claude/settings.json in your home
directory, not in a project's .claude/settings.json. Claude Code ignores it in
project settings.
Configure the API Key Authentication policy
On the pool's policy template, or on one app's Policies tab, edit API Key Authentication:
-
Turn on credentialPassthrough.
-
Set authHeader to
zp-gateway-api-key. -
Leave authScheme blank and click Use an empty value for authScheme. The field reports "Empty value set. The default (Bearer) is not applied."
-
Click Apply, then Save changes.
A blank authScheme field is not an empty value. It omits the option, the
Bearer default still applies, and every request fails with
401 Invalid Authorization Scheme.
In the JSON editor:
Code
Rules
- The provider still needs an API key to save. Passthrough requests never use it. Apps without passthrough and every Fallback Model target do. If nothing uses it, a placeholder value works.
- The Portal playground sends the app key as
Authorization: Bearer, so it can't call a passthrough app. Test from Claude Code. - Do not set
ANTHROPIC_AUTH_TOKENorANTHROPIC_API_KEY, in the settings file or in your shell. Either one replaces your login, and the gateway forwards it to Anthropic instead.
Configure Claude Code
Code
ANTHROPIC_CUSTOM_HEADERS adds the zp-gateway-api-key header. Claude Code
keeps sending its own Authorization header from your login. The gateway never
sends your app key to Anthropic.
Verify
Code
With the subscription approach, the first command reports a claude.ai login,
not an API key or auth token. With a personal key, the request appears in your
usage on the My Keys tab; with an app, it appears in the app's usage in the
Zuplo Portal.
Troubleshooting
| Error | Fix |
|---|---|
400 model must use "providerName/model" | The selected model has no provider prefix. Check ANTHROPIC_MODEL and the other ANTHROPIC_*_MODEL variables. If you select an exact model ID, add a modelOverrides entry for it. Restart after editing. |
403 This User App route requires a personal API key issued for this User App | With a personal key: the key is missing, wrong, from another project, or not sent as Authorization: Bearer. Create a key on My Keys and use the Gateway URL from the same project. |
401 Invalid Authorization Scheme | authScheme still has its Bearer default. Set an explicit empty value. |
401 Header configured by options.authHeader is missing | Claude Code didn't send zp-gateway-api-key. Check ANTHROPIC_CUSTOM_HEADERS. |
401 credentialPassthrough requires a non-empty Authorization header | Claude Code isn't signed in. Run claude and use /login. |
| An authentication error from Anthropic | Anthropic rejected the forwarded login. Sign in to Claude Code again. |