zuplo 7.9.5 → 7.9.8

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 (35) hide show
  1. package/docs/ai-gateway/apps.mdx +28 -16
  2. package/docs/ai-gateway/custom-policies.mdx +7 -7
  3. package/docs/ai-gateway/custom-providers.mdx +1 -1
  4. package/docs/ai-gateway/fallback.mdx +5 -5
  5. package/docs/ai-gateway/integrations/ai-sdk.mdx +2 -2
  6. package/docs/ai-gateway/integrations/claude-code.mdx +41 -33
  7. package/docs/ai-gateway/integrations/claude-desktop.mdx +37 -34
  8. package/docs/ai-gateway/integrations/codex.mdx +42 -31
  9. package/docs/ai-gateway/integrations/github-copilot.mdx +39 -37
  10. package/docs/ai-gateway/integrations/goose.mdx +27 -30
  11. package/docs/ai-gateway/integrations/langchain.mdx +2 -2
  12. package/docs/ai-gateway/integrations/openai.mdx +2 -2
  13. package/docs/ai-gateway/jev.mdx +344 -0
  14. package/docs/ai-gateway/managing-apps.mdx +22 -22
  15. package/docs/ai-gateway/managing-pools.mdx +87 -0
  16. package/docs/ai-gateway/managing-providers.mdx +4 -4
  17. package/docs/ai-gateway/overview.mdx +38 -26
  18. package/docs/ai-gateway/policy-chains.mdx +7 -7
  19. package/docs/ai-gateway/policy-templates.mdx +22 -22
  20. package/docs/ai-gateway/pools.mdx +53 -0
  21. package/docs/ai-gateway/providers.mdx +32 -2
  22. package/docs/ai-gateway/source-control.mdx +2 -2
  23. package/docs/ai-gateway/universal-api.mdx +4 -0
  24. package/docs/ai-gateway/usage-limits.mdx +49 -47
  25. package/docs/ai-gateway/user-apps.mdx +166 -0
  26. package/docs/articles/accounts/roles-and-permissions.mdx +92 -63
  27. package/docs/concepts/ai-gateway.mdx +24 -20
  28. package/docs/policies/ai-gateway-akamai-firewall-inbound/doc.md +1 -1
  29. package/docs/policies/ai-gateway-metering-inbound/schema.json +16 -2
  30. package/docs/policies/ai-gateway-smart-router-inbound/doc.md +172 -29
  31. package/docs/policies/ai-gateway-smart-router-inbound/intro.md +4 -3
  32. package/docs/policies/ai-gateway-smart-router-inbound/schema.json +177 -30
  33. package/package.json +5 -5
  34. package/docs/ai-gateway/managing-teams.mdx +0 -87
  35. package/docs/ai-gateway/teams.mdx +0 -49
@@ -2,17 +2,27 @@
2
2
  title: AI Gateway Apps
3
3
  sidebar_label: Overview
4
4
  description:
5
- Apps represent the services and integrations that call your AI Gateway. Each
6
- app has its own URL, API key, and policy chain.
5
+ Apps are how software and people call your AI Gateway. Services use apps with
6
+ their own API keys; people use the User App with their own personal API key.
7
7
  ---
8
8
 
9
- An app represents one caller of your AI Gateway—a service, an agent, or a
10
- feature in a larger codebase. A support chatbot on your website is one app; the
11
- batch job that summarizes tickets overnight is another. Each app belongs to a
12
- [team](./teams.mdx), which controls dashboard access to the app. Access to AI
13
- providers is governed separately by the user's Zuplo account and Zuplo project
14
- roles. A Zuplo account contains one or more projects, and the AI Gateway is the
15
- Zuplo project that contains these providers, teams, and apps. See
9
+ Everything that calls your AI Gateway goes through an app. There are two kinds:
10
+
11
+ | Kind | Who calls it | Key | Budget |
12
+ | ------------------------------- | ---------------------------------------------------------------- | ---------------------------------- | ------------------------------------------------ |
13
+ | **App** | Software: a service, an agent, or a feature in a larger codebase | One API key per app | The app's own, plus its pool's and the gateway's |
14
+ | **[User App](./user-apps.mdx)** | People, from their everyday tools such as Claude Code or Codex | Each person's own personal API key | Per person, plus the gateway's |
15
+
16
+ A support chatbot on your website is one app; the batch job that summarizes
17
+ tickets overnight is another. An engineer who wants to use Claude Code through
18
+ the gateway doesn't need an app of their own: they create a personal key and
19
+ call the project's [User App](./user-apps.mdx).
20
+
21
+ The rest of this page covers apps. Each app belongs to a [pool](./pools.mdx),
22
+ which groups apps and controls dashboard access to them. Access to AI providers
23
+ is governed separately by the user's Zuplo account and Zuplo project roles. A
24
+ Zuplo account contains one or more projects, and the AI Gateway is the Zuplo
25
+ project that contains these providers, pools, and apps. See
16
26
  [Role Permissions](../articles/accounts/roles-and-permissions.mdx).
