zuplo 7.8.8 → 7.8.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/docs/ai-gateway/azure-ai.mdx +132 -0
  2. package/docs/ai-gateway/cookbooks/sdk-path-shim.mdx +457 -0
  3. package/docs/ai-gateway/integrations/ai-sdk.mdx +127 -1
  4. package/docs/ai-gateway/integrations/claude-code.mdx +82 -180
  5. package/docs/ai-gateway/integrations/claude-desktop.mdx +61 -99
  6. package/docs/ai-gateway/integrations/codex.mdx +63 -57
  7. package/docs/ai-gateway/vertex-ai.mdx +32 -0
  8. package/docs/articles/custom-domains.mdx +3 -2
  9. package/docs/articles/source-control.mdx +4 -3
  10. package/docs/articles/testing.mdx +5 -5
  11. package/docs/articles/upstream-iam-auth.mdx +2 -2
  12. package/docs/concepts/how-zuplo-works.mdx +2 -1
  13. package/docs/dev-portal/migration.mdx +2 -2
  14. package/docs/getting-started/dev-portal/index.mdx +2 -2
  15. package/docs/getting-started/gateway/add-api-key-auth/index.mdx +3 -0
  16. package/docs/getting-started/gateway/add-api-key-auth/local.mdx +3 -0
  17. package/docs/getting-started/gateway/add-rate-limiting/index.mdx +3 -0
  18. package/docs/getting-started/gateway/add-rate-limiting/local.mdx +3 -0
  19. package/docs/getting-started/gateway/agent.mdx +2 -1
  20. package/docs/getting-started/gateway/deploy-to-the-edge/index.mdx +3 -0
  21. package/docs/getting-started/gateway/deploy-to-the-edge/local.mdx +3 -0
  22. package/docs/getting-started/gateway/dynamic-rate-limiting/index.mdx +3 -0
  23. package/docs/getting-started/gateway/dynamic-rate-limiting/local.mdx +3 -0
  24. package/docs/getting-started/gateway/setup-a-basic-gateway/index.mdx +4 -1
  25. package/docs/getting-started/gateway/setup-a-basic-gateway/local.mdx +4 -1
  26. package/docs/getting-started/mcp-gateway/local.mdx +31 -9
  27. package/docs/getting-started/mcp-gateway/portal.mdx +8 -7
  28. package/docs/getting-started/mcp-server/local.mdx +2 -2
  29. package/docs/getting-started/migrate/index.mdx +2 -2
  30. package/docs/mcp-gateway/connect-clients/claude-desktop.mdx +21 -19
  31. package/docs/mcp-gateway/connect-clients/overview.mdx +2 -1
  32. package/docs/policies/ai-gateway-auth-v2-inbound/doc.md +10 -0
  33. package/package.json +5 -5
@@ -53,7 +53,8 @@ configure.
53
53
  Each provider package appends its own operation path to `baseURL`, so pick the
54
54
  model factory that targets an endpoint the gateway serves:
55
55
  `/v1/chat/completions` for OpenAI-compatible requests, `/v1/messages` for
56
- Anthropic, `/v1/embeddings`, and `/v1/responses` for OpenAI only. The examples
56
+ Anthropic, `/v1/embeddings` for every provider with embedding models, and
57
+ `/v1/responses` for OpenAI and Azure OpenAI-compatible deployments. The examples
57
58
  below use the right factory for each provider.
58
59
 
59
60
  ### OpenAI
@@ -161,6 +162,131 @@ const { text } = await generateText({
161
162
  });
