zuplo 7.1.1 → 7.1.3
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.
- package/docs/ai-gateway/apps.mdx +28 -10
- package/docs/ai-gateway/cookbooks/custom-fallback.mdx +96 -0
- package/docs/ai-gateway/cookbooks/dynamic-model-routing.mdx +119 -0
- package/docs/ai-gateway/custom-policies.mdx +213 -0
- package/docs/ai-gateway/custom-providers.mdx +11 -2
- package/docs/ai-gateway/fallback.mdx +48 -75
- package/docs/ai-gateway/getting-started.mdx +202 -133
- package/docs/ai-gateway/integrations/ai-sdk.mdx +71 -28
- package/docs/ai-gateway/integrations/claude-code.mdx +32 -8
- package/docs/ai-gateway/integrations/codex.mdx +28 -10
- package/docs/ai-gateway/integrations/goose.mdx +26 -19
- package/docs/ai-gateway/integrations/langchain.mdx +31 -15
- package/docs/ai-gateway/integrations/openai.mdx +28 -16
- package/docs/ai-gateway/introduction.mdx +73 -32
- package/docs/ai-gateway/managing-apps.mdx +62 -17
- package/docs/ai-gateway/managing-providers.mdx +26 -8
- package/docs/ai-gateway/managing-teams.mdx +29 -12
- package/docs/ai-gateway/policies/akamai-ai-firewall.mdx +92 -96
- package/docs/ai-gateway/policies/authentication.mdx +44 -0
- package/docs/ai-gateway/policies/comet-opik-tracing.mdx +40 -2
- package/docs/ai-gateway/policies/fallback-model.mdx +40 -0
- package/docs/ai-gateway/policies/galileo-tracing.mdx +36 -22
- package/docs/ai-gateway/policies/metering.mdx +47 -0
- package/docs/ai-gateway/policies/model-filtering.mdx +49 -0
- package/docs/ai-gateway/policies/overview.mdx +28 -0
- package/docs/ai-gateway/policies/semantic-cache.mdx +48 -0
- package/docs/ai-gateway/policy-chains.mdx +178 -0
- package/docs/ai-gateway/policy-templates.mdx +68 -0
- package/docs/ai-gateway/providers.mdx +47 -9
- package/docs/ai-gateway/source-control.mdx +88 -0
- package/docs/ai-gateway/teams.mdx +16 -10
- package/docs/ai-gateway/universal-api.mdx +39 -12
- package/docs/ai-gateway/usage-limits.mdx +87 -55
- package/docs/policies/cdn-cache-control-outbound/doc.md +13 -13
- package/package.json +5 -5
- package/docs/ai-gateway/guardrails.mdx +0 -65
|
@@ -1,130 +1,202 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Zuplo AI Gateway Getting Started
|
|
3
3
|
sidebar_label: Getting Started
|
|
4
|
+
description:
|
|
5
|
+
Set up your first AI Gateway project. Connect a Git repository, configure an
|
|
6
|
+
AI provider, create a team and an app, review the app's policy chain, and make
|
|
7
|
+
your first LLM request through Zuplo.
|
|
4
8
|
---
|
|
5
9
|
|
|
6
|
-
This guide
|
|
7
|
-
|
|
10
|
+
This guide walks you through setting up your first AI Gateway project, from
|
|
11
|
+
connecting a Git repository to making your first LLM request through Zuplo.
|
|
8
12
|
|
|
9
13
|
## Prerequisites
|
|
10
14
|
|
|
11
15
|
- A Zuplo account (sign up free at [zuplo.com](https://zuplo.com))
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
- An
|
|
16
|
+
- An account with a supported Git provider that can create repositories (this
|
|
17
|
+
guide uses GitHub)
|
|
18
|
+
- An API key for at least one LLM provider (OpenAI, Anthropic, Google, Mistral,
|
|
19
|
+
xAI, etc.)—or none at all, if you start with the free
|
|
20
|
+
[Zuplo Demo provider](./providers.mdx#zuplo-demo)
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
<Stepper>
|
|
17
23
|
|
|
18
|
-
1.
|
|
19
|
-
2. Navigate to **Projects**
|
|
20
|
-
3. Click **New Project**
|
|
21
|
-
4. Click **AI or MCP Gateway** at the bottom of the dialog
|
|
22
|
-
5. Give your project a name (for example, "MyCompany AI Gateway")
|
|
23
|
-
6. Click **Create Project**
|
|
24
|
+
1. **Create an AI Gateway project**
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
Log into the [Zuplo Portal](https://portal.zuplo.com), navigate to
|
|
27
|
+
**Projects**, and click **New Project**. Choose **Configure an AI gateway**,
|
|
28
|
+
give your project a name (for example, "MyCompany AI Gateway"), and click
|
|
29
|
+
**Create Project**.
|
|
27
30
|
|
|
28
|
-
|
|
31
|
+
2. **Connect the project to a Git repository**
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
Your AI Gateway deploys from source control, so the first step after creating
|
|
34
|
+
the project is connecting it to a repository. The project shows a **Let's Get
|
|
35
|
+
You Deployed** screen until a repository is connected.
|
|
33
36
|
|
|
34
|
-
|
|
37
|
+
Zuplo supports GitHub, GitLab, Bitbucket, and Azure DevOps. This guide uses
|
|
38
|
+
GitHub, which is the only provider with automatic deployments—see
|
|
39
|
+
[Source Control and Deployment](../concepts/source-control-and-deployment.mdx)
|
|
40
|
+
for the other providers, which deploy through the Zuplo CLI in your own CI/CD
|
|
41
|
+
pipeline.
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
6. Click **Create**
|
|
43
|
+
With GitHub, click **Create New Repo** to open GitHub with the repository
|
|
44
|
+
name prefilled, create the repository, then return to the Zuplo Portal and
|
|
45
|
+
select the repository to connect it. Zuplo adds the gateway's source to the
|
|
46
|
+
repository and deploys it. After that, pushes to your default branch deploy
|
|
47
|
+
to production.
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
To work with the gateway's source later—for example, to add
|
|
50
|
+
[custom policies](./custom-policies.mdx)—clone the repository:
|
|
44
51
|
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
```bash
|
|
53
|
+
git clone https://github.com/your-org/your-gateway-repo.git
|
|
54
|
+
```
|
|
47
55
|
|
|
48
|
-
|
|
56
|
+
:::note
|
|
49
57
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- Mistral (for Mistral models)
|
|
54
|
-
- xAI (for Grok models)
|
|
58
|
+
If your default branch requires pull requests, Zuplo pushes the gateway
|
|
59
|
+
source to a setup branch and shows you a pull request to merge. The project
|
|
60
|
+
finishes connecting once the pull request lands on the default branch.
|
|
55
61
|
|
|
56
|
-
|
|
57
|
-
capabilities, including OpenAI-compatible custom providers.
|
|
62
|
+
:::
|
|
58
63
|
|
|
59
|
-
|
|
64
|
+
See [Source Control](./source-control.mdx) for what the repository contains
|
|
65
|
+
and how deployments work.
|
|
60
66
|
|
|
61
|
-
|
|
62
|
-
you're starting solo, you'll need at least one team.
|
|
67
|
+
3. **Configure a provider**
|
|
63
68
|
|
|
64
|
-
|
|
69
|
+
Providers are the LLM services (like OpenAI or Anthropic) that your apps use.
|
|
70
|
+
You configure these once as an administrator, and your team members use them
|
|
71
|
+
without needing direct access to provider API keys.
|
|
65
72
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
- **Budget Limit**: Maximum spend per day (for example, $1,000)
|
|
73
|
-
- **Rate Limits**: Request limits if needed
|
|
73
|
+
Open
|
|
74
|
+
[**Settings → AI Providers**](https://portal.zuplo.com/+/account/project/ai/settings/data-models)
|
|
75
|
+
and click **Add Provider**. Select your AI provider (for example,
|
|
76
|
+
**OpenAI**), paste your provider's API key, and select which models to make
|
|
77
|
+
available. The **Provider Name** field fills in automatically based on the
|
|
78
|
+
provider you selected—`openai`, for example. Click **Create**.
|
|
74
79
|
|
|
75
|
-
|
|
80
|
+
:::caution{title="The provider name becomes the model prefix"}
|
|
76
81
|
|
|
77
|
-
|
|
82
|
+
Apps reference this provider's models as `providerName/model`, so the
|
|
83
|
+
provider name is the prefix in every model string—a provider named `openai`
|
|
84
|
+
serves `openai/gpt-5-mini`. The pre-filled name is usually what you want. To
|
|
85
|
+
use your own, set it now—the name is permanent after creation—and keep it
|
|
86
|
+
short and lowercase.
|
|
78
87
|
|
|
79
|
-
|
|
80
|
-
2. Name the team (for example, "Engineering Team", "Credit Team")
|
|
81
|
-
3. Choose an icon
|
|
82
|
-
4. Set team-specific limits by clicking on **Settings**:
|
|
83
|
-
- Daily budgets that are equal to or less than the parent team's limit
|
|
84
|
-
- Example: If root is $1,000/day, a sub-team might be $500/day
|
|
85
|
-
5. Click **Save Changes**
|
|
88
|
+
:::
|
|
86
89
|
|
|
87
|
-
|
|
90
|
+
Repeat for additional providers. See [AI Providers](./providers.mdx) for the
|
|
91
|
+
full list of supported providers, including OpenAI-compatible custom
|
|
92
|
+
providers.
|
|
88
93
|
|
|
89
|
-
|
|
90
|
-
Gateway. Each app gets its own unique URL and API key.
|
|
94
|
+
4. **Create a team**
|
|
91
95
|
|
|
92
|
-
|
|
96
|
+
Teams organize users and carry hierarchical budget controls and policy
|
|
97
|
+
templates. Even if you're starting solo, you need at least one team.
|
|
93
98
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
- **Provider**: Choose your LLM provider (for example, OpenAI)
|
|
100
|
-
- **Completions**: Select the model for chat completions (for example,
|
|
101
|
-
GPT-4o)
|
|
102
|
-
- **Embeddings**: Select the model for embeddings (optional)
|
|
103
|
-
3. Set application-level budgets:
|
|
104
|
-
- **Daily Limit**: (for example, $1/day for a hackathon project)
|
|
105
|
-
- **Monthly Limit**: (for example, $10/month)
|
|
106
|
-
4. Enable **Semantic Caching** (optional):
|
|
107
|
-
- Caches similar prompts to reduce costs and improve performance
|
|
108
|
-
- Best for applications with repeated queries
|
|
109
|
-
5. Click **Create App**
|
|
99
|
+
Open the **Teams** tab and click **Create Team**. Name your team (for
|
|
100
|
+
example, "Root" or your company name), choose an icon, and click **Create
|
|
101
|
+
Team**. To set organization-wide spending limits, open the gateway's
|
|
102
|
+
**Settings → Usage Limits**; for team-specific limits, use the team's **Usage
|
|
103
|
+
& Limits** tab. See [Usage Limits](./usage-limits.mdx).
|
|
110
104
|
|
|
111
|
-
|
|
105
|
+
5. **Create an app**
|
|
112
106
|
|
|
113
|
-
|
|
107
|
+
Apps represent individual projects or services that call the AI Gateway. Each
|
|
108
|
+
app gets its own unique URL and API key.
|
|
114
109
|
|
|
115
|
-
|
|
116
|
-
|
|
110
|
+
Open the **Apps** tab and click **Create App**. Give the app a descriptive
|
|
111
|
+
name (for example, "Tennis Chat") and select the team that owns it. That's
|
|
112
|
+
the whole dialog—models, budgets, and other behavior are configured on the
|
|
113
|
+
app's policy chain in the next step.
|
|
117
114
|
|
|
118
|
-
|
|
115
|
+
:::tip
|
|
119
116
|
|
|
120
|
-
|
|
121
|
-
|
|
117
|
+
If the app's team has a policy template, the new app starts with the
|
|
118
|
+
template's policy chain already in place. See
|
|
119
|
+
[Policy Templates](./policy-templates.mdx).
|
|
122
120
|
|
|
123
|
-
|
|
124
|
-
[Node.js OpenAI SDK](https://platform.openai.com/docs/libraries/node-js-library)
|
|
125
|
-
and that you have executed `npm install openai`.
|
|
121
|
+
:::
|
|
126
122
|
|
|
127
|
-
|
|
123
|
+
6. **Review the app's policy chain**
|
|
124
|
+
|
|
125
|
+
The portal opens the app's **Policies** tab, which shows the app's policy
|
|
126
|
+
chain—the ordered list of policies that run on each request. No policy is
|
|
127
|
+
required: an app with an empty chain works immediately, and each request
|
|
128
|
+
picks its own model as `providerName/model`, from any model your providers
|
|
129
|
+
expose.
|
|
130
|
+
|
|
131
|
+
To restrict that, add the **Model Filtering** policy and give it an allow
|
|
132
|
+
list such as `openai/gpt-5-mini`. Requests may then use only listed models,
|
|
133
|
+
and the first entry becomes the default when a request omits `model`.
|
|
134
|
+
|
|
135
|
+
:::caution{title="An unrestricted app can reach every model you configured"}
|
|
136
|
+
|
|
137
|
+
Without Model Filtering, an app may call any model available through the
|
|
138
|
+
providers assigned to its team, including expensive ones. Add Model Filtering
|
|
139
|
+
for any app that should be limited to a specific set.
|
|
140
|
+
|
|
141
|
+
:::
|
|
142
|
+
|
|
143
|
+
This is also where you add budgets, semantic caching, guardrails, and any
|
|
144
|
+
custom policies. Changes to the chain apply within about a minute—no redeploy
|
|
145
|
+
needed. See [Policy Chains](./policy-chains.mdx).
|
|
146
|
+
|
|
147
|
+
7. **Get the app's URL and API key**
|
|
148
|
+
|
|
149
|
+
The app page shows its **API URL** and **API Key** at the top right. The API
|
|
150
|
+
URL is the gateway's hostname plus the app's ID—for example
|
|
151
|
+
`https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e`.
|
|
152
|
+
Copy both rather than constructing them.
|
|
153
|
+
|
|
154
|
+
Client libraries expect a base URL ending in `/v1`, so append it: the OpenAI
|
|
155
|
+
SDK examples below use
|
|
156
|
+
`https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1`
|
|
157
|
+
as a stand-in, and requests land on paths like `/v1/chat/completions`.
|
|
158
|
+
|
|
159
|
+
:::note
|
|
160
|
+
|
|
161
|
+
The gateway checks the key only after you add the
|
|
162
|
+
[authentication policy](./policy-chains.mdx#authentication) to the route or
|
|
163
|
+
to the app's chain. Until then the gateway identifies the app from the
|
|
164
|
+
`{app_id}` segment of the URL and accepts the request without a key. The
|
|
165
|
+
examples below send the key so they keep working once you add the policy.
|
|
166
|
+
|
|
167
|
+
:::
|
|
168
|
+
|
|
169
|
+
Export the key so the samples below can read it:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
export ZUPLO_APP_API_KEY="<the API key from the app page>"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
8. **Send your first request from the Playground**
|
|
176
|
+
|
|
177
|
+
The app's **Playground** tab chats with the app's own gateway URL and API
|
|
178
|
+
key, so it exercises the same policy chain your code will hit—without wiring
|
|
179
|
+
up a client first.
|
|
180
|
+
|
|
181
|
+
Pick a model from the selector, optionally set a system prompt, and send a
|
|
182
|
+
message. The tab shows the cURL for the next request, and **Copy cURL** puts
|
|
183
|
+
it on your clipboard to run in a terminal or adapt it for your client. Expand
|
|
184
|
+
any reply to inspect the request and the raw response.
|
|
185
|
+
|
|
186
|
+
</Stepper>
|
|
187
|
+
|
|
188
|
+
## Integrate with your own code
|
|
189
|
+
|
|
190
|
+
Once the Playground works, configure your own code with the same URL and key.
|
|
191
|
+
|
|
192
|
+
These examples use the official
|
|
193
|
+
[Node.js OpenAI SDK](https://platform.openai.com/docs/libraries/node-js-library);
|
|
194
|
+
run `npm install openai` first. For other clients, see the integration guides
|
|
195
|
+
for the [OpenAI SDK](./integrations/openai.mdx),
|
|
196
|
+
[AI SDK](./integrations/ai-sdk.mdx), and
|
|
197
|
+
[LangChain](./integrations/langchain.mdx).
|
|
198
|
+
|
|
199
|
+
### Before: direct provider integration (sample.mjs)
|
|
128
200
|
|
|
129
201
|
```javascript
|
|
130
202
|
import OpenAI from "openai";
|
|
@@ -135,26 +207,27 @@ const openai = new OpenAI({
|
|
|
135
207
|
});
|
|
136
208
|
|
|
137
209
|
const completion = await openai.chat.completions.create({
|
|
138
|
-
model: "gpt-
|
|
210
|
+
model: "gpt-5-mini",
|
|
139
211
|
messages: [{ role: "user", content: "Hello!" }],
|
|
140
212
|
});
|
|
141
213
|
|
|
142
214
|
console.log(completion.choices[0].message.content);
|
|
143
215
|
```
|
|
144
216
|
|
|
145
|
-
### After:
|
|
217
|
+
### After: using the Zuplo AI Gateway (sample.mjs)
|
|
146
218
|
|
|
147
219
|
```javascript
|
|
148
220
|
import OpenAI from "openai";
|
|
149
221
|
|
|
150
222
|
// New approach - using Zuplo AI Gateway
|
|
151
223
|
const openai = new OpenAI({
|
|
152
|
-
apiKey: process.env.
|
|
153
|
-
baseURL:
|
|
224
|
+
apiKey: process.env.ZUPLO_APP_API_KEY,
|
|
225
|
+
baseURL:
|
|
226
|
+
"https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1",
|
|
154
227
|
});
|
|
155
228
|
|
|
156
229
|
const completion = await openai.chat.completions.create({
|
|
157
|
-
model: "gpt-
|
|
230
|
+
model: "openai/gpt-5-mini",
|
|
158
231
|
messages: [{ role: "user", content: "Hello!" }],
|
|
159
232
|
});
|
|
160
233
|
|
|
@@ -163,35 +236,39 @@ console.log(completion.choices[0].message.content);
|
|
|
163
236
|
|
|
164
237
|
Run the example with `node sample.mjs`.
|
|
165
238
|
|
|
166
|
-
### What
|
|
239
|
+
### What changed?
|
|
167
240
|
|
|
168
|
-
1. **URL**: Replace your provider's URL with your
|
|
169
|
-
|
|
170
|
-
|
|
241
|
+
1. **URL**: Replace your provider's URL with your app's gateway URL from the app
|
|
242
|
+
page
|
|
243
|
+
2. **API Key**: Use your app's API key instead of the provider's key—the gateway
|
|
244
|
+
checks it once the authentication policy applies
|
|
245
|
+
3. **Model**: Reference models as `providerName/model` so the gateway knows
|
|
246
|
+
which provider to route to
|
|
247
|
+
4. **Everything else stays the same**: The request format remains compatible
|
|
171
248
|
with OpenAI's API
|
|
172
249
|
|
|
173
|
-
## Verify
|
|
250
|
+
## Verify your setup
|
|
174
251
|
|
|
175
|
-
### Make
|
|
252
|
+
### Make your first request
|
|
176
253
|
|
|
177
|
-
Send a test request through your gateway:
|
|
254
|
+
Send a test request through your gateway, using your app's URL and API key:
|
|
178
255
|
|
|
179
256
|
```bash
|
|
180
|
-
curl https://
|
|
181
|
-
-H "Authorization: Bearer
|
|
257
|
+
curl https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1/chat/completions \
|
|
258
|
+
-H "Authorization: Bearer YOUR_APP_API_KEY" \
|
|
182
259
|
-H "Content-Type: application/json" \
|
|
183
260
|
-d '{
|
|
184
|
-
"model": "gpt-
|
|
261
|
+
"model": "openai/gpt-5-mini",
|
|
185
262
|
"messages": [{"role": "user", "content": "Hello, world!"}]
|
|
186
263
|
}'
|
|
187
264
|
```
|
|
188
265
|
|
|
189
|
-
### Check
|
|
266
|
+
### Check your dashboard
|
|
190
267
|
|
|
191
268
|
1. Open the [**Apps**](https://portal.zuplo.com/+/account/project/ai/apps) tab
|
|
192
269
|
of your AI Gateway project
|
|
193
270
|
2. Click on your app
|
|
194
|
-
3. Click on **Dashboard** to view:
|
|
271
|
+
3. Click on the app's **Dashboard** tab to view:
|
|
195
272
|
- Request count
|
|
196
273
|
- Token usage
|
|
197
274
|
- Time to first byte
|
|
@@ -200,31 +277,23 @@ curl https://your-ai-gateway-url.zuplo.app/v1/chat/completions \
|
|
|
200
277
|
You should see your test request appear with token usage and performance
|
|
201
278
|
metrics.
|
|
202
279
|
|
|
203
|
-
## Next
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
- **Solution**: Check that sub-team limits don't exceed available budget from
|
|
225
|
-
parent team
|
|
226
|
-
|
|
227
|
-
**Issue**: Semantic caching not working
|
|
228
|
-
|
|
229
|
-
- **Solution**: Ensure caching is enabled in your application settings and
|
|
230
|
-
prompts are similar enough to match
|
|
280
|
+
## Next steps
|
|
281
|
+
|
|
282
|
+
- [Policy Chains](./policy-chains.mdx): add budgets, semantic caching, and
|
|
283
|
+
guardrails to your app's chain
|
|
284
|
+
- [Custom Policies](./custom-policies.mdx): write your own policy and add it to
|
|
285
|
+
an app's chain
|
|
286
|
+
- [Policy Templates](./policy-templates.mdx): give every new app in a team a
|
|
287
|
+
consistent starting chain
|
|
288
|
+
- [Usage Limits](./usage-limits.mdx): set spending limits for the gateway,
|
|
289
|
+
teams, and apps
|
|
290
|
+
|
|
291
|
+
## Common issues
|
|
292
|
+
|
|
293
|
+
| Symptom | Fix |
|
|
294
|
+
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
295
|
+
| "Authentication failed" error | Verify you're using your app's API key, not your provider's key. This error appears only when the authentication policy applies |
|
|
296
|
+
| 404 "Unsupported AI Gateway endpoint" | The path must end with a supported `/v1/...` operation—usually the URL is missing its `/v1` segment. Use the app's API URL plus `/v1/chat/completions`, for example |
|
|
297
|
+
| 400 error asking for `providerName/model` | Prefix the model with the provider name configured in the portal—`openai/gpt-5-mini`, not `gpt-5-mini` |
|
|
298
|
+
| 403 error listing the allowed models | The app's Model Filtering policy doesn't include the requested model; add it on the app's Policies tab or use a listed one |
|
|
299
|
+
| Budget limit reached immediately | Check the limits at every level—gateway, team, and the app's Budgets and Costs policy—since any level's limit blocks the request |
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: AI SDK
|
|
3
3
|
sidebar_label: AI SDK
|
|
4
|
+
description:
|
|
5
|
+
Route AI SDK requests through the Zuplo AI Gateway by pointing each provider's
|
|
6
|
+
base URL at your app's gateway URL and referencing models as
|
|
7
|
+
providerName/model.
|
|
4
8
|
---
|
|
5
9
|
|
|
6
10
|
The [AI SDK](https://ai-sdk.dev/) is a free open-source library that gives you
|
|
@@ -10,32 +14,47 @@ community supported providers being added regularly.
|
|
|
10
14
|
|
|
11
15
|
## Prerequisites
|
|
12
16
|
|
|
13
|
-
In order to use the AI Gateway with any AI SDK powered
|
|
14
|
-
|
|
17
|
+
In order to use the AI Gateway with any AI SDK powered app you will need to
|
|
18
|
+
complete these steps first:
|
|
15
19
|
|
|
16
20
|
<Stepper>
|
|
17
21
|
|
|
18
|
-
1. Create a [new provider](
|
|
19
|
-
|
|
22
|
+
1. Create a [new provider](../managing-providers.mdx) in the AI Gateway for the
|
|
23
|
+
provider you want to use with AI SDK
|
|
20
24
|
|
|
21
|
-
2. [Set up a new team](
|
|
25
|
+
2. [Set up a new team](../managing-teams.mdx)
|
|
22
26
|
|
|
23
|
-
3. Create a [new app](
|
|
24
|
-
|
|
27
|
+
3. Create a [new app](../managing-apps.mdx) to use specifically with AI SDK and
|
|
28
|
+
assign it to the team you created
|
|
25
29
|
|
|
26
|
-
4. Copy the API
|
|
30
|
+
4. Copy the **API URL** and **API Key** shown at the top of the app page
|
|
27
31
|
|
|
28
32
|
</Stepper>
|
|
29
33
|
|
|
30
34
|
## Configure the AI SDK
|
|
31
35
|
|
|
32
36
|
To route all AI SDK requests through Zuplo instead of directly to the API of the
|
|
33
|
-
chosen provider, you must set
|
|
34
|
-
|
|
37
|
+
chosen provider, you must set `baseURL` in the SDK configuration to point to
|
|
38
|
+
your app's API URL with `/v1` appended. The app page in the Zuplo Portal shows
|
|
39
|
+
the URL, which ends in the app's ID.
|
|
35
40
|
|
|
36
41
|
Additionally, you will need to change the value of `apiKey` to the API key of
|
|
37
42
|
the app you have configured in Zuplo.
|
|
38
43
|
|
|
44
|
+
Models are referenced as `providerName/model`, where `providerName` is the
|
|
45
|
+
provider name configured in your gateway. By default an app can reach any model
|
|
46
|
+
offered by the providers assigned to its [team](../managing-teams.mdx). To limit
|
|
47
|
+
it to a curated set, add the [Model Filtering](../policies/model-filtering.mdx)
|
|
48
|
+
policy to the app—it applies separate rules to completions (`generateText`,
|
|
49
|
+
`streamText`) and embeddings (`embed`), and rejects a capability it doesn't
|
|
50
|
+
configure.
|
|
51
|
+
|
|
52
|
+
Each provider package appends its own operation path to `baseURL`, so pick the
|
|
53
|
+
model factory that targets an endpoint the gateway serves:
|
|
54
|
+
`/v1/chat/completions` for OpenAI-compatible requests, `/v1/messages` for
|
|
55
|
+
Anthropic, `/v1/embeddings`, and `/v1/responses` for OpenAI only. The examples
|
|
56
|
+
below use the right factory for each provider.
|
|
57
|
+
|
|
39
58
|
### OpenAI
|
|
40
59
|
|
|
41
60
|
```typescript
|
|
@@ -44,43 +63,45 @@ import { generateText } from "ai";
|
|
|
44
63
|
|
|
45
64
|
const openai = createOpenAI({
|
|
46
65
|
apiKey: process.env.ZUPLO_AI_GATEWAY_API_KEY,
|
|
47
|
-
baseURL:
|
|
66
|
+
baseURL:
|
|
67
|
+
"https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1",
|
|
48
68
|
});
|
|
49
69
|
|
|
50
70
|
const { text } = await generateText({
|
|
51
|
-
model: openai.chat("gpt-
|
|
71
|
+
model: openai.chat("openai/gpt-5-mini"),
|
|
52
72
|
prompt: "Write a one-sentence bedtime story about a unicorn.",
|
|
53
73
|
});
|
|
54
74
|
```
|
|
55
75
|
|
|
56
76
|
### Anthropic
|
|
57
77
|
|
|
78
|
+
Pass the app's API key as `authToken`, not `apiKey`. The provider sends `apiKey`
|
|
79
|
+
as the `x-api-key` header, which the gateway doesn't read, while `authToken` is
|
|
80
|
+
sent as `Authorization: Bearer`. Setting both throws an `InvalidArgumentError`.
|
|
81
|
+
|
|
58
82
|
```typescript
|
|
59
83
|
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
60
84
|
import { generateText } from "ai";
|
|
61
85
|
|
|
62
86
|
const anthropic = createAnthropic({
|
|
63
|
-
|
|
64
|
-
baseURL:
|
|
65
|
-
|
|
66
|
-
headers: {
|
|
67
|
-
Authorization: `Bearer ${process.env.ZUPLO_AI_GATEWAY_API_KEY}`,
|
|
68
|
-
},
|
|
87
|
+
authToken: process.env.ZUPLO_AI_GATEWAY_API_KEY,
|
|
88
|
+
baseURL:
|
|
89
|
+
"https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1",
|
|
69
90
|
});
|
|
70
91
|
|
|
71
92
|
const { text } = await generateText({
|
|
72
|
-
model: anthropic("claude-sonnet-4-5-20250929"),
|
|
93
|
+
model: anthropic("anthropic/claude-sonnet-4-5-20250929"),
|
|
73
94
|
prompt: "Write a one-sentence bedtime story about a unicorn.",
|
|
74
95
|
});
|
|
75
96
|
```
|
|
76
97
|
|
|
77
98
|
### Google
|
|
78
99
|
|
|
79
|
-
The `@ai-sdk/google` provider speaks Gemini's native protocol: it
|
|
80
|
-
|
|
100
|
+
The `@ai-sdk/google` provider speaks Gemini's native protocol: it posts to a
|
|
101
|
+
`{model}:generateContent` path and authenticates with the `x-goog-api-key`
|
|
81
102
|
header, neither of which the AI Gateway serves. Use the
|
|
82
103
|
[OpenAI-compatible provider](https://ai-sdk.dev/providers/openai-compatible-providers)
|
|
83
|
-
instead
|
|
104
|
+
instead—the AI Gateway translates OpenAI-format requests to Google upstream.
|
|
84
105
|
|
|
85
106
|
```typescript
|
|
86
107
|
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
|
|
@@ -89,11 +110,12 @@ import { generateText } from "ai";
|
|
|
89
110
|
const gateway = createOpenAICompatible({
|
|
90
111
|
name: "zuplo-ai-gateway",
|
|
91
112
|
apiKey: process.env.ZUPLO_AI_GATEWAY_API_KEY,
|
|
92
|
-
baseURL:
|
|
113
|
+
baseURL:
|
|
114
|
+
"https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1",
|
|
93
115
|
});
|
|
94
116
|
|
|
95
117
|
const { text } = await generateText({
|
|
96
|
-
model: gateway("gemini-2.5-flash"),
|
|
118
|
+
model: gateway("google/gemini-2.5-flash"),
|
|
97
119
|
prompt: "Write a one-sentence bedtime story about a unicorn.",
|
|
98
120
|
});
|
|
99
121
|
```
|
|
@@ -106,28 +128,49 @@ import { generateText } from "ai";
|
|
|
106
128
|
|
|
107
129
|
const mistral = createMistral({
|
|
108
130
|
apiKey: process.env.ZUPLO_AI_GATEWAY_API_KEY,
|
|
109
|
-
baseURL:
|
|
131
|
+
baseURL:
|
|
132
|
+
"https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1",
|
|
110
133
|
});
|
|
111
134
|
|
|
112
135
|
const { text } = await generateText({
|
|
113
|
-
model: mistral("mistral-large-latest"),
|
|
136
|
+
model: mistral("mistral/mistral-large-latest"),
|
|
114
137
|
prompt: "Write a one-sentence bedtime story about a unicorn.",
|
|
115
138
|
});
|
|
116
139
|
```
|
|
117
140
|
|
|
118
141
|
### xAI
|
|
119
142
|
|
|
143
|
+
Call `xai.chat(...)` rather than `xai(...)`. The bare callable targets xAI's
|
|
144
|
+
Responses API, and the gateway serves `/v1/responses` for the OpenAI provider
|
|
145
|
+
only—an xAI model sent there returns a `400`.
|
|
146
|
+
|
|
120
147
|
```typescript
|
|
121
148
|
import { createXai } from "@ai-sdk/xai";
|
|
122
149
|
import { generateText } from "ai";
|
|
123
150
|
|
|
124
151
|
const xai = createXai({
|
|
125
152
|
apiKey: process.env.ZUPLO_AI_GATEWAY_API_KEY,
|
|
126
|
-
baseURL:
|
|
153
|
+
baseURL:
|
|
154
|
+
"https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1",
|
|
127
155
|
});
|
|
128
156
|
|
|
129
157
|
const { text } = await generateText({
|
|
130
|
-
model: xai("grok-4"),
|
|
158
|
+
model: xai.chat("xai/grok-4"),
|
|
131
159
|
prompt: "Write a one-sentence bedtime story about a unicorn.",
|
|
132
160
|
});
|
|
133
161
|
```
|
|
162
|
+
|
|
163
|
+
## Provider options the gateway doesn't forward
|
|
164
|
+
|
|
165
|
+
On the OpenAI-shaped endpoints (`/v1/chat/completions`, `/v1/embeddings`, and
|
|
166
|
+
`/v1/responses`) the gateway rebuilds the upstream request from a per-provider
|
|
167
|
+
parameter list instead of forwarding your body as-is. Standard AI SDK settings—
|
|
168
|
+
messages, `temperature`, `topP`, `maxOutputTokens`, `stopSequences`, `tools`,
|
|
169
|
+
`toolChoice`, `responseFormat`, `presencePenalty`, and `frequencyPenalty`—are
|
|
170
|
+
forwarded. Options outside that list are dropped without a warning. For example,
|
|
171
|
+
`seed` and `providerOptions.mistral.safePrompt` don't reach Mistral, and
|
|
172
|
+
`temperature` is capped at Mistral's maximum of `1`.
|
|
173
|
+
|
|
174
|
+
Anthropic is different: `/v1/messages` is a native passthrough, so
|
|
175
|
+
`@ai-sdk/anthropic` requests reach Anthropic unchanged apart from the model and
|
|
176
|
+
credential, which the gateway sets from your app configuration.
|