zuplo 7.7.8 → 7.7.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.
- package/docs/ai-gateway/azure-ai.mdx +466 -0
- package/docs/ai-gateway/bedrock-mantle.mdx +5 -1
- package/docs/ai-gateway/integrations/claude-code.mdx +166 -11
- package/docs/ai-gateway/managing-providers.mdx +10 -6
- package/docs/ai-gateway/overview.mdx +3 -2
- package/docs/ai-gateway/providers.mdx +39 -0
- package/docs/ai-gateway/universal-api.mdx +6 -6
- package/docs/ai-gateway/vertex-ai.mdx +6 -1
- package/docs/policies/_index.md +1 -1
- package/docs/policies/ai-gateway-auth-v2-inbound/doc.md +65 -3
- package/docs/policies/ai-gateway-auth-v2-inbound/schema.json +29 -4
- package/docs/policies/ai-gateway-configuration-executor-v2-inbound/doc.md +54 -30
- package/docs/policies/ai-gateway-fallback-model-v2-inbound/doc.md +6 -3
- package/docs/policies/ai-gateway-metering-v2-inbound/doc.md +32 -19
- package/docs/policies/ai-gateway-model-filtering-v2-inbound/doc.md +55 -0
- package/package.json +5 -5
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Using Azure AI
|
|
3
|
+
sidebar_label: Azure AI
|
|
4
|
+
description:
|
|
5
|
+
Serve Azure OpenAI and Microsoft Foundry models through one provider
|
|
6
|
+
configuration. Map each deployment to the model it serves so the gateway
|
|
7
|
+
prices usage.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Azure AI** serves models from your own Azure resource through one provider
|
|
11
|
+
configuration—one resource endpoint and one resource key. Adding it gives your
|
|
12
|
+
[apps](./apps.mdx) the models you have deployed, through the
|
|
13
|
+
[Universal API](./universal-api.mdx), on your Azure subscription and Azure
|
|
14
|
+
billing.
|
|
15
|
+
|
|
16
|
+
One provider type covers both kinds of Azure resource:
|
|
17
|
+
|
|
18
|
+
- An **Azure OpenAI** resource deploys OpenAI models and serves them on an
|
|
19
|
+
OpenAI-compatible API.
|
|
20
|
+
- A **Microsoft Foundry** resource serves that same API for every Foundry model
|
|
21
|
+
family—Grok, DeepSeek, Llama, Mistral, Phi, Kimi and more—_and_ serves Claude
|
|
22
|
+
on the native Anthropic Messages API.
|
|
23
|
+
|
|
24
|
+
Apps reference models as `providerName/model`, where `providerName` is the name
|
|
25
|
+
you give the provider configuration. A provider named `azureai` serves
|
|
26
|
+
`azureai/my-gpt`.
|
|
27
|
+
|
|
28
|
+
## Azure serves deployments, not model names
|
|
29
|
+
|
|
30
|
+
Of the ways Azure differs from other providers, this is the one that changes
|
|
31
|
+
what you put in the `model` field.
|
|
32
|
+
|
|
33
|
+
Other providers accept a published model ID. Azure resolves the `model` field
|
|
34
|
+
against the **deployments** in your resource, and you choose deployment names
|
|
35
|
+
when you create them. If you deploy `gpt-4.1-mini` under the name `my-gpt`, then
|
|
36
|
+
`my-gpt` is the only name Azure accepts for it.
|
|
37
|
+
|
|
38
|
+
The gateway forwards your deployment name to Azure unchanged, because it's the
|
|
39
|
+
only address Azure answers to. What the gateway needs to know separately is
|
|
40
|
+
which catalog model each deployment serves—that's what prices your usage.
|
|
41
|
+
|
|
42
|
+
:::caution{title="An unmapped deployment is rejected"}
|
|
43
|
+
|
|
44
|
+
The gateway prices a request by looking up the model name in its catalog. A
|
|
45
|
+
deployment named after something outside the catalog, such as `my-gpt`, matches
|
|
46
|
+
nothing—so the gateway returns **400** rather than serving a request it can't
|
|
47
|
+
bill. Azure would have served it, and the usage would have recorded no cost.
|
|
48
|
+
|
|
49
|
+
Map every deployment whose name differs from the model it serves. You do this
|
|
50
|
+
when you add or edit the provider. The error names the deployment and lists the
|
|
51
|
+
names that do work.
|
|
52
|
+
|
|
53
|
+
:::
|
|
54
|
+
|
|
55
|
+
Mapping is optional when it isn't needed. Deploy `gpt-4.1-mini` under the name
|
|
56
|
+
`gpt-4.1-mini`—the Azure portal's own default—and it already matches the
|
|
57
|
+
catalog.
|
|
58
|
+
|
|
59
|
+
### Deployment name rules
|
|
60
|
+
|
|
61
|
+
Azure accepts 2 to 64 characters of letters, digits, hyphens, underscores and
|
|
62
|
+
periods, and won't accept a name ending in a period. Leading hyphens and
|
|
63
|
+
periods, doubled periods, trailing hyphens and uppercase letters are all fine.
|
|
64
|
+
|
|
65
|
+
Deployment names match case-insensitively, so a deployment named `MyGpt` answers
|
|
66
|
+
to `mygpt`, and one named `my-gpt` answers to `MY-GPT`. Map each deployment once
|
|
67
|
+
using whichever spelling you prefer; requests in any casing resolve to it.
|
|
68
|
+
|
|
69
|
+
## How the gateway routes Azure AI models
|
|
70
|
+
|
|
71
|
+
A Foundry resource serves two API formats on the same host with the same
|
|
72
|
+
resource key:
|
|
73
|
+
|
|
74
|
+
- An **OpenAI-compatible API** at `/openai/v1`, serving every non-Claude model.
|
|
75
|
+
- The **native Anthropic Messages API** at `/anthropic/v1/messages`, serving the
|
|
76
|
+
Claude models.
|
|
77
|
+
|
|
78
|
+
<Diagram height="h-64">
|
|
79
|
+
<DiagramNode id="app">Your app</DiagramNode>
|
|
80
|
+
<DiagramNode id="gateway" variant="zuplo">
|
|
81
|
+
AI Gateway
|
|
82
|
+
</DiagramNode>
|
|
83
|
+
<DiagramGroup id="azure" label="Your Azure resource">
|
|
84
|
+
<DiagramNode id="openai-surface" variant="blue">
|
|
85
|
+
OpenAI-compatible API
|
|
86
|
+
</DiagramNode>
|
|
87
|
+
<DiagramNode id="messages-surface" variant="green">
|
|
88
|
+
Anthropic Messages API
|
|
89
|
+
</DiagramNode>
|
|
90
|
+
</DiagramGroup>
|
|
91
|
+
<DiagramEdge from="app" to="gateway" label="Universal API" />
|
|
92
|
+
<DiagramEdge
|
|
93
|
+
from="gateway"
|
|
94
|
+
to="openai-surface"
|
|
95
|
+
label="OpenAI-compatible models"
|
|
96
|
+
/>
|
|
97
|
+
<DiagramEdge from="gateway" to="messages-surface" label="Claude models" />
|
|
98
|
+
</Diagram>
|
|
99
|
+
|
|
100
|
+
The gateway's model catalog records which API serves each model, and routes
|
|
101
|
+
every request accordingly. Your clients always call your app's URL and never see
|
|
102
|
+
the Azure endpoint.
|
|
103
|
+
|
|
104
|
+
Claude needs a Foundry resource, because an Azure OpenAI resource can't deploy
|
|
105
|
+
Claude at all. Which endpoint host you configure doesn't affect this—a Foundry
|
|
106
|
+
resource serves Claude on either host family the provider accepts.
|
|
107
|
+
|
|
108
|
+
## Supported endpoints
|
|
109
|
+
|
|
110
|
+
| Endpoint | OpenAI-compatible models | Claude models |
|
|
111
|
+
| ---------------------- | ------------------------ | ------------- |
|
|
112
|
+
| `/v1/chat/completions` | ✅ Forwarded | ✅ Translated |
|
|
113
|
+
| `/v1/embeddings` | ✅ Embedding models | ❌ |
|
|
114
|
+
| `/v1/messages` | ❌ | ✅ Forwarded |
|
|
115
|
+
| `/v1/responses` | ✅ Models that serve it | ❌ |
|
|
116
|
+
|
|
117
|
+
**Forwarded** means the gateway sends your request on in the shape you wrote it.
|
|
118
|
+
**Translated** means it converts between two API shapes, which limits you to the
|
|
119
|
+
parameters listed below.
|
|
120
|
+
|
|
121
|
+
Streaming (`stream: true`) works on chat completions, messages, and responses.
|
|
122
|
+
|
|
123
|
+
The catalog carries three embedding models—`text-embedding-3-small`,
|
|
124
|
+
`text-embedding-3-large` and `text-embedding-ada-002`—so `/v1/embeddings` works
|
|
125
|
+
once you deploy one of them and map your deployment to it.
|
|
126
|
+
|
|
127
|
+
`/v1/responses` serves the OpenAI Responses API, buffered and streaming. Support
|
|
128
|
+
is **per deployed model**, not per resource: Azure serves Responses for
|
|
129
|
+
particular model and version combinations, and a deployment outside that set
|
|
130
|
+
answers `400` with `The requested operation is unsupported`—which is what an
|
|
131
|
+
embedding deployment on this endpoint returns. Check Azure's own Responses API
|
|
132
|
+
model list for your model and version before relying on it.
|
|
133
|
+
|
|
134
|
+
The management operations on a stored response are forwarded too:
|
|
135
|
+
|
|
136
|
+
| Operation | Does |
|
|
137
|
+
| ------------------------------------ | ------------------------------------- |
|
|
138
|
+
| `GET /v1/responses/{id}` | Retrieves the response |
|
|
139
|
+
| `GET /v1/responses/{id}/input_items` | Lists the input items of one response |
|
|
140
|
+
| `DELETE /v1/responses/{id}` | Deletes the response |
|
|
141
|
+
|
|
142
|
+
Two things they need. Send **`store: true`** on the create, since your resource
|
|
143
|
+
serves them only for a response it kept. And because these requests carry no
|
|
144
|
+
body, there is no `model` in them for the gateway to route on—it uses the app's
|
|
145
|
+
first configured completions model instead, so the app needs a
|
|
146
|
+
[Model Filtering](../policies/ai-gateway-model-filtering-v2-inbound.mdx) policy
|
|
147
|
+
whose completions allow list **starts with an OpenAI-compatible Azure
|
|
148
|
+
deployment**. Without one the gateway answers `400`, asking for preselected
|
|
149
|
+
routing, before reaching Azure.
|
|
150
|
+
|
|
151
|
+
A Claude deployment doesn't work in that first slot, even though the allow list
|
|
152
|
+
accepts it—Claude doesn't serve Responses at all, so the request still fails.
|
|
153
|
+
|
|
154
|
+
Azure also takes a moment to make a new response readable. A `GET` immediately
|
|
155
|
+
after a create can return `404` before it settles, so retry rather than treating
|
|
156
|
+
the first `404` as final.
|
|
157
|
+
|
|
158
|
+
Claude deployments don't serve Responses, so a Claude model on this endpoint
|
|
159
|
+
fails with a `400` error—use
|
|
160
|
+
[`/v1/messages`](#call-claude-models-on-the-messages-api) for those.
|
|
161
|
+
|
|
162
|
+
Claude models work on `/v1/chat/completions` through the gateway's translation
|
|
163
|
+
to the Messages API, which supports the core chat parameters: `messages`,
|
|
164
|
+
`max_tokens`, `temperature`, `top_p`, `stop`, and `stream`. For tool use or
|
|
165
|
+
other Anthropic-specific features, call
|
|
166
|
+
[`/v1/messages`](#call-claude-models-on-the-messages-api) instead.
|
|
167
|
+
|
|
168
|
+
This is the gateway's standard handling for Claude, not something specific to
|
|
169
|
+
Azure—[Bedrock Mantle](./bedrock-mantle.mdx#supported-endpoints-by-model-family)
|
|
170
|
+
serves Claude the same way. You get an ordinary `chat.completion` object back,
|
|
171
|
+
with `choices` and `prompt_tokens`/`completion_tokens`. The one visible trace of
|
|
172
|
+
the conversion is the response `id`, which keeps Anthropic's `msg_` prefix.
|
|
173
|
+
Azure's OpenAI-compatible models are forwarded instead of translated, so their
|
|
174
|
+
responses carry Azure's own fields, such as `content_filter_results`.
|
|
175
|
+
|
|
176
|
+
## Before you begin
|
|
177
|
+
|
|
178
|
+
You need:
|
|
179
|
+
|
|
180
|
+
- An Azure subscription with an Azure OpenAI or Microsoft Foundry resource. Note
|
|
181
|
+
the resource name—it's the first label of the resource's endpoint host.
|
|
182
|
+
- **At least one model deployed in that resource**, and its deployment name. The
|
|
183
|
+
gateway addresses deployments, so a resource with no deployments serves
|
|
184
|
+
nothing. Deploy models in the Azure portal under your resource's **Model
|
|
185
|
+
deployments**.
|
|
186
|
+
- One of the resource's API keys, from the resource's **Keys and Endpoint** page
|
|
187
|
+
in the Azure portal.
|
|
188
|
+
- An AI Gateway project in the Zuplo Portal.
|
|
189
|
+
- An AI Gateway [app](./apps.mdx) to call the models from. The app page shows
|
|
190
|
+
the app's API URL, and its API key lives on the app's **API Key** tab.
|
|
191
|
+
|
|
192
|
+
:::note
|
|
193
|
+
|
|
194
|
+
Use a resource key, not a Microsoft Entra ID token. Azure accepts both on its
|
|
195
|
+
own API, but the gateway stores long-lived resource keys, and the provider
|
|
196
|
+
dialog rejects a pasted Entra token—those expire within hours.
|
|
197
|
+
|
|
198
|
+
:::
|
|
199
|
+
|
|
200
|
+
### Deploying Claude on Foundry
|
|
201
|
+
|
|
202
|
+
Claude deployments carry extra requirements that Azure applies only to them, and
|
|
203
|
+
the failures are easy to misread:
|
|
204
|
+
|
|
205
|
+
- Azure asks for your **industry, organization name and country** when you
|
|
206
|
+
create an Anthropic-format deployment. Give a plain organization name;
|
|
207
|
+
punctuation in it has been enough to fail the deployment.
|
|
208
|
+
- Azure validates none of it up front. A deployment can report success, spend a
|
|
209
|
+
few minutes provisioning, and then land in a **Failed** state with an
|
|
210
|
+
internal-error message. Check the deployment's provisioning state before you
|
|
211
|
+
configure the provider, and delete a failed deployment before reusing its
|
|
212
|
+
name.
|
|
213
|
+
- If you deploy through the Azure REST API or a template rather than the portal,
|
|
214
|
+
use API version `2025-12-01` or later. Earlier versions silently ignore those
|
|
215
|
+
fields and then reject the request for not providing them.
|
|
216
|
+
|
|
217
|
+
## Add the provider
|
|
218
|
+
|
|
219
|
+
Adding or editing providers requires the **Edit** permission, granted to Zuplo
|
|
220
|
+
account and project **Admins**—see
|
|
221
|
+
[Managing Providers](./managing-providers.mdx).
|
|
222
|
+
|
|
223
|
+
<Stepper>
|
|
224
|
+
|
|
225
|
+
1. Open
|
|
226
|
+
[**Settings → AI Providers**](https://portal.zuplo.com/+/account/project/ai/settings/data-models)
|
|
227
|
+
in your AI Gateway project in the Zuplo Portal.
|
|
228
|
+
|
|
229
|
+
1. Click the **Add Provider** button.
|
|
230
|
+
|
|
231
|
+
1. In the **AI Provider** list, select **Azure AI** from the Default Providers
|
|
232
|
+
group.
|
|
233
|
+
|
|
234
|
+
1. Review the **Provider Name**, which fills in as `azureai` (a second
|
|
235
|
+
configuration becomes `azureai-2`). You can replace it with your own name,
|
|
236
|
+
but only now—the name is permanent after creation, and it's the prefix in
|
|
237
|
+
every model reference: a provider named `azureai` serves `azureai/my-gpt`.
|
|
238
|
+
|
|
239
|
+
1. In **Azure Resource Name**, enter your resource's name, such as
|
|
240
|
+
`my-resource`. Use the host family selector beside the field to pick
|
|
241
|
+
`openai.azure.com` or `services.ai.azure.com`, matching your resource's
|
|
242
|
+
endpoint. The gateway sends this provider's requests to
|
|
243
|
+
`https://<resource>.<host family>`.
|
|
244
|
+
|
|
245
|
+
1. In **API Key**, paste one of the resource's keys.
|
|
246
|
+
|
|
247
|
+
1. Select the models to enable, or click **Select All**. The picker shows
|
|
248
|
+
per-token prices, which the gateway uses to track cost per app. You can
|
|
249
|
+
change the selection later.
|
|
250
|
+
|
|
251
|
+
1. Under **Deployment Names**, click **Add deployment** for each deployment
|
|
252
|
+
whose name differs from the model it serves. Enter the deployment name, then
|
|
253
|
+
pick the model it serves from the list. Skip this for deployments already
|
|
254
|
+
named after their model.
|
|
255
|
+
|
|
256
|
+
1. Click **Create**.
|
|
257
|
+
|
|
258
|
+
</Stepper>
|
|
259
|
+
|
|
260
|
+
:::note
|
|
261
|
+
|
|
262
|
+
Saving provider settings triggers an automatic production deployment of your
|
|
263
|
+
gateway, because provider credentials are part of the deployed gateway. The
|
|
264
|
+
change is live once the deployment completes.
|
|
265
|
+
|
|
266
|
+
:::
|
|
267
|
+
|
|
268
|
+
When you edit the provider later—see
|
|
269
|
+
[Managing Providers](./managing-providers.mdx)—the **Azure Resource Name**, host
|
|
270
|
+
family and deployment mappings all stay editable, and you can replace the API
|
|
271
|
+
key. The **Provider Name** doesn't change.
|
|
272
|
+
|
|
273
|
+
:::caution{title="Which endpoint form to enter"}
|
|
274
|
+
|
|
275
|
+
Enter the resource name and pick a host family; don't paste a full URL. The
|
|
276
|
+
provider accepts the `openai.azure.com` and `services.ai.azure.com` families
|
|
277
|
+
only.
|
|
278
|
+
|
|
279
|
+
A Foundry resource also has a `cognitiveservices.azure.com` address, and that's
|
|
280
|
+
the one the Azure portal shows as the resource's endpoint. It isn't accepted
|
|
281
|
+
here—use the resource name with one of the two families above instead. The
|
|
282
|
+
resource is the same either way.
|
|
283
|
+
|
|
284
|
+
:::
|
|
285
|
+
|
|
286
|
+
## Verify the provider
|
|
287
|
+
|
|
288
|
+
Once the deployment completes, send a chat completions request to your app's
|
|
289
|
+
[Universal API](./universal-api.mdx) URL—shown at the top of the
|
|
290
|
+
[app page](./apps.mdx)—with the app's API key as the bearer token and one of
|
|
291
|
+
your deployments:
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
curl https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1/chat/completions \
|
|
295
|
+
-H "Authorization: Bearer $ZUPLO_APP_API_KEY" \
|
|
296
|
+
-H "Content-Type: application/json" \
|
|
297
|
+
-d '{
|
|
298
|
+
"model": "azureai/my-gpt",
|
|
299
|
+
"messages": [{ "role": "user", "content": "Say hi" }]
|
|
300
|
+
}'
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
The URL is a sample—replace it with your app's API URL plus
|
|
304
|
+
`/v1/chat/completions`, set `ZUPLO_APP_API_KEY` to the app's API key, and
|
|
305
|
+
substitute your own deployment name for `my-gpt`.
|
|
306
|
+
|
|
307
|
+
A `200` response confirms the provider works. If the request fails immediately
|
|
308
|
+
after you save the provider, the deployment may not have finished—retry before
|
|
309
|
+
debugging further.
|
|
310
|
+
|
|
311
|
+
## Call OpenAI-compatible models
|
|
312
|
+
|
|
313
|
+
Use any OpenAI client with your app's URL plus `/v1` as the base URL and the
|
|
314
|
+
app's API key:
|
|
315
|
+
|
|
316
|
+
```ts
|
|
317
|
+
import OpenAI from "openai";
|
|
318
|
+
|
|
319
|
+
const client = new OpenAI({
|
|
320
|
+
apiKey: process.env.ZUPLO_APP_API_KEY,
|
|
321
|
+
baseURL:
|
|
322
|
+
"https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1",
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
const response = await client.chat.completions.create({
|
|
326
|
+
model: "azureai/my-gpt",
|
|
327
|
+
messages: [{ role: "user", content: "Summarize this ticket." }],
|
|
328
|
+
});
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
The same call works with a Claude deployment—the gateway translates it to the
|
|
332
|
+
Messages API—within the [translation's parameter subset](#supported-endpoints).
|
|
333
|
+
|
|
334
|
+
## Call Claude models on the Messages API
|
|
335
|
+
|
|
336
|
+
Claude deployments on a Foundry resource serve the native
|
|
337
|
+
[Anthropic Messages API](./universal-api.mdx#supported-endpoints) at
|
|
338
|
+
`/v1/messages`. With the Anthropic SDK, set `baseURL` to the app's URL _without_
|
|
339
|
+
`/v1`—the SDK appends `/v1/messages` itself—and pass the app's API key as
|
|
340
|
+
`authToken`, not `apiKey`:
|
|
341
|
+
|
|
342
|
+
```ts
|
|
343
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
344
|
+
|
|
345
|
+
const client = new Anthropic({
|
|
346
|
+
baseURL:
|
|
347
|
+
"https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e",
|
|
348
|
+
authToken: process.env.ZUPLO_APP_API_KEY, // apiKey would send x-api-key, which the gateway ignores
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
const message = await client.messages.create({
|
|
352
|
+
model: "azureai/my-claude",
|
|
353
|
+
max_tokens: 1024,
|
|
354
|
+
messages: [{ role: "user", content: "Say hi" }],
|
|
355
|
+
});
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
The gateway forwards the request body to Azure verbatim, so tool use, system
|
|
359
|
+
prompts and streaming work as they do against Anthropic directly.
|
|
360
|
+
|
|
361
|
+
`anthropic-beta` headers are the exception. The gateway forwards the
|
|
362
|
+
long-context and prompt-caching betas and drops every other value, because Azure
|
|
363
|
+
rejects an unrecognized beta by failing the whole request. A client asking for a
|
|
364
|
+
different beta still gets an answer, without that feature.
|
|
365
|
+
|
|
366
|
+
## What the model field reports in responses
|
|
367
|
+
|
|
368
|
+
The `model` field in a response doesn't always say what you might expect, and
|
|
369
|
+
what it says depends on the model you called.
|
|
370
|
+
|
|
371
|
+
**Claude models and `/v1/responses` report your deployment name.** Everything
|
|
372
|
+
else reports Azure's own model ID, which usually carries a version date the
|
|
373
|
+
short name doesn't.
|
|
374
|
+
|
|
375
|
+
| Endpoint | Deployment `my-gpt` / `my-embed` / `my-claude` serves | `model` in the response |
|
|
376
|
+
| ---------------------- | ----------------------------------------------------- | ------------------------- |
|
|
377
|
+
| `/v1/chat/completions` | `gpt-4.1-mini` | `gpt-4.1-mini-2025-04-14` |
|
|
378
|
+
| `/v1/responses` | `gpt-4.1-mini` | `my-gpt` |
|
|
379
|
+
| `/v1/embeddings` | `text-embedding-3-small` | `text-embedding-3-small` |
|
|
380
|
+
| `/v1/messages` | `claude-haiku-4-5` | `my-claude` |
|
|
381
|
+
| `/v1/chat/completions` | `claude-haiku-4-5` | `my-claude` |
|
|
382
|
+
|
|
383
|
+
The same deployment reports two different values depending on the endpoint you
|
|
384
|
+
call it on: chat completions answers with Azure's dated ID, Responses with the
|
|
385
|
+
name you gave the deployment. That's Azure's own behavior on each surface, not
|
|
386
|
+
something the gateway changes.
|
|
387
|
+
|
|
388
|
+
A Claude model reports your deployment name on both endpoints—the native
|
|
389
|
+
Messages API and the chat completions translation—but for a different reason:
|
|
390
|
+
there the gateway builds the response itself and echoes back the model you asked
|
|
391
|
+
for.
|
|
392
|
+
|
|
393
|
+
One exception, if you stream Claude: the `message_start` event reports Azure's
|
|
394
|
+
ID (`claude-haiku-4-5-20251001`) rather than your deployment name, because the
|
|
395
|
+
gateway forwards each event as it arrives instead of rebuilding the response. So
|
|
396
|
+
the same request reports two different values depending on whether you streamed
|
|
397
|
+
it.
|
|
398
|
+
|
|
399
|
+
Treat this field as informational either way. If you need to know which
|
|
400
|
+
deployment served a request, use your own request metadata rather than parsing
|
|
401
|
+
this.
|
|
402
|
+
|
|
403
|
+
## Troubleshooting
|
|
404
|
+
|
|
405
|
+
**A request fails with a deployment-not-found error.** The `model` value after
|
|
406
|
+
the provider prefix must be a deployment name in your Azure resource, not a
|
|
407
|
+
published model ID. Check the deployment list in the Azure portal under your
|
|
408
|
+
resource's **Model deployments**, and confirm the deployment finished
|
|
409
|
+
provisioning.
|
|
410
|
+
|
|
411
|
+
**A request fails saying the deployment isn't mapped.** The deployment exists in
|
|
412
|
+
Azure, but the gateway can't tell which model it serves, so it can't price the
|
|
413
|
+
request. Edit the provider, add the deployment under **Deployment Names**, and
|
|
414
|
+
pick its model. If the deployment is named after its model, selecting that model
|
|
415
|
+
is enough. The error lists the names that currently work.
|
|
416
|
+
|
|
417
|
+
**The dialog rejects your endpoint.** Enter the resource name, not a URL, and
|
|
418
|
+
pick `openai.azure.com` or `services.ai.azure.com`. A Foundry resource's
|
|
419
|
+
`cognitiveservices.azure.com` address isn't accepted—use the resource name with
|
|
420
|
+
one of those two families. Resource names are 2 to 63 characters of lowercase
|
|
421
|
+
letters, digits and hyphens, starting and ending with a letter or digit.
|
|
422
|
+
|
|
423
|
+
**The dialog rejects your API key.** The gateway takes a resource key from the
|
|
424
|
+
resource's **Keys and Endpoint** page. A Microsoft Entra ID access token is
|
|
425
|
+
rejected—it expires within hours, so the connection would break the same day.
|
|
426
|
+
|
|
427
|
+
**A Claude model returns an error on an Azure OpenAI resource.** Only Foundry
|
|
428
|
+
resources deploy Claude. Confirm the deployment exists and is Anthropic-format,
|
|
429
|
+
and see [Deploying Claude on Foundry](#deploying-claude-on-foundry) for the
|
|
430
|
+
requirements Azure applies to those deployments.
|
|
431
|
+
|
|
432
|
+
**A `400` error names `/v1/responses`.** Two different causes, and the message
|
|
433
|
+
tells you which. If it names the provider or the endpoint, the deployment is a
|
|
434
|
+
**Claude** one—Claude doesn't serve Responses, so call
|
|
435
|
+
[`/v1/messages`](#call-claude-models-on-the-messages-api) instead, or
|
|
436
|
+
`/v1/chat/completions` for the translated form. If it says
|
|
437
|
+
`The requested operation is unsupported`, that came from Azure: the deployed
|
|
438
|
+
model doesn't serve Responses. Support is per model and version, so check
|
|
439
|
+
Azure's Responses API model list—an embedding deployment always fails this way.
|
|
440
|
+
|
|
441
|
+
**A `400` asks for preselected routing.** You called `GET` or `DELETE` on a
|
|
442
|
+
response, or listed its input items. Those requests carry no body, so there is
|
|
443
|
+
no `model` for the gateway to route on and it falls back to the app's first
|
|
444
|
+
configured completions model. Add a
|
|
445
|
+
[Model Filtering](../policies/ai-gateway-model-filtering-v2-inbound.mdx) policy
|
|
446
|
+
to the app with an **OpenAI-compatible** Azure deployment first in its
|
|
447
|
+
completions allow list. A Claude deployment in that slot still fails, since
|
|
448
|
+
Claude doesn't serve Responses.
|
|
449
|
+
|
|
450
|
+
**A model in the picker fails at request time.** The picker lists the full Azure
|
|
451
|
+
catalog, but a model only works once you deploy it in your resource, and model
|
|
452
|
+
availability varies by region and resource kind. Deploy the model, then map your
|
|
453
|
+
deployment name to it.
|
|
454
|
+
|
|
455
|
+
## Next steps
|
|
456
|
+
|
|
457
|
+
- [AI Providers](./providers.mdx)—the capability matrix across every supported
|
|
458
|
+
provider.
|
|
459
|
+
- [Universal API](./universal-api.mdx)—the endpoints every app serves and how
|
|
460
|
+
model references work.
|
|
461
|
+
- [Managing Providers](./managing-providers.mdx)—edit models, keys, and the
|
|
462
|
+
endpoint, and understand when changes deploy.
|
|
463
|
+
- [AI Gateway Apps](./apps.mdx)—create the apps that call your Azure-backed
|
|
464
|
+
models.
|
|
465
|
+
- [Model Filtering policy](../policies/ai-gateway-model-filtering-v2-inbound.mdx)—control
|
|
466
|
+
which models each app can call.
|
|
@@ -72,9 +72,13 @@ either way.
|
|
|
72
72
|
| ---------------------- | ---------------------------- | ------------- |
|
|
73
73
|
| `/v1/chat/completions` | ✅ Forwarded | ✅ Translated |
|
|
74
74
|
| `/v1/responses` | ✅ Models that serve it | ❌ |
|
|
75
|
-
| `/v1/messages` | ❌ | ✅
|
|
75
|
+
| `/v1/messages` | ❌ | ✅ Forwarded |
|
|
76
76
|
| `/v1/embeddings` | ❌ Mantle has no such models | ❌ |
|
|
77
77
|
|
|
78
|
+
**Forwarded** means the gateway sends your request on in the shape you wrote it.
|
|
79
|
+
**Translated** means it converts between two API shapes, which limits you to the
|
|
80
|
+
parameters listed below.
|
|
81
|
+
|
|
78
82
|
Streaming (`stream: true`) works on all three serving endpoints.
|
|
79
83
|
|
|
80
84
|
On the OpenAI-compatible side, endpoint support is per model, decided by AWS:
|