162
163
  ```
163
164
 
165
+ ### Azure AI
166
+
167
+ Use `@ai-sdk/azure`. Set `baseURL` to your app's URL plus `/v1`, and pass the
168
+ app's API key through `tokenProvider`—not `apiKey`. The provider sends `apiKey`
169
+ as the `api-key` header, which the gateway doesn't read, so the request fails
170
+ with a `401`; `tokenProvider` puts the same key on `Authorization: Bearer`,
171
+ which the gateway does read. Leave `useDeploymentBasedUrls` off—it moves the
172
+ deployment into the path as `/deployments/{id}/chat/completions`, which isn't a
173
+ gateway endpoint and returns a `404`. To keep `useDeploymentBasedUrls: true`—or
174
+ to authenticate with `apiKey` rather than `tokenProvider`—install the
175
+ [SDK path shim](../cookbooks/sdk-path-shim.mdx), a custom policy that rewrites
176
+ the deployment path and maps the `api-key` header.
177
+
178
+ Reference models by deployment name, as `providerName/deploymentName`—see
179
+ [Azure serves deployments, not model names](../azure-ai.mdx#azure-serves-deployments-not-model-names).
180
+
181
+ ```typescript
182
+ import { createAzure } from "@ai-sdk/azure";
183
+ import { generateText } from "ai";
184
+
185
+ const appKey = process.env.ZUPLO_AI_GATEWAY_API_KEY;
186
+ if (!appKey) {
187
+ throw new Error("Set ZUPLO_AI_GATEWAY_API_KEY to the app's API key");
188
+ }
189
+
190
+ const azure = createAzure({
191
+ baseURL:
192
+ "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1",
193
+ tokenProvider: async () => appKey,
194
+ });
195
+
196
+ const { text } = await generateText({
197
+ model: azure.chat("azureai/my-gpt"),
198
+ prompt: "Write a one-sentence bedtime story about a unicorn.",
199
+ });
200
+ ```
201
+
202
+ Call `azure.chat(id)` for chat completions and `azure.textEmbeddingModel(id)`
203
+ for embeddings. The bare `azure(id)` callable targets the Responses API, which
204
+ Azure serves for its OpenAI-compatible deployments, so that form works too.
205
+
206
+ For a Claude deployment on a Foundry resource, either call
207
+ `azure.chat("azureai/my-claude")`—the gateway translates the chat completion to
208
+ the Messages API—or use `@ai-sdk/anthropic` with `authToken` for the native
209
+ Messages API:
210
+
211
+ ```typescript
212
+ import { createAnthropic } from "@ai-sdk/anthropic";
213
+ import { generateText } from "ai";
214
+
215
+ const anthropic = createAnthropic({
216
+ authToken: process.env.ZUPLO_AI_GATEWAY_API_KEY,
217
+ baseURL:
218
+ "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1",
219
+ });
220
+
221
+ const { text } = await generateText({
222
+ model: anthropic("azureai/my-claude"),
223
+ prompt: "Write a one-sentence bedtime story about a unicorn.",
224
+ });
225
+ ```
226
+
227
+ ### Vertex AI
228
+
229
+ The `@ai-sdk/google-vertex` provider posts to Vertex's own publisher paths—
230
+ `{model}:generateContent` for Gemini, and `{model}:rawPredict` for Claude on its
231
+ `/anthropic` entry—neither of which the AI Gateway serves, so both return a
232
+ `404`. Use the
233
+ [OpenAI-compatible provider](https://ai-sdk.dev/providers/openai-compatible-providers)
234
+ for Gemini and Model Garden models, and `@ai-sdk/anthropic` for Claude. For
235
+ Claude, the [SDK path shim](../cookbooks/sdk-path-shim.mdx) can instead repoint
236
+ `@ai-sdk/google-vertex/anthropic` onto `/v1/messages`; the Gemini entry can't be
237
+ repointed.
238
+
239
+ Every Vertex model reference has two slashes, `providerName/publisher/model`—see
240
+ [Model references include the publisher prefix](../vertex-ai.mdx#model-references-include-the-publisher-prefix).
241
+
242
+ ```typescript
243
+ import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
244
+ import { generateText } from "ai";
245
+
246
+ const gateway = createOpenAICompatible({
247
+ name: "zuplo-ai-gateway",
248
+ apiKey: process.env.ZUPLO_AI_GATEWAY_API_KEY,
249
+ baseURL:
250
+ "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1",
251
+ });
252
+
253
+ const { text } = await generateText({
254
+ model: gateway("vertexai/google/gemini-3.7-flash"),
255
+ prompt: "Write a one-sentence bedtime story about a unicorn.",
256
+ });
257
+ ```
258
+
259
+ The same provider embeds through `textEmbeddingModel`, which the gateway
260
+ translates onto Vertex's embedding API:
261
+
262
+ ```typescript
263
+ import { embedMany } from "ai";
264
+
265
+ const { embeddings } = await embedMany({
266
+ model: gateway.textEmbeddingModel("vertexai/google/gemini-embedding-2"),
267
+ values: ["first document", "second document"],
268
+ });
269
+ ```
270
+
271
+ Claude models serve the native Messages API on Vertex, so use
272
+ `@ai-sdk/anthropic` with `authToken`:
273
+
274
+ ```typescript
275
+ import { createAnthropic } from "@ai-sdk/anthropic";
276
+ import { generateText } from "ai";
277
+
278
+ const anthropic = createAnthropic({
279
+ authToken: process.env.ZUPLO_AI_GATEWAY_API_KEY,
280
+ baseURL:
281
+ "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1",
282
+ });
283
+
284
+ const { text } = await generateText({
285
+ model: anthropic("vertexai/anthropic/claude-haiku-4-5@20251001"),
286
+ prompt: "Write a one-sentence bedtime story about a unicorn.",
287
+ });
288
+ ```
289
+
164
290
  ## Provider options the gateway doesn't forward
165
291
 
166
292
  On the OpenAI-shaped endpoints (`/v1/chat/completions`, `/v1/embeddings`, and
@@ -2,92 +2,70 @@
2
2
  title: Claude Code
3
3
  sidebar_label: Claude Code
4
4
  description:
5
- Point Claude Code at an AI Gateway app so every Claude Code request is
6
- authenticated, metered, and routed by the gateway.
5
+ Route Claude Code requests through a Zuplo AI Gateway app, with a provider key
6
+ or your Claude subscription.
7
7
  ---
8
8
 
9
- You can configure [Claude Code](https://www.claude.com/product/claude-code) to
10
- send its model requests through the Zuplo AI Gateway, so the gateway
11
- authenticates, meters, and routes every Claude Code session.
9
+ Route [Claude Code](https://www.claude.com/product/claude-code) through the
10
+ Zuplo AI Gateway. The gateway authenticates, meters, and routes every session.
12
11
 
13
- The gateway can authenticate to Anthropic in two ways. Pick one before you
14
- configure Claude Code:
12
+ The gateway authenticates to Anthropic in one of two ways:
15
13
 
16
- | Approach | The gateway sends Anthropic | Claude Code sends the gateway |
17
- | --------------------------------------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------- |
18
- | [Configured provider key](#use-a-configured-provider-key) | The Anthropic API key saved on your provider | The app's API key as `ANTHROPIC_AUTH_TOKEN` |
19
- | [Your Claude subscription](#use-your-claude-subscription) | The credential from your `claude.ai` login, such as a Claude Max plan | The app's API key in a `zp-gateway-api-key` header, plus your login as-is |
14
+ | Approach | The gateway sends Anthropic | Claude Code sends the gateway |
15
+ | ---------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------------- |
16
+ | [Provider key](#use-a-provider-key) | The Anthropic API key saved on your provider | The app's API key as `ANTHROPIC_AUTH_TOKEN` |
17
+ | [Claude subscription](#use-your-claude-subscription) | Your `claude.ai` login, such as a Claude Max plan | The app's API key in a `zp-gateway-api-key` header, plus your login |
20
18
 
21
- Both approaches share the same provider, team, and app setup, and the same model
22
- configuration.
23
-
24
- ## Claude Code Setup
19
+ ## Prerequisites
25
20
 
26
21
  <Stepper>
27
22
 
28
- 1. Create a [new provider](../managing-providers.mdx) in the AI Gateway for
29
- Anthropic
30
-
31
- 2. [Set up a new team](../managing-teams.mdx)
32
-
33
- 3. If you plan to use your Claude subscription, configure the team's
34
- [API Key Authentication policy](#configure-the-api-key-authentication-policy)
35
- for passthrough before you create the app
23
+ 1. Create an Anthropic [provider](../managing-providers.mdx) in the AI Gateway.
36
24
 
37
- 4. Create a [new app](../managing-apps.mdx) to use with Claude Code and assign
38
- it to the team you created
25
+ 2. [Create a team](../managing-teams.mdx). For the subscription approach,
26
+ [configure its API Key Authentication policy](#configure-the-api-key-authentication-policy)
27
+ now.
39
28
 
40
- 5. Copy the **API URL** and **API Key** shown at the top of the app page
29
+ 3. [Create an app](../managing-apps.mdx) for Claude Code and assign it to the
30
+ team.
41
31
 
42
- 6. Add the gateway URL, the app's API key, and model mappings to
43
- `.claude/settings.json`, following the section below for the approach you
44
- chose
32
+ 4. Copy the **API URL** and **API Key** from the app page.
45
33
 
46
34
  </Stepper>
47
35
 
48
- ### Before copying: replace the provider name
36
+ ## Configure Claude Code
49
37
 
50
- :::warning
38
+ :::warning{title="Replace the provider name"}
51
39
 
52
- The examples below assume your provider is named `anthropic`. Replace that
53
- prefix with the name of **your** provider before copying the configuration. For
54
- example, a provider named `my-anthropic` routes `my-anthropic/claude-sonnet-5`,
55
- while a Bedrock provider named `bedrock` routes
56
- `bedrock/anthropic.claude-sonnet-5`. The model part must be an id that provider
57
- understands.
40
+ The examples assume your provider is named `anthropic`. Replace that prefix with
41
+ the name of **your** provider before copying anything. A provider named
42
+ `my-anthropic` routes `my-anthropic/claude-sonnet-5`; a Bedrock provider named
43
+ `bedrock` routes `bedrock/anthropic.claude-sonnet-5`. The model part must be an
44
+ ID that provider serves. Check [your provider's page](../managing-providers.mdx)
45
+ in the Portal.
58
46
 
59
47
  :::
60
48
 
61
- The gateway routes every request using `providerName/model`. The provider prefix
62
- picks which of your providers handles the request — a gateway can contain
63
- several providers that serve Anthropic models.
64
-
65
- ### Where Claude Code reads its settings
66
-
67
- You can configure Claude Code either globally or per project by editing the
68
- settings file:
49
+ Claude Code reads `~/.claude/settings.json`, or `.claude/settings.json` in a
50
+ project. Add the block for your approach, then restart Claude Code.
69
51
 
70
- - **Global:** `~/.claude/settings.json`
71
- - **Project-specific:** `.claude/settings.json` in your project directory
72
-
73
- Each approach below shows the `env` and `modelOverrides` blocks to add to that
74
- file. Restart Claude Code after saving it, and all your Claude Code LLM requests
75
- route through the AI Gateway.
76
-
77
- :::note
78
-
79
- Claude Code appends `/v1/messages` to the base URL itself, so
80
- `ANTHROPIC_BASE_URL` is the app's URL _without_ the `/v1` suffix.
81
-
82
- :::
52
+ ### Rules
83
53
 
84
- ## Use a configured provider key
54
+ - `ANTHROPIC_BASE_URL` is the app's API URL _without_ `/v1`. Claude Code appends
55
+ `/v1/messages`.
56
+ - Set every `ANTHROPIC_*_MODEL` variable and every `modelOverrides` entry.
57
+ Claude Code's built-in model names have no prefix. The variables map the
58
+ `opus`, `sonnet`, `haiku`, and `fable` aliases;
59
+ [`modelOverrides`](https://code.claude.com/docs/en/model-config#override-model-ids-per-version)
60
+ maps exact IDs; the `/model` picker can select either.
61
+ - The app's
62
+ [Model Filtering](../../policies/ai-gateway-model-filtering-v2-inbound.mdx)
63
+ policy controls which models the app can use.
85
64
 
86
- With this approach the gateway calls Anthropic with the API key you saved on the
87
- [provider](../managing-providers.mdx). Claude Code presents only the app's API
88
- key, and Anthropic bills the account that owns the provider key.
65
+ ## Use a provider key
89
66
 
90
- Add the following configuration to the settings file:
67
+ The gateway calls Anthropic with the key saved on your provider. Anthropic bills
68
+ that key's account. Your Claude subscription is not used.
91
69
 
92
70
  ```json
