1> ## Documentation Index
2> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
3> Use this file to discover all available pages before exploring further.
4
5# Connect Claude Code to an LLM gateway
6
7> Point Claude Code at your organization's LLM gateway. Check whether your admin already configured it, or set the base URL and credential yourself for the CLI, VS Code, GitHub Actions, and the Agent SDK, then verify the connection and fix gateway errors.
8
9An [LLM gateway](/en/llm-gateway) is a proxy your organization runs between Claude Code and the model provider. When your organization uses one, Claude Code authenticates to the gateway with a credential your organization issues instead of your personal claude.ai login.
10
11This page is for developers running Claude Code through a gateway their organization operates. It covers two paths: [checking whether your administrator already configured it for you](#check-for-an-existing-configuration), and [configuring it yourself](#configure-claude-code-yourself) when they haven't.
12
13<Note>
14 * To deploy a gateway for your organization, see [Roll out an LLM gateway](/en/llm-gateway-rollout)
15 * For what Claude Code sends to a gateway, see the [gateway protocol reference](/en/llm-gateway-protocol)
16</Note>
17
18## Check for an existing configuration
19
20Administrators can distribute the gateway address and credential through [managed settings](/en/settings#settings-files), device management, or an [`apiKeyHelper`](#rotate-credentials-with-apikeyhelper), so Claude Code picks them up at startup with nothing for you to set. To check whether your organization already did this:
21
22<Steps>
23 <Step title="Start Claude Code">
24 Run `claude`. If it opens to the login screen instead of a session, no gateway credential was distributed; [configure it yourself](#configure-claude-code-yourself) below.
25 </Step>
26
27 <Step title="Check the Status tab">
28 If Claude Code started a session without showing the login screen, run `/status`, open the **Status** tab, and check two lines:
29
30 * `Anthropic base URL`: this line only appears when a gateway address is set. If it isn't there, Claude Code isn't pointed at the gateway; [configure it yourself](#configure-claude-code-yourself) below.
31 * `Auth token` or `API key`: a line naming `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_API_KEY`, or an `apiKeyHelper` confirms a gateway credential is active. A `Login method` line naming a claude.ai account instead means the credential wasn't distributed; [set it yourself](#set-the-credential-variable).
32 </Step>
33
34 <Step title="Send a test message">
35 Close the `/status` menu and send any prompt in Claude Code. A normal response from Claude, with no error, confirms the gateway connection works.
36 </Step>
37</Steps>
38
39If both lines in the `/status` menu look right but the message to Claude fails, see the [troubleshooting table](#troubleshoot-gateway-errors).
40
41## Configure Claude Code yourself
42
43To configure Claude Code for the gateway yourself, you need from your gateway team:
44
45* The gateway's base URL
46* A credential: a key or token string, or a command that fetches one
47 * If your gateway team didn't say which kind of credential it is, the [credential variable section](#set-the-credential-variable) below covers what to try
48
49The sections below cover the configuration in order:
50
51* [Set the credential variable](#set-the-credential-variable) and [set the base URL](#set-the-base-url-and-credential): the two variables every gateway connection needs
52* [Verify the connection](#verify-the-connection): confirm it works before persisting anything
53* [Configure each surface](#configure-each-surface): if you are using a surface besides the Claude Code CLI, such as VS Code, see how to configure it with your gateway credentials
54* [Additional configuration](#additional-configuration): variables some gateways need beyond the base URL and credential, such as a custom header, a credential helper, model discovery, or a provider-format base URL. Set these only if your administrator named them
55
56### Set the credential variable
57
58To authenticate Claude Code to the gateway, set your credential in an environment variable. Which variable depends on what your gateway team told you:
59
60| Set the credential in | Use when |
61| :------------------------------------------------------ | :-------------------------------------------------------------- |
62| `ANTHROPIC_AUTH_TOKEN` | Your gateway team said "bearer token" or "Authorization header" |
63| `ANTHROPIC_API_KEY` | Your gateway team said "API key" or "x-api-key" |
64| [`apiKeyHelper`](#rotate-credentials-with-apikeyhelper) | The credential rotates or comes from a vault |
65
66If you weren't told which kind, use `ANTHROPIC_AUTH_TOKEN`; the [verification request](#verify-the-connection) below shows how to tell if you need to switch.
67
68### Set the base URL and credential
69
70Set the gateway's base URL and the credential variable you picked above as environment variables. The examples use `ANTHROPIC_AUTH_TOKEN`; swap it for `ANTHROPIC_API_KEY` if that's [the variable you picked](#set-the-credential-variable). You can set them [in your shell](#set-as-shell-environment-variables), which lasts for one terminal session, or [in a Claude Code settings file](#set-in-a-settings-file), which persists everywhere Claude Code runs.
71
72For your first connection, start with shell exports and run the [verification request](#verify-the-connection) before moving the values to a settings file.
73
74#### Set as shell environment variables
75
76Replace the values with the ones your gateway team gave you:
77
78<Tabs>
79 <Tab title="Bash or Zsh">
80 ```bash theme={null}
81 export ANTHROPIC_BASE_URL=https://llm-gateway.example.com
82 export ANTHROPIC_AUTH_TOKEN=sk-gateway-key
83 ```
84 </Tab>
85
86 <Tab title="PowerShell">
87 ```powershell theme={null}
88 $env:ANTHROPIC_BASE_URL = "https://llm-gateway.example.com"
89 $env:ANTHROPIC_AUTH_TOKEN = "sk-gateway-key"
90 ```
91 </Tab>
92</Tabs>
93
94Shell exports apply only to that terminal session and programs started from it; an editor launched from the dock or Start menu won't see them. To make them persist across new terminals, add the same lines to your shell profile, such as `~/.zshrc`, `~/.bashrc`, or your PowerShell `$PROFILE`, or use a settings file instead.
95
96#### Set in a settings file
97
98To make the configuration apply everywhere Claude Code runs without depending on your shell, set the variables in the `env` block of a [settings file](/en/settings). Settings files have different scopes:
99
100* `~/.claude/settings.json` applies to all your projects. On Windows the path is `%USERPROFILE%\.claude\settings.json`
101* `.claude/settings.local.json` applies to one project. Claude Code adds it to your gitignore when it creates the file; if you create it yourself, add it to your gitignore manually first so you don't accidentally commit your credential
102
103<Warning>
104 Don't put the credential in a project's `.claude/settings.json`. That file is committed and shared with everyone who clones the repository.
105</Warning>
106
107The `env` block looks the same in either file:
108
109```json theme={null}
110{
111 "env": {
112 "ANTHROPIC_BASE_URL": "https://llm-gateway.example.com",
113 "ANTHROPIC_AUTH_TOKEN": "sk-gateway-key"
114 }
115}
116```
117
118When both a shell export and a settings-file `env` block set the same variable, the settings-file value applies. Run `/status` to see which base URL and credential source Claude Code is using.
119
120### Verify the connection
121
122With the variables exported in your shell, send a one-token request to the gateway directly. This confirms the URL and credential work before you open Claude Code, so a failure points at the gateway rather than your configuration. The commands below read the shell variables, so they need the [shell exports](#set-as-shell-environment-variables) even if you also put the values in a settings file.
123
124<Tabs>
125 <Tab title="Bash or Zsh">
126 ```bash theme={null}
127 curl -X POST "$ANTHROPIC_BASE_URL/v1/messages" \
128 -H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
129 -H "anthropic-version: 2023-06-01" \
130 -H "content-type: application/json" \
131 -d '{"model": "claude-sonnet-4-6", "max_tokens": 1, "messages": [{"role": "user", "content": "."}]}'
132 ```
133 </Tab>
134
135 <Tab title="PowerShell">
136 ```powershell theme={null}
137 Invoke-RestMethod -Method Post -Uri "$env:ANTHROPIC_BASE_URL/v1/messages" `
138 -Headers @{ "Authorization" = "Bearer $env:ANTHROPIC_AUTH_TOKEN"; "anthropic-version" = "2023-06-01" } `
139 -ContentType "application/json" `
140 -Body '{"model": "claude-sonnet-4-6", "max_tokens": 1, "messages": [{"role": "user", "content": "."}]}'
141 ```
142 </Tab>
143</Tabs>
144
145If your gateway expects keys in the `x-api-key` header, replace the `Authorization` header with `x-api-key: $ANTHROPIC_API_KEY` in the Bash command, or the `"Authorization"` hashtable entry with `"x-api-key" = "$env:ANTHROPIC_API_KEY"` in the PowerShell command.
146
147A JSON response that starts with `{"id":"msg_` and includes a `"content":[...]` field means the gateway is reachable and the credential works. An error naming an unknown model still proves the URL and credential work, since the gateway authenticated the request before rejecting the model name; you don't need to find a model your gateway serves for this test. A `401` means the credential was rejected: if you guessed the variable, switch to the other one and re-export.
148
149#### Confirm in Claude Code
150
151Start `claude` from the same shell so it inherits the exports, send a message, and run `/status`.
152
153On the **Status** tab, the `Anthropic base URL` line should show your gateway address, which confirms requests are routing there; if the line isn't there, the variable didn't reach the session. An `Auth token` or `API key` line naming the variable you set confirms the gateway credential is active rather than a saved claude.ai login.
154
155If the message fails, or `/status` doesn't show the gateway URL, see the [troubleshooting table](#troubleshoot-gateway-errors) below.
156
157### How the credential variable maps to a header
158
159Each variable sends the credential in a different HTTP header: `ANTHROPIC_AUTH_TOKEN` in `Authorization: Bearer`, `ANTHROPIC_API_KEY` in `x-api-key`, and `apiKeyHelper` in both. A credential in the wrong variable reaches the gateway in a header it doesn't read, and the request fails with `401`. If the verification request returned `401`, switch to the other variable and try again.
160
161### Conflicts with an existing login
162
163A gateway credential variable takes precedence over a saved claude.ai login or Console key. Your claude.ai login stays saved and unused while the variable is set; unset the variable and Claude Code goes back to it. With `ANTHROPIC_AUTH_TOKEN`, the variable takes precedence immediately. With `ANTHROPIC_API_KEY`, you are prompted once in interactive mode to approve the key before it takes over.
164
165Run `/status` to confirm which credential source is active. If startup shows an auth-conflict warning naming two sources, see the first row of the [troubleshooting table](#troubleshoot-gateway-errors) for which one to drop. To clear a saved login so only the gateway credential remains, run `/logout`.
166
167## Configure each surface
168
169The CLI reads the environment variables and settings files above. The other surfaces are the VS Code extension, the desktop app, GitHub Actions, the Agent SDK, and the cloud surfaces such as Slack and the web; the sections below cover whether those settings reach each one.
170
171### VS Code extension
172
173Set the gateway variables for the [VS Code extension](/en/vs-code) in `claudeCode.environmentVariables`, in VS Code's own user settings opened with the **Preferences: Open User Settings (JSON)** command. The extension checks credentials from this setting before launching, so it's the reliable place for the gateway credential; values in `~/.claude/settings.json` reach the spawned process but not the extension's own login check.
174
175```json theme={null}
176{
177 "claudeCode.environmentVariables": [
178 { "name": "ANTHROPIC_BASE_URL", "value": "https://llm-gateway.example.com" },
179 { "name": "ANTHROPIC_AUTH_TOKEN", "value": "sk-gateway-key" }
180 ]
181}
182```
183
184### Desktop app
185
186The desktop app reads gateway routing from an [administrator-distributed configuration](https://claude.com/docs/cowork/3p/gateway), not from `ANTHROPIC_BASE_URL` or `settings.json`. If your organization has distributed it, the desktop app routes through the gateway with no setup on your part; if not, use the terminal CLI or VS Code extension for gateway sessions. Administrators distribute the configuration as described in the [organization rollout](/en/llm-gateway-rollout#distribute-through-managed-settings).
187
188If the desktop app shows `Gateway was unreachable`, the app couldn't reach the configured base URL at startup; check the URL and network path with the [curl test above](#verify-the-connection).
189
190### GitHub Actions
191
192[Claude Code GitHub Actions](/en/github-actions) reads `ANTHROPIC_BASE_URL` and `ANTHROPIC_CUSTOM_HEADERS` from the workflow's `env` block. Pass the credential as the action's `anthropic_api_key` input; the action sets it as `ANTHROPIC_API_KEY`, so it reaches the gateway in the `x-api-key` header.
193
194For an `x-api-key` gateway, set the base URL in `env` and pass the gateway key as the input:
195
196```yaml theme={null}
197env:
198 ANTHROPIC_BASE_URL: https://llm-gateway.example.com
199
200steps:
201 - uses: anthropics/claude-code-action@v1
202 with:
203 anthropic_api_key: ${{ secrets.GATEWAY_API_KEY }}
204```
205
206For a bearer-token gateway, pass the same secret as both the `anthropic_api_key` input and `ANTHROPIC_AUTH_TOKEN` in the workflow `env` block. The action requires `anthropic_api_key`, `CLAUDE_CODE_OAUTH_TOKEN`, or workload identity federation before it launches Claude Code, and it doesn't read `ANTHROPIC_AUTH_TOKEN`, so the input satisfies that launch check while the env variable puts the key in the `Authorization` header the gateway reads. The copy in `x-api-key` is ignored:
207
208```yaml theme={null}
209env:
210 ANTHROPIC_BASE_URL: https://llm-gateway.example.com
211 ANTHROPIC_AUTH_TOKEN: ${{ secrets.GATEWAY_API_KEY }}
212
213steps:
214 - uses: anthropics/claude-code-action@v1
215 with:
216 anthropic_api_key: ${{ secrets.GATEWAY_API_KEY }}
217```
218
219For the action's other authentication options, including `CLAUDE_CODE_OAUTH_TOKEN` and workload identity federation, see [Claude Code GitHub Actions](/en/github-actions) and the action's [README](https://github.com/anthropics/claude-code-action#readme).
220
221### Agent SDK
222
223The [Agent SDK](/en/agent-sdk/overview) has no gateway-specific options; it passes environment variables to the Claude Code process it spawns. Each SDK accepts an `env` option that sets the spawned process's environment, and the TypeScript and Python SDKs treat it differently:
224
225* TypeScript: the spawned process inherits the parent environment by default, but setting `options.env` replaces the environment entirely. Spread `process.env` into it to keep your gateway variables.
226* Python: `ClaudeAgentOptions(env=...)` merges on top of the inherited environment, so gateway variables set in the parent process carry through without spreading.
227
228<CodeGroup>
229 ```ts TypeScript theme={null}
230 const result = query({
231 prompt: "...",
232 options: {
233 env: {
234 ...process.env,
235 ANTHROPIC_BASE_URL: "https://llm-gateway.example.com",
236 ANTHROPIC_AUTH_TOKEN: process.env.GATEWAY_KEY,
237 },
238 },
239 })
240 ```
241
242 ```python Python theme={null}
243 options = ClaudeAgentOptions(
244 env={
245 "ANTHROPIC_BASE_URL": "https://llm-gateway.example.com",
246 "ANTHROPIC_AUTH_TOKEN": os.environ["GATEWAY_KEY"],
247 }
248 )
249 ```
250</CodeGroup>
251
252### Slack, web, and Remote Control
253
254[Claude Code in Slack](/en/slack) and [Claude Code on the web](/en/claude-code-on-the-web) are Anthropic-hosted products that always use Anthropic's API; they aren't part of a gateway deployment. Gateway variables set in a cloud session's environment configuration are not applied. If your traffic must stay on the gateway, don't enable these surfaces for those users.
255
256[Remote Control](/en/remote-control) and [voice dictation](/en/voice-dictation) both rely on a claude.ai identity: Remote Control to pair a live session with your account, and voice dictation to reach the claude.ai transcription endpoint. They are unavailable while `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or an `apiKeyHelper` is active. To use either, unset the gateway credential and log in with claude.ai instead; `/doctor` names the variable to unset.
257
258## Additional configuration
259
260These settings cover cases beyond the base URL and credential. Set them only if your administrator's instructions or the [troubleshooting table](#troubleshoot-gateway-errors) call for one.
261
262### Send additional headers
263
264Some gateways route or tag requests using a custom header in addition to the credential, for example a tenant identifier or a routing key. To send one, set [`ANTHROPIC_CUSTOM_HEADERS`](/en/env-vars) with one `Name: Value` pair per line. The example below adds a routing header named `X-Org-Route`:
265
266<Tabs>
267 <Tab title="Bash or Zsh">
268 ```bash theme={null}
269 export ANTHROPIC_CUSTOM_HEADERS="X-Org-Route: prod"
270 ```
271 </Tab>
272
273 <Tab title="PowerShell">
274 ```powershell theme={null}
275 $env:ANTHROPIC_CUSTOM_HEADERS = "X-Org-Route: prod"
276 ```
277 </Tab>
278</Tabs>
279
280You can also set `ANTHROPIC_CUSTOM_HEADERS` in the `env` block of a settings file. Use `\n` between pairs there, since JSON strings can't span multiple lines:
281
282```json theme={null}
283{
284 "env": {
285 "ANTHROPIC_CUSTOM_HEADERS": "X-Org-Route: prod\nX-Tenant: acme"
286 }
287}
288```
289
290### Add gateway models to the model picker
291
292Model discovery queries the gateway for its model list at startup and adds those names to the `/model` picker alongside the built-in entries.
293
294Enable it if your gateway serves model names that aren't in Claude Code's built-in list and you want to select them from the picker. If the built-in models are what you use, you don't need discovery; your administrator may also have already enabled it through managed settings.
295
296To enable it, set `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1` in your shell or in the `env` block of `~/.claude/settings.json`. Discovery requires Claude Code v2.1.129 or later. {/* min-version: 2.1.129 */}
297
298Discovered models appear as additional `/model` entries labeled `From gateway`. To confirm discovery ran, start `claude --debug` and look for the `[gatewayDiscovery]` lines: a success logs how many models were cached, and a `404`, timeout, or redirect is recorded there too. For when discovery runs, what it filters, and the response format gateways serve, see the [model discovery reference](/en/llm-gateway-protocol#model-discovery).
299
300### Rotate credentials with apiKeyHelper
301
302An `apiKeyHelper` is a command Claude Code runs to fetch your gateway credential, instead of reading it from a static environment variable.
303
304Use a helper when the credential expires on a schedule, comes from a vault or SSO command, or your administrator told you to configure one. If your credential is a fixed string you set once, the [credential variable](#set-the-credential-variable) is all you need and you can skip this section.
305
306The helper is any shell command that prints the current credential to stdout. Claude Code runs it through your system shell, so on Windows it can be an executable or a PowerShell invocation. Write the script, make it executable, and reference it from `apiKeyHelper` in your [settings file](/en/settings):
307
308<Tabs>
309 <Tab title="Bash or Zsh">
310 For example, a script that reads from a vault:
311
312 ```bash theme={null}
313 #!/bin/bash
314 vault kv get -field=api_key secret/llm-gateway/claude-code
315 ```
316
317 Reference its path in `~/.claude/settings.json`:
318
319 ```json theme={null}
320 {
321 "apiKeyHelper": "~/bin/get-gateway-key.sh"
322 }
323 ```
324 </Tab>
325
326 <Tab title="PowerShell">
327 For example, a script that reads from a vault:
328
329 ```powershell theme={null}
330 vault kv get -field=api_key secret/llm-gateway/claude-code
331 ```
332
333 Reference the PowerShell invocation in `%USERPROFILE%\.claude\settings.json`, escaping the backslashes in the JSON string:
334
335 ```json theme={null}
336 {
337 "apiKeyHelper": "powershell -NoProfile -File C:\\scripts\\get-gateway-key.ps1"
338 }
339 ```
340 </Tab>
341</Tabs>
342
343Claude Code caches the helper's output for five minutes by default and re-runs it when a request returns HTTP 401. To change the cache lifetime, set `CLAUDE_CODE_API_KEY_HELPER_TTL_MS` in milliseconds, for example `CLAUDE_CODE_API_KEY_HELPER_TTL_MS=900000` for 15 minutes.
344
345The helper's value is sent in both the `Authorization` and `x-api-key` headers, so it works whichever header your gateway reads.
346
347### Route to a cloud provider through a gateway
348
349These configurations point Claude Code at a gateway through a provider-specific base URL variable in place of `ANTHROPIC_BASE_URL`. Bedrock and Vertex gateways accept those providers' native request formats; Foundry and Claude Platform on AWS gateways accept the Anthropic Messages format and differ only in which base URL variable reaches them.
350
351Use one only if your gateway team specifically named Bedrock, Vertex, Foundry, or the Claude Platform on AWS. If the [verification request](#verify-the-connection) above returned JSON, you can skip this section.
352
353Set the block for the provider your gateway team named. The skip-auth variables tell Claude Code not to sign requests with provider credentials, since the gateway holds those. If the gateway needs its own token, add `ANTHROPIC_AUTH_TOKEN` after the block, except for Foundry, which uses `ANTHROPIC_FOUNDRY_API_KEY` as shown.
354
355#### Amazon Bedrock
356
357<Tabs>
358 <Tab title="Bash or Zsh">
359 ```bash theme={null}
360 export ANTHROPIC_BEDROCK_BASE_URL=https://llm-gateway.example.com/bedrock
361 export CLAUDE_CODE_SKIP_BEDROCK_AUTH=1
362 export CLAUDE_CODE_USE_BEDROCK=1
363 ```
364 </Tab>
365
366 <Tab title="PowerShell">
367 ```powershell theme={null}
368 $env:ANTHROPIC_BEDROCK_BASE_URL = "https://llm-gateway.example.com/bedrock"
369 $env:CLAUDE_CODE_SKIP_BEDROCK_AUTH = "1"
370 $env:CLAUDE_CODE_USE_BEDROCK = "1"
371 ```
372 </Tab>
373</Tabs>
374
375#### Google Vertex AI
376
377<Tabs>
378 <Tab title="Bash or Zsh">
379 ```bash theme={null}
380 export ANTHROPIC_VERTEX_BASE_URL=https://llm-gateway.example.com/vertex
381 export ANTHROPIC_VERTEX_PROJECT_ID=your-gcp-project-id
382 export CLAUDE_CODE_SKIP_VERTEX_AUTH=1
383 export CLAUDE_CODE_USE_VERTEX=1
384 export CLOUD_ML_REGION=us-east5
385 ```
386 </Tab>
387
388 <Tab title="PowerShell">
389 ```powershell theme={null}
390 $env:ANTHROPIC_VERTEX_BASE_URL = "https://llm-gateway.example.com/vertex"
391 $env:ANTHROPIC_VERTEX_PROJECT_ID = "your-gcp-project-id"
392 $env:CLAUDE_CODE_SKIP_VERTEX_AUTH = "1"
393 $env:CLAUDE_CODE_USE_VERTEX = "1"
394 $env:CLOUD_ML_REGION = "us-east5"
395 ```
396 </Tab>
397</Tabs>
398
399#### Microsoft Foundry
400
401Put the gateway's credential in `ANTHROPIC_FOUNDRY_API_KEY`; it is sent to the gateway as the `x-api-key` header. `CLAUDE_CODE_SKIP_FOUNDRY_AUTH` doesn't apply here: without an API key, the Foundry client fails every request before it leaves the machine.
402
403<Tabs>
404 <Tab title="Bash or Zsh">
405 ```bash theme={null}
406 export ANTHROPIC_FOUNDRY_BASE_URL=https://llm-gateway.example.com/foundry
407 export ANTHROPIC_FOUNDRY_API_KEY=sk-gateway-key
408 export CLAUDE_CODE_USE_FOUNDRY=1
409 ```
410 </Tab>
411
412 <Tab title="PowerShell">
413 ```powershell theme={null}
414 $env:ANTHROPIC_FOUNDRY_BASE_URL = "https://llm-gateway.example.com/foundry"
415 $env:ANTHROPIC_FOUNDRY_API_KEY = "sk-gateway-key"
416 $env:CLAUDE_CODE_USE_FOUNDRY = "1"
417 ```
418 </Tab>
419</Tabs>
420
421#### Claude Platform on AWS
422
423See [Claude Platform on AWS](/en/claude-platform-on-aws) for the workspace ID.
424
425<Tabs>
426 <Tab title="Bash or Zsh">
427 ```bash theme={null}
428 export ANTHROPIC_AWS_BASE_URL=https://llm-gateway.example.com/anthropic-aws
429 export ANTHROPIC_AWS_WORKSPACE_ID=wrkspc_01ABCDEFGHIJKLMN
430 export CLAUDE_CODE_SKIP_ANTHROPIC_AWS_AUTH=1
431 export CLAUDE_CODE_USE_ANTHROPIC_AWS=1
432 ```
433 </Tab>
434
435 <Tab title="PowerShell">
436 ```powershell theme={null}
437 $env:ANTHROPIC_AWS_BASE_URL = "https://llm-gateway.example.com/anthropic-aws"
438 $env:ANTHROPIC_AWS_WORKSPACE_ID = "wrkspc_01ABCDEFGHIJKLMN"
439 $env:CLAUDE_CODE_SKIP_ANTHROPIC_AWS_AUTH = "1"
440 $env:CLAUDE_CODE_USE_ANTHROPIC_AWS = "1"
441 ```
442 </Tab>
443</Tabs>
444
445## Troubleshoot gateway errors
446
447These are the most common errors when running Claude Code through a gateway, with the gateway-side cause and the fix:
448
449| Error | Cause | Fix |
450| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
451| A startup warning naming two credential sources and ending in `auth may not work as expected`. Older versions show `Auth conflict: Both a token (SOURCE) and an API key (SOURCE) are set` instead. | A gateway credential and a saved login are both active; the variable is used for requests, but the stale login can cause unexpected auth behavior | Unset the variable to use the saved login, or run `/logout` to use the gateway credential |
452| `401` errors naming an invalid or unrecognized token | The credential isn't one the gateway issued, or it's in a header the gateway doesn't read | Confirm the variable matches your credential kind in the [credential table](#set-the-credential-variable), and regenerate the key at the gateway if it was revoked |
453| `Unable to connect to API (ConnectionRefused)`, or `(ECONNREFUSED)` from npm installs, often after a silent pause while Claude Code [retries with backoff](/en/errors#automatic-retries) | Nothing answered at the base URL: the address is wrong, or a VPN or firewall blocks the path to the gateway | Run the [curl test above](#verify-the-connection), which fails immediately with the same cause, and confirm the URL and network path with your gateway team |
454| `API returned an empty or malformed response (HTTP 200)` | The gateway or an intermediate proxy returned a non-API response, often an HTML error or login page | Test with the [curl request above](#verify-the-connection); fix the gateway route that returns non-JSON |
455| `400` errors naming `context_management`, `Extra inputs are not permitted`, or other unrecognized fields | The gateway forwards requests to an upstream that rejects fields Claude Code sends to Anthropic-format endpoints | Set `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1`, which suppresses most pre-release fields; see [feature pass-through](/en/llm-gateway-protocol#feature-pass-through). Some betas aren't gated by this flag; for those, set the matching `CLAUDE_CODE_USE_*` provider variable so Claude Code sends only what that provider accepts |
456| `400` errors naming `thinking` or `adaptive`, such as `Input tag 'adaptive' found` | The upstream model build doesn't accept adaptive reasoning, which Claude Code requests for Claude 4.6 and later models | Upgrade the gateway's upstream. On Opus 4.6 and Sonnet 4.6, `CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1` works instead. The [model configuration](/en/model-config) capability variables apply only to the provider configurations, such as `CLAUDE_CODE_USE_BEDROCK` and `CLAUDE_CODE_USE_VERTEX`, not behind an `ANTHROPIC_BASE_URL` gateway |
457| `400` errors stating a context or token limit in the gateway's own words, such as `ContextWindowExceededError` or `prompt token count of N exceeds the limit of M` | The gateway enforces a smaller context than the model's native window and rewrites the upstream error, so the automatic compact-and-retry, which matches Anthropic's `prompt is too long` wording, doesn't fire | Run `/compact` to recover the session. To prevent it, set `CLAUDE_CODE_AUTO_COMPACT_WINDOW` to the gateway's limit; the value is clamped to at least 100,000 tokens and at most the model's context window, so a gateway limit below 100,000 can't be matched and `/compact` remains the recovery there. Also set `CLAUDE_CODE_MAX_OUTPUT_TOKENS` below the gateway model's output limit |
458| Models missing from the `/model` picker | Gateway model names aren't in Claude Code's built-in list | Enable [gateway model discovery](#add-gateway-models-to-the-model-picker) or add names with the [model configuration](/en/model-config) variables |
459| Claude Code asks you to log in even though the [curl test](#verify-the-connection) succeeds | The CLI has no credential of its own: a reachable base URL isn't one, and an `env` block in a project's `.claude/settings.json` or `.claude/settings.local.json` applies only after the first-run wizard and trust prompt | Set `ANTHROPIC_AUTH_TOKEN` somewhere Claude Code reads before first-run setup: a shell export, the `env` block in `~/.claude/settings.json`, or managed settings |
460| `ANTHROPIC_API_KEY` is set but ignored, with no prompt | The key needs a one-time approval in interactive sessions, and a previously declined key is ignored without asking again | Enable it under `/config` with the `Use custom API key` option |
461| `This machine's managed settings require a first-party login` | Managed settings include `forceLoginMethod` or `forceLoginOrgUUID`, which on Claude Code v2.1.146 and later cannot coexist with `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `apiKeyHelper` | Your administrator must remove `forceLoginMethod` and `forceLoginOrgUUID` from managed settings to use gateway credentials, or remove the gateway credential to use first-party login. The two cannot be combined |
462| `403` with an HTML body such as `403 Forbidden`, when the gateway's own logs show no request received | A web application firewall or reverse proxy in front of the gateway blocked the request body before it reached the gateway. Claude Code prompts include XML-style tags and source code that match cross-site-scripting body rules, so a short curl test passes while a real session doesn't | Exempt the gateway's `/v1/messages` path from request-body inspection. On AWS WAF this is the `CrossSiteScripting_Body` managed rule; on nginx with ModSecurity it is the equivalent OWASP CRS body rules |
463| Certificate or TLS errors such as `SSL certificate verification failed` or `Self-signed certificate detected`, when the [curl test](#verify-the-connection) succeeds | Claude Code's runtime isn't trusting the same certificate authority that `curl` uses. Common behind corporate TLS-inspection proxies | Set `NODE_EXTRA_CA_CERTS` to the CA bundle path; see [CA certificate store](/en/network-config#ca-certificate-store) |
464
465If Claude Code prompts you to log in repeatedly after removing gateway configuration, the cause is usually credential storage rather than the gateway; see [authentication errors](/en/errors#authentication-errors).
466
467## Related resources
468
469* [LLM gateways overview](/en/llm-gateway): what a gateway is and how it interacts with claude.ai subscriptions
470* [Roll out an LLM gateway for your organization](/en/llm-gateway-rollout): the admin-facing checklist for deploying and distributing gateway configuration
471* [Gateway protocol reference](/en/llm-gateway-protocol): what Claude Code sends to a gateway, including the headers and fields the gateway must forward
472* [Settings](/en/settings): where settings files live and how the `env` block is read
473* [Authentication](/en/authentication): how credential variables, `apiKeyHelper`, and OAuth login interact