17
27
 
18
28
  Each app has three things of its own:
@@ -28,7 +38,7 @@ Each app has three things of its own:
28
38
  [authentication policy](./policy-chains.mdx#authentication).
29
39
  - **A [policy chain](./policy-chains.mdx)**—the ordered policies that run on the
30
40
  app's requests: model access, app-specific budgets, caching, guardrails, and
31
- custom policies. The chain starts out empty unless the app's team has a
41
+ custom policies. The chain starts out empty unless the app's pool has a
32
42
  [policy template](./policy-templates.mdx).
33
43
 
34
44
  ## API Keys
@@ -40,14 +50,14 @@ validated key or from the `{app_id}` segment of the request URL, so an app
40
50
  without authentication still tracks usage independently.
41
51
 
42
52
  To find an app's API key, open the
43
- [Apps & Teams](https://portal.zuplo.com/+/account/project/ai/apps) tab of your
44
- AI Gateway project in the Zuplo Portal and select the app. The key lives on the
53
+ [Apps](https://portal.zuplo.com/+/account/project/ai/apps) tab of your AI
54
+ Gateway project in the Zuplo Portal and select the app. The key lives on the
45
55
  app's **API Key** tab.
46
56
 
47
57
  :::caution{title="Rotate keys to revoke access"}
48
58
 
49
59
  An issued app API key authenticates gateway traffic by the key itself. Changing
50
- a user's dashboard permissions or removing them from a team doesn't invalidate
60
+ a user's dashboard permissions or removing them from a pool doesn't invalidate
51
61
  the key. To revoke access, rotate the app's API key and update authorized
52
62
  clients with the new value.
53
63
 
@@ -57,7 +67,9 @@ clients with the new value.
57
67
 
58
68
  - [Creating & Editing Apps](./managing-apps.mdx) - How to create, configure, and
59
69
  delete apps.
60
- - [Creating & Editing Teams](./managing-teams.mdx) - How to create and edit
61
- teams.
70
+ - [User Apps](./user-apps.mdx) - How people call the gateway with a personal API
71
+ key.
72
+ - [Creating & Editing Pools](./managing-pools.mdx) - How to create and edit
73
+ pools.
62
74
  - [Role Permissions](../articles/accounts/roles-and-permissions.mdx) - Details
63
- on Zuplo account, Zuplo project, and AI Gateway team roles.
75
+ on Zuplo account, Zuplo project, and AI Gateway pool roles.
@@ -11,7 +11,7 @@ The AI Gateway's built-in policies cover model access, app-specific budgets,
11
11
  caching, guardrails, and tracing—but your gateway can run any policy you can
12
12
  write in TypeScript. A custom policy lives in your gateway's
13
13
  [repository](./source-control.mdx), is declared in `config/policies.json`, and
14
- from then on appears in the portal's **Add Policy** dialog like any built-in
14
+ from then on appears in the portal's **Add policy** dialog like any built-in
15
15
  policy. Apps add it to their [policy chains](./policy-chains.mdx), and it runs
16
16
  on every request for those apps.
17
17
 
@@ -21,7 +21,7 @@ terms. By the end, one app on your gateway rejects a prompt containing
21
21
 
22
22
  ## Prerequisites
23
23
 
24
- - An AI Gateway project connected to a Git repository, with a provider, a team,
24
+ - An AI Gateway project connected to a Git repository, with a provider, a pool,
25
25
  and an app—the [Getting Started](../getting-started/ai-gateway/portal.mdx)
26
26
  guide covers this
27
27
  - A local clone of the gateway's repository
@@ -118,10 +118,10 @@ terms. By the end, one app on your gateway rejects a prompt containing
118
118
  4. **Add the policy to an app's chain**
119
119
 
120
120
  In the Zuplo Portal, open
121
- [**Apps & Teams**](https://portal.zuplo.com/+/account/project/ai/apps),
122
- select your app, and open its **Policies** tab. Click **Add
123
- Policy**—`content-filter` now appears alongside the built-in policies. Add
124
- it, drag it to where in the chain it should run, and save.
121
+ [**Apps**](https://portal.zuplo.com/+/account/project/ai/apps), select your
122
+ app, and open its **Policies** tab. Click **Add policy**—`content-filter` now
123
+ appears alongside the built-in policies. Add it, drag it to where in the
124
+ chain it should run, and save.
125
125
 
126
126
  :::tip{title="Where in the chain?"}
127
127
 
@@ -214,5 +214,5 @@ complete recipes:
214
214
  - [Policy Chains](./policy-chains.mdx): execution order, options inheritance,
215
215
  and the built-in policies
216
216
  - [Policy Templates](./policy-templates.mdx): roll a custom policy out to every
217
- new app in a team
217
+ new app in a pool
218
218
  - [Source Control](./source-control.mdx): how repository changes deploy
@@ -59,7 +59,7 @@ To add a custom AI provider to your Zuplo AI Gateway, follow these steps:
59
59
  reserves the built-in provider names (`openai`, `anthropic`, `google`,
60
60
  `mistral`, `xai`, `moonshot`, `zuplo`, `zuplodemo`, `zuplo-demo`,
61
61
  `bedrockmantle`, `bedrock-mantle`, `azureai`, `azure-ai`, `vertexai`,
62
- `vertex-ai`, `openrouter`, `open-router`). The name is permanent after
62
+ `vertex-ai`, `openrouter`, `open-router`, `jev`). The name is permanent after
63
63
  creation.
64
64
 
65
65
  1. Enter the provider's **API URL** as its origin root—for example
@@ -17,7 +17,7 @@ different condition:
17
17
  | Mechanism | Triggers when… | Without a fallback set… |
18
18
  | ---------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------- |
19
19
  | **Fallback & Timeout** | The primary fails with a retryable error (`5xx`, `408`, `425`, `429`), a network failure, or a timeout | The gateway returns the error to the caller |
20
- | **Quota Fallback** | An app, team, or gateway usage limit is exceeded | The request is blocked with a `429` |
20
+ | **Quota Fallback** | An app, pool, or gateway usage limit is exceeded | The request is blocked with a `429` |
21
21
 
22
22
  Both are configured entirely in the Zuplo Portal, and either can route to _any_
23
23
  provider—the fallback doesn't have to share the primary's provider. Fallback
@@ -27,11 +27,11 @@ models are referenced like any model, as `providerName/model`.
27
27
 
28
28
  <Stepper>
29
29
 
30
- 1. Open the [Apps & Teams](https://portal.zuplo.com/+/account/project/ai/apps)
31
- tab of your AI Gateway project and select the app to edit.
30
+ 1. Open the [Apps](https://portal.zuplo.com/+/account/project/ai/apps) tab of
31
+ your AI Gateway project and select the app to edit.
32
32
 
33
33
  1. Select the **Policies** tab. If the chain doesn't have a **Fallback Model**
34
- policy yet, click **Add Policy** and add it—placed directly after Model
34
+ policy yet, click **Add policy** and add it—placed directly after Model
35
35
  Filtering.
36
36
 
37
37
  1. Configure the policy:
@@ -57,7 +57,7 @@ is configured, the primary model call runs unbounded.
57
57
  ## Quota fallback
58
58
 
59
59
  For requests continuing to a provider, the quota fallback selects an alternate,
60
- usually cheaper, model when an app, team, or gateway
60
+ usually cheaper, model when an app, pool, or gateway
61
61
  [usage limit](./usage-limits.mdx) is exceeded, rather than blocking the request
62
62
  with a `429`. This keeps an app available after an applicable budget, token, or
63
63
  request threshold is crossed, while shifting the overflow traffic to a
@@ -22,10 +22,10 @@ complete these steps first:
22
22
  1. Create a [new provider](../managing-providers.mdx) in the AI Gateway for the
23
23
  provider you want to use with AI SDK
24
24
 
25
- 2. [Set up a new team](../managing-teams.mdx)
25
+ 2. [Set up a new pool](../managing-pools.mdx)
26
26
 
27
27
  3. Create a [new app](../managing-apps.mdx) to use specifically with AI SDK and
28
- assign it to the team you created
28
+ assign it to the pool you created
29
29
 
30
30
  4. Copy the **API URL** and **API Key** shown at the top of the app page
31
31
 
@@ -2,8 +2,8 @@
2
2
  title: Claude Code
3
3
  sidebar_label: Claude Code
4
4
  description:
5
- Route Claude Code requests through a Zuplo AI Gateway app, with a provider key
6
- or your Claude subscription.
5
+ Route Claude Code through the Zuplo AI Gateway with your personal API key or
6
+ an app's API key, using either a provider key or your Claude subscription.
7
7
  ---
8
8
 
9
9
  Route [Claude Code](https://www.claude.com/product/claude-code) through the
@@ -11,27 +11,27 @@ Zuplo AI Gateway. The gateway authenticates, meters, and routes every session.
11
11
 
12
12
  The gateway authenticates to Anthropic in one of two ways:
13
13
 
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 |
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 | Your personal API key, or an 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 | An app's API key in a `zp-gateway-api-key` header, plus your login |
18
18
 
19
19
  ## Prerequisites
20
20
 
21
- <Stepper>
22
-
23
- 1. Create an Anthropic [provider](../managing-providers.mdx) in the AI Gateway.
24
-
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.
28
-
29
- 3. [Create an app](../managing-apps.mdx) for Claude Code and assign it to the
30
- team.
21
+ Create an Anthropic [provider](../managing-providers.mdx) in the AI Gateway,
22
+ then get a gateway URL and key in one of two ways:
31
23
 
32
- 4. Copy the **API URL** and **API Key** from the app page.
24
+ - **Use your personal API key (recommended).** Claude Code runs on your own
25
+ machine, so call the project's [User App](../user-apps.mdx). Open the
26
+ [**Home**](https://portal.zuplo.com/+/account/project/ai/home) tab of your AI
27
+ Gateway project, copy the **Gateway URL**, and create a key under **My API
28
+ keys**. Your requests count against your own budget.
29
+ - **Use an app.** For a shared or automated setup, and for the
30
+ [Claude subscription](#use-your-claude-subscription) approach,
31
+ [create a pool](../managing-pools.mdx) and [an app](../managing-apps.mdx) for
32
+ Claude Code, then copy the app's **API URL** and **API Key**.
33
33
 
34
- </Stepper>
34
+ The rest of this guide calls these your **gateway URL** and **gateway key**.
35
35
 
36
36
  ## Configure Claude Code
37
37
 
@@ -51,27 +51,29 @@ project. Add the block for your approach, then restart Claude Code.
51
51
 
52
52
  ### Rules
53
53
 
54
- - `ANTHROPIC_BASE_URL` is the app's API URL _without_ `/v1`. Claude Code appends
54
+ - `ANTHROPIC_BASE_URL` is your gateway URL _without_ `/v1`. Claude Code appends
55
55
  `/v1/messages`.
56
56
  - Set every `ANTHROPIC_*_MODEL` variable and every `modelOverrides` entry.
57
57
  Claude Code's built-in model names have no prefix. The variables map the
58
58
  `opus`, `sonnet`, `haiku`, and `fable` aliases;
59
59
  [`modelOverrides`](https://code.claude.com/docs/en/model-config#override-model-ids-per-version)
60
60
  maps exact IDs; the `/model` picker can select either.
61
- - The app's
62
- [Model Filtering](../../policies/ai-gateway-model-filtering-inbound.mdx)
63
- policy controls which models the app can use.
61
+ - The [Model Filtering](../../policies/ai-gateway-model-filtering-inbound.mdx)
62
+ policy on the User App or the app controls which models you can use.
64
63
 
65
64
  ## Use a provider key
66
65
 
67
66
  The gateway calls Anthropic with the key saved on your provider. Anthropic bills
68
67
  that key's account. Your Claude subscription is not used.
69
68
 
69
+ This example uses a personal API key and the User App's gateway URL. For an app,
70
+ use the app's API key and API URL instead.
71
+
70
72
  ```json
71
73
  {
72
74
  "env": {
73
- "ANTHROPIC_AUTH_TOKEN": "<your-ai-gateway-app-api-key>",
74
- "ANTHROPIC_BASE_URL": "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e",
75
+ "ANTHROPIC_AUTH_TOKEN": "<your-personal-api-key>",
76
+ "ANTHROPIC_BASE_URL": "https://my-gateway-main-2e18f50.zuplo.app/u/741d375d631b429293481d6d0458bb64",
75
77
  "ANTHROPIC_MODEL": "anthropic/claude-sonnet-5",
76
78
  "ANTHROPIC_SMALL_FAST_MODEL": "anthropic/claude-haiku-4-5",
77
79
  "ANTHROPIC_DEFAULT_OPUS_MODEL": "anthropic/claude-opus-5",
@@ -93,13 +95,17 @@ that key's account. Your Claude subscription is not used.
93
95
 
94
96
  ## Use your Claude subscription
95
97
 
98
+ This approach is shown with an app. On the User App, turning on passthrough
99
+ would change authentication for everyone who uses it, so use an app for
100
+ subscription logins.
101
+
96
102
  Claude Code stays signed in to `claude.ai`. The gateway forwards that login to
97
103
  Anthropic and reads the app's API key from a separate `zp-gateway-api-key`
98
104
  header, so it still authenticates the app, runs its policies, and meters usage.
99
105
 
100
106
  ### Configure the API Key Authentication policy
101
107
 
102
- On the team's [policy template](../policy-templates.mdx), or on one app's
108
+ On the pool's [policy template](../policy-templates.mdx), or on one app's
103
109
  **Policies** tab, edit **API Key Authentication**:
104
110
 
105
111
  <Stepper>
@@ -177,15 +183,17 @@ claude -p "Reply with the single word OK"
177
183
  ```
178
184
 
179
185
  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
186
+ not an API key or auth token. With a personal key, the request appears in your
187
+ usage on the **Home** tab; with an app, it appears in the app's usage in the
181
188
  Zuplo Portal.
182
189
 
183
190
  ## Troubleshooting
184
191
 
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. |
192
+ | Error | Fix |
193
+ | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
194
+ | `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. |
195
+ | `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 **Home** and use the Gateway URL from the same project. |
196
+ | `401` `Invalid Authorization Scheme` | `authScheme` still has its `Bearer` default. Set an explicit empty value. |
197
+ | `401` `Header configured by options.authHeader is missing` | Claude Code didn't send `zp-gateway-api-key`. Check `ANTHROPIC_CUSTOM_HEADERS`. |
198
+ | `401` `credentialPassthrough requires a non-empty Authorization header` | Claude Code isn't signed in. Run `claude` and use `/login`. |
199
+ | An authentication error from Anthropic | Anthropic rejected the forwarded login. Sign in to Claude Code again. |
@@ -2,8 +2,8 @@
2
2
  title: Claude Desktop
3
3
  sidebar_label: Claude Desktop
4
4
  description:
5
- Route Claude Desktop's Chat, Cowork, and Code sessions through a Zuplo AI
6
- Gateway app.
5
+ Route Claude Desktop's Chat, Cowork, and Code sessions through the Zuplo AI
6
+ Gateway with your personal API key, or with an app's key for a managed fleet.
7
7
  ---
8
8
 
9
9
  Route [Claude Desktop](https://claude.com/download) through the Zuplo AI
@@ -15,18 +15,20 @@ To give Claude Desktop tools from a Zuplo MCP route instead, see
15
15
 
16
16
  ## Prerequisites
17
17
 
18
- <Stepper>
19
-
20
- 1. Create an Anthropic [provider](../managing-providers.mdx) in the AI Gateway.
21
-
22
- 2. [Create a team](../managing-teams.mdx).
18
+ Create an Anthropic [provider](../managing-providers.mdx) in the AI Gateway,
19
+ then get a gateway URL and key in one of two ways:
23
20
 
24
- 3. [Create an app](../managing-apps.mdx) for Claude Desktop and assign it to the
25
- team.
21
+ - **Use your personal API key (recommended).** Claude Desktop runs on your own
22
+ machine, so call the project's [User App](../user-apps.mdx). Open the
23
+ [**Home**](https://portal.zuplo.com/+/account/project/ai/home) tab of your AI
24
+ Gateway project, copy the **Gateway URL**, and create a key under **My API
25
+ keys**. Your requests count against your own budget.
26
+ - **Use an app.** For a shared setup, such as
27
+ [deploying to a fleet](#deploy-to-a-fleet) with one key,
28
+ [create a pool](../managing-pools.mdx) and [an app](../managing-apps.mdx) for
29
+ Claude Desktop, then copy the app's **API URL** and **API Key**.
26
30
 
27
- 4. Copy the **API URL** and **API Key** from the app page.
28
-
29
- </Stepper>
31
+ The rest of this guide calls these your **gateway URL** and **gateway key**.
30
32
 
31
33
  ## Configure Claude Desktop
32
34
 
@@ -39,16 +41,15 @@ To give Claude Desktop tools from a Zuplo MCP route instead, see
39
41
 
40
42
  3. Under **Connection**, set **Inference provider** to **Gateway**.
41
43
 
42
- 4. Under **Gateway credentials**, set **Gateway base URL** to the app's API URL,
44
+ 4. Under **Gateway credentials**, set **Gateway base URL** to your gateway URL,
43
45
  for example
44
- `https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e`,
45
- and **Gateway API key** to the app's API key.
46
+ `https://my-gateway-main-2e18f50.zuplo.app/u/741d375d631b429293481d6d0458bb64`,
47
+ and **Gateway API key** to your gateway key.
46
48
 
47
49
  5. Leave **Credential kind** set to **Static API key** and **Gateway auth
48
50
  scheme** set to **Bearer**.
49
51
 
50
- 6. Under **Models**, add each model the app may use. See
51
- [Add models](#add-models).
52
+ 6. Under **Models**, add each model you may use. See [Add models](#add-models).
52
53
 
53
54
  7. Click **Apply locally**. Claude Desktop saves the configuration and
54
55
  relaunches.
@@ -57,12 +58,12 @@ To give Claude Desktop tools from a Zuplo MCP route instead, see
57
58
 
58
59
  ### Rules
59
60
 
60
- - **Gateway base URL** is the app's API URL _without_ `/v1`. Claude Desktop
61
+ - **Gateway base URL** is your gateway URL _without_ `/v1`. Claude Desktop
61
62
  appends `/v1/messages`.
62
63
  - **Gateway auth scheme** stays **Bearer**. The gateway reads the API key from
63
64
  the `Authorization: Bearer` header.
64
- - **Credential kind** stays **Static API key**. AI Gateway apps authenticate
65
- with API keys, not identity-provider tokens.
65
+ - **Credential kind** stays **Static API key**. The AI Gateway authenticates
66
+ with personal or app API keys, not identity-provider tokens.
66
67
 
67
68
  ## Add models
68
69
 
@@ -92,28 +93,30 @@ Click **Add** once per model:
92
93
  The first entry is the picker default. Include a Haiku-tier model: Claude
93
94
  Desktop runs background and sub-agent tasks on a small, fast model.
94
95
 
95
- The app's
96
- [Model Filtering](../../policies/ai-gateway-model-filtering-inbound.mdx) policy
97
- controls which models the app can use.
96
+ The [Model Filtering](../../policies/ai-gateway-model-filtering-inbound.mdx)
97
+ policy on the User App or the app controls which models you can use.
98
98
 
99
99
  ## Verify
100
100
 
101
- Send a message in Chat and start a Cowork session. Both appear in the app's
102
- usage in the Zuplo Portal, as do Code sessions started from the desktop app.
103
- Terminal Claude Code sessions use their own configuration. See
104
- [Claude Code](./claude-code.mdx).
101
+ Send a message in Chat and start a Cowork session. Both appear in your usage on
102
+ the **Home** tab, or in the app's usage if you used an app, as do Code sessions
103
+ started from the desktop app. Terminal Claude Code sessions use their own
104
+ configuration. See [Claude Code](./claude-code.mdx).
105
105
 
106
106
  ## Troubleshooting
107
107
 
108
- | Error | Fix |
109
- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------- |
110
- | `400` `The request body model must use "providerName/model"` | A model list entry has no provider prefix. Give every entry a full `providerName/model` ID. |
108
+ | Error | Fix |
109
+ | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
110
+ | `400` `The request body model must use "providerName/model"` | A model list entry has no provider prefix. Give every entry a full `providerName/model` ID. |
111
+ | `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 **Home** and use the Gateway URL from the same project. |
111
112
 
112
113
  ## Deploy to a fleet
113
114
 
114
- Use the configuration window's **Export** menu instead of **Apply locally**. It
115
- produces a `.mobileconfig` profile for macOS MDM tools such as Jamf, a `.reg`
116
- policy file for Intune or Group Policy, and related artifacts. Managed
117
- configuration overrides local settings. See Anthropic's
115
+ A fleet deployment shares one gateway key across machines, so use an app's API
116
+ URL and API key rather than a personal key. Use the configuration window's
117
+ **Export** menu instead of **Apply locally**. It produces a `.mobileconfig`
118
+ profile for macOS MDM tools such as Jamf, a `.reg` policy file for Intune or
119
+ Group Policy, and related artifacts. Managed configuration overrides local
120
+ settings. See Anthropic's
118
121
  [Deploy Claude Desktop with an LLM gateway](https://claude.com/docs/third-party/claude-desktop/gateway)
119
122
  and [Deploy with MDM](https://claude.com/docs/third-party/claude-desktop/mdm).
@@ -1,7 +1,9 @@
1
1
  ---
2
2
  title: Codex
3
3
  sidebar_label: Codex
4
- description: Route Codex CLI requests through a Zuplo AI Gateway app.
4
+ description:
5
+ Route Codex CLI requests through the Zuplo AI Gateway with your personal API
6
+ key or an app's API key, using a provider key or your ChatGPT subscription.
5
7
  ---
6
8
 
7
9
  [Codex](https://developers.openai.com/codex) is OpenAI's coding agent for the
@@ -12,24 +14,25 @@ Two approaches:
12
14
  - **Use a provider key.** The gateway calls OpenAI with the API key saved on
13
15
  your provider. OpenAI bills that key's account.
14
16
  - **Use your ChatGPT subscription.** Codex stays signed in with `codex login`.
15
- The gateway forwards that login to OpenAI and meters usage against your app.
17
+ The gateway forwards that login to OpenAI and meters usage against an app.
16
18
  Your ChatGPT plan pays for the tokens.
17
19
 
18
20
  ## Prerequisites
19
21
 
20
- <Stepper>
22
+ Create an OpenAI [provider](../managing-providers.mdx) in the AI Gateway, then
23
+ get a gateway URL and key in one of two ways:
21
24
 
22
- 1. Create an OpenAI [provider](../managing-providers.mdx) in the AI Gateway.
25
+ - **Use your personal API key (recommended).** Codex runs on your own machine,
26
+ so call the project's [User App](../user-apps.mdx). Open the
27
+ [**Home**](https://portal.zuplo.com/+/account/project/ai/home) tab of your AI
28
+ Gateway project, copy the **Gateway URL**, and create a key under **My API
29
+ keys**. Your requests count against your own budget.
30
+ - **Use an app.** For a shared or automated setup, and for the
31
+ [ChatGPT subscription](#use-your-chatgpt-subscription) approach,
32
+ [create a pool](../managing-pools.mdx) and [an app](../managing-apps.mdx) for
33
+ Codex, then copy the app's **API URL** and **API Key**.
23
34
 
24
- 2. [Create a team](../managing-teams.mdx). For the subscription approach,
25
- [configure its API Key Authentication policy](#configure-the-api-key-authentication-policy)
26
- now.
27
-
28
- 3. [Create an app](../managing-apps.mdx) for Codex and assign it to the team.
29
-
30
- 4. Copy the **API URL** and **API Key** from the app page.
31
-
32
- </Stepper>
35
+ The rest of this guide calls these your **gateway URL** and **gateway key**.
33
36
 
34
37
  ## Configure Codex
35
38
 
@@ -47,27 +50,34 @@ Codex reads configuration from `~/.codex/config.toml`. Create this file (and the
47
50
  approach, then set the API key in your environment and restart Codex:
48
51
 
49
52
  ```bash
50
- export ZUPLO_AI_GATEWAY_API_KEY="<your-app-api-key>"
53
+ export ZUPLO_AI_GATEWAY_API_KEY="<your-gateway-key>"
51
54
  ```
52
55
 
53
56
  ### Use a provider key
54
57
 
58
+ This example uses the User App's gateway URL. For an app, use the app's API URL
59
+ instead.
60
+
55
61
  ```toml
56
62
  model_provider = "zuplo"
57
63
  model = "openai/gpt-5"
58
64
 
59
65
  [model_providers.zuplo]
60
66
  name = "Zuplo AI Gateway"
61
- base_url = "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1"
67
+ base_url = "https://my-gateway-main-2e18f50.zuplo.app/u/741d375d631b429293481d6d0458bb64/v1"
62
68
  env_key = "ZUPLO_AI_GATEWAY_API_KEY"
63
69
  wire_api = "responses"
64
70
  ```
65
71
 
66
- - `base_url` is the app's API URL with `/v1` appended.
72
+ - `base_url` is your gateway URL with `/v1` appended.
67
73
  - `model` is `providerName/model`.
68
74
 
69
75
  ### Use your ChatGPT subscription
70
76
 
77
+ This approach is shown with an app. On the User App, turning on passthrough
78
+ would change authentication for everyone who uses it, so use an app for
79
+ subscription logins.
80
+
71
81
  ```toml
72
82
  model_provider = "zuplo"
73
83
  model = "openai/gpt-5.6-sol"
@@ -92,7 +102,7 @@ login anywhere except OpenAI, and never sends your app key to OpenAI.
92
102
 
93
103
  #### Configure the API Key Authentication policy
94
104
 
95
- On the team's [policy template](../policy-templates.mdx), or on the app's
105
+ On the pool's [policy template](../policy-templates.mdx), or on the app's
96
106
  **Policies** tab, edit **API Key Authentication** in the **JSON** editor:
97
107
 
98
108
  ```json
@@ -137,9 +147,8 @@ prefix, and the gateway rejects them with a `400`.
137
147
  Codex warns that it has no metadata for a prefixed model name. Requests still
138
148
  succeed.
139
149
 
140
- The app's
141
- [Model Filtering](../../policies/ai-gateway-model-filtering-inbound.mdx) policy
142
- controls which models the app can use.
150
+ The [Model Filtering](../../policies/ai-gateway-model-filtering-inbound.mdx)
151
+ policy on the User App or the app controls which models you can use.
143
152
 
144
153
  ## Verify
145
154
 
@@ -147,18 +156,20 @@ controls which models the app can use.
147
156
  codex exec "Reply with the single word OK"
148
157
  ```
149
158
 
150
- The session header shows `provider: zuplo`. The request appears in the app's
159
+ The session header shows `provider: zuplo`. With a personal key, the request
160
+ appears in your usage on the **Home** tab; with an app, it appears in the app's
151
161
  usage in the Zuplo Portal.
152
162
 
153
163
  ## Troubleshooting
154
164
 
155
- | Error | Fix |
156
- | ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------- |
157
- | `400` `The request body model must use "providerName/model"` | Add the provider prefix to `model`. Do not use the `/model` picker. |
158
- | `ERROR: Missing environment variable: ZUPLO_AI_GATEWAY_API_KEY` | Export the variable in the shell that runs Codex. |
159
- | `401` `Authorization Failed` | The API key is wrong. Copy it from the app's **API Key** tab. |
160
- | `401` `Header configured by options.authHeader is missing` | Subscription approach: add the `env_http_headers` line and export `ZUPLO_AI_GATEWAY_API_KEY`. |
161
- | `401` `Invalid Authorization Scheme` | Set `authScheme` to the empty string in the policy JSON. |
162
- | `401` `rejected the credential this app passed through from the caller` `(HTTP 401)` | Your ChatGPT login expired or is invalid. Run `codex login` again. |
163
- | `401` `Missing scopes: api.responses.write` | The app is not in passthrough mode. Configure the API Key Authentication policy as above. |
164
- | Errors mention `api.openai.com` or `not supported when using Codex with a ChatGPT account` | Codex is not using your provider. Set `model_provider = "zuplo"`. |
165
+ | Error | Fix |
166
+ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
167
+ | `400` `The request body model must use "providerName/model"` | Add the provider prefix to `model`. Do not use the `/model` picker. |
168
+ | `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 **Home** and use the Gateway URL from the same project. |
169
+ | `ERROR: Missing environment variable: ZUPLO_AI_GATEWAY_API_KEY` | Export the variable in the shell that runs Codex. |
170
+ | `401` `Authorization Failed` | With an app: the key is wrong. Copy it from the app's **API Key** tab. |
171
+ | `401` `Header configured by options.authHeader is missing` | Subscription approach: add the `env_http_headers` line and export `ZUPLO_AI_GATEWAY_API_KEY`. |
172
+ | `401` `Invalid Authorization Scheme` | Set `authScheme` to the empty string in the policy JSON. |
173
+ | `401` `rejected the credential this app passed through from the caller` `(HTTP 401)` | Your ChatGPT login expired or is invalid. Run `codex login` again. |
174
+ | `401` `Missing scopes: api.responses.write` | The app is not in passthrough mode. Configure the API Key Authentication policy as above. |
175
+ | Errors mention `api.openai.com` or `not supported when using Codex with a ChatGPT account` | Codex is not using your provider. Set `model_provider = "zuplo"`. |