93
71
  {
@@ -111,58 +89,37 @@ Add the following configuration to the settings file:
111
89
  }
112
90
  ```
113
91
 
114
- `ANTHROPIC_AUTH_TOKEN` replaces whatever login Claude Code would otherwise use,
115
- so this approach doesn't consume your Claude subscription.
92
+ `ANTHROPIC_AUTH_TOKEN` replaces your `claude.ai` login.
116
93
 
117
94
  ## Use your Claude subscription
118
95
 
119
- With this approach Claude Code stays signed in to `claude.ai` — for example with
120
- a Claude Max plan — and the gateway forwards that login credential to Anthropic
121
- as the request's provider credential. The app's API key travels in a separate
122
- `zp-gateway-api-key` header, so the gateway still authenticates the app, applies
123
- its policy chain, and meters its usage.
124
-
125
- Two pieces of configuration make this work: the app's **API Key Authentication**
126
- policy accepts the app key from the `zp-gateway-api-key` header and passes the
127
- `Authorization` header through, and Claude Code sends both headers.
96
+ Claude Code stays signed in to `claude.ai`. The gateway forwards that login to
97
+ Anthropic and reads the app's API key from a separate `zp-gateway-api-key`
98
+ header, so it still authenticates the app, runs its policies, and meters usage.
128
99
 
129
100
  ### Configure the API Key Authentication policy
130
101
 
131
- The [API Key Authentication](../../policies/ai-gateway-auth-v2-inbound.mdx)
132
- policy needs three options for passthrough:
133
-
134
- | Option | Value | Effect |
135
- | ----------------------- | -------------------- | -------------------------------------------------------- |
136
- | `credentialPassthrough` | On | Forward the caller's `Authorization` header to Anthropic |
137
- | `authHeader` | `zp-gateway-api-key` | Read the app's API key from this header instead |
138
- | `authScheme` | Empty value | The header holds the bare key, with no `Bearer` prefix |
139
-
140
- You can set these options on the team's
141
- [policy template](../policy-templates.mdx), so every app created in the team
142
- starts with passthrough enabled, or on a single app's **Policies** tab. The
143
- steps below use the team template; the app's policy editor works the same way.
102
+ On the team's [policy template](../policy-templates.mdx), or on one app's
103
+ **Policies** tab, edit **API Key Authentication**:
144
104
 
145
105
  <Stepper>
146
106
 
147
- 1. Open the team in the Zuplo Portal and select its **Policy Template** tab.
148
-
149
- 2. Click the edit (pencil) icon on the **API Key Authentication** entry.
150
-
151
- 3. Turn on **credentialPassthrough**.
107
+ 1. Turn on **credentialPassthrough**.
152
108
 
153
- 4. Set **authHeader** to `zp-gateway-api-key`.
109
+ 2. Set **authHeader** to `zp-gateway-api-key`.
154
110
 
155
- 5. Leave **authScheme** blank and click **Use an empty value for authScheme**.
156
- The field then reports "Empty value set. The default (Bearer) is not
157
- applied." Clearing the field alone isn't enough: a blank field omits the
158
- option, so the `Bearer` default still applies and every request fails with
159
- `401 Invalid Authorization Scheme`.
111
+ 3. Leave **authScheme** blank and click **Use an empty value for authScheme**.
112
+ The field reports "Empty value set. The default (Bearer) is not applied."
160
113
 
161
- 6. Click **Apply**, then **Save changes**.
114
+ 4. Click **Apply**, then **Save changes**.
162
115
 
163
116
  </Stepper>
164
117
 
165
- The **JSON** editor mode shows the equivalent options:
118
+ A blank **authScheme** field is not an empty value. It omits the option, the
119
+ `Bearer` default still applies, and every request fails with
120
+ `401 Invalid Authorization Scheme`.
121
+
122
+ In the **JSON** editor:
166
123
 
167
124
  ```json
168
125
  {
@@ -172,29 +129,20 @@ The **JSON** editor mode shows the equivalent options:
172
129
  }
173
130
  ```
174
131
 
175
- ### The provider still needs an API key
176
-
177
- The Portal requires an API key to save an Anthropic provider, and passthrough
178
- requests never send it: the request to Anthropic carries the caller's credential
179
- instead. Anything else that uses this provider's configured credential still
180
- needs a real key. That includes apps on this gateway that don't use passthrough
181
- and any
182
- [Fallback Model](../../policies/ai-gateway-fallback-model-v2-inbound.mdx)
183
- target, because fallback requests use the provider's configured credential
184
- rather than the caller's. If nothing on the gateway uses the configured
185
- credential, a placeholder value works.
132
+ ### Rules
186
133
 
187
- The app's playground in the Portal sends the app key as a bearer token in
188
- `Authorization`, so it can't call an app that uses passthrough. Test the app
189
- from Claude Code instead, as described below.
134
+ - The provider still needs an API key to save. Passthrough requests never use
135
+ it. Apps without passthrough and every
136
+ [Fallback Model](../../policies/ai-gateway-fallback-model-v2-inbound.mdx)
137
+ target do. If nothing uses it, a placeholder value works.
138
+ - The Portal playground sends the app key as `Authorization: Bearer`, so it
139
+ can't call a passthrough app. Test from Claude Code.
140
+ - Do not set `ANTHROPIC_AUTH_TOKEN` or `ANTHROPIC_API_KEY`, in the settings file
141
+ or in your shell. Either one replaces your login, and the gateway forwards it
142
+ to Anthropic instead.
190
143
 
191
144
  ### Configure Claude Code
192
145
 
193
- Add the following configuration to the settings file. Don't set
194
- `ANTHROPIC_AUTH_TOKEN` or `ANTHROPIC_API_KEY` here or in your shell: either one
195
- replaces your `claude.ai` login, and the gateway would then forward that value
196
- to Anthropic as the credential.
197
-
198
146
  ```json
199
147
  {
200
148
  "env": {
@@ -217,73 +165,27 @@ to Anthropic as the credential.
217
165
  }
218
166
  ```
219
167
 
220
- `ANTHROPIC_CUSTOM_HEADERS` adds the `zp-gateway-api-key` header to every request
221
- Claude Code makes, while Claude Code keeps sending its own `Authorization`
222
- header from your login. The gateway consumes those incoming headers, uses the
223
- login credential to authenticate the Anthropic request, and never sends your app
224
- key to Anthropic.
168
+ `ANTHROPIC_CUSTOM_HEADERS` adds the `zp-gateway-api-key` header. Claude Code
169
+ keeps sending its own `Authorization` header from your login. The gateway never
170
+ sends your app key to Anthropic.
225
171
 
226
- ### Verify the subscription setup
227
-
228
- Restart Claude Code, then confirm which credential it's using and send one
229
- request through the gateway:
172
+ ## Verify
230
173
 
231
174
  ```bash
232
175
  claude auth status --text
233
176
  claude -p "Reply with the single word OK"
234
177
  ```
235
178
 
236
- The first command should report that you're signed in with your `claude.ai`
237
- account rather than an API key or auth token. The second returns a short reply,
238
- and the request appears in the app's usage in the Zuplo Portal. In an
239
- interactive session, `/status` shows the same login information.
240
-
241
- If the request fails:
242
-
243
- - `401` with `Invalid Authorization Scheme` — `authScheme` still has its
244
- `Bearer` default. Set it to an explicit empty value in the policy.
245
- - `401` with `Header configured by options.authHeader is missing` — Claude Code
246
- didn't send `zp-gateway-api-key`. Check `ANTHROPIC_CUSTOM_HEADERS`.
247
- - `401` with `credentialPassthrough requires a non-empty Authorization header` —
248
- Claude Code isn't signed in. Run `claude` and use `/login`.
249
- - An authentication error from Anthropic — Anthropic rejected the forwarded
250
- login credential. Sign in to Claude Code again.
251
-
252
- ## Configure every Claude Code model variable
253
-
254
- The model ids in these examples reflect what was current when this page was
255
- written, and ids differ across providers — a Bedrock provider serves different
256
- ids than Anthropic directly, and availability can vary by region. Check
257
- [your provider's page](../managing-providers.mdx) in the portal for the models
258
- it currently serves, and use those ids.
259
-
260
- None of Claude Code's built-in model names carry a provider prefix, so each of
261
- the model variables above must be set to a prefixed reference:
262
-
263
- - `ANTHROPIC_MODEL` — the startup model. Set it to a prefixed reference so the
264
- gateway can route the first request.
265
- - `ANTHROPIC_SMALL_FAST_MODEL` — the model for background tasks.
266
- - `ANTHROPIC_DEFAULT_OPUS_MODEL`, `ANTHROPIC_DEFAULT_SONNET_MODEL`,
267
- `ANTHROPIC_DEFAULT_HAIKU_MODEL`, `ANTHROPIC_DEFAULT_FABLE_MODEL` — what the
268
- `opus`/`sonnet`/`haiku`/`fable` aliases resolve to, so `claude --model opus`
269
- and `/model sonnet` keep working. In these examples,
270
- `ANTHROPIC_DEFAULT_FABLE_MODEL` maps `fable` to `anthropic/claude-fable-5-1`.
271
-
272
- Claude Code's `/model` picker can select either an alias or an exact model ID.
273
- `ANTHROPIC_DEFAULT_*_MODEL` maps aliases to gateway model names;
274
- [`modelOverrides`](https://code.claude.com/docs/en/model-config#override-model-ids-per-version)
275
- maps exact IDs. The examples configure both so either selection works through
276
- the gateway.
277
-
278
- :::caution{title='HTTP 400: model must use "providerName/model"'}
279
-
280
- This error means the selected model lacks its provider prefix. At startup, check
281
- `ANTHROPIC_MODEL`. After choosing a picker entry, check its `modelOverrides`
282
- entry, or type `/model fable` to use the configured alias. Restart Claude Code
283
- after editing the settings file.
179
+ With the subscription approach, the first command reports a `claude.ai` login,
180
+ not an API key or auth token. The request appears in the app's usage in the
181
+ Zuplo Portal.
284
182
 
285
- :::
183
+ ## Troubleshooting
286
184
 
287
- The app's
288
- [Model Filtering](../../policies/ai-gateway-model-filtering-v2-inbound.mdx)
289
- policy controls which models the app may use.
185
+ | Error | Fix |
186
+ | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
187
+ | `400` `model must use "providerName/model"` | The selected model has no provider prefix. Check `ANTHROPIC_MODEL`, or the picker entry's `modelOverrides` mapping. Restart after editing. |
188
+ | `401` `Invalid Authorization Scheme` | `authScheme` still has its `Bearer` default. Set an explicit empty value. |
189
+ | `401` `Header configured by options.authHeader is missing` | Claude Code didn't send `zp-gateway-api-key`. Check `ANTHROPIC_CUSTOM_HEADERS`. |
190
+ | `401` `credentialPassthrough requires a non-empty Authorization header` | Claude Code isn't signed in. Run `claude` and use `/login`. |
191
+ | An authentication error from Anthropic | Anthropic rejected the forwarded login. Sign in to Claude Code again. |