Integrations

AI SDK

The AI SDK is a free open-source library that gives you the tools you need to build AI-powered products. It's compatible with a large selection of providers and models, and has a large selection of additional community supported providers being added regularly.

Prerequisites

In order to use the AI Gateway with any AI SDK powered app you will need to complete these steps first:

  1. Create a new provider in the AI Gateway for the provider you want to use with AI SDK

  2. Set up a new pool

  3. Create a new app to use specifically with AI SDK and assign it to the pool you created

  4. Copy the API URL and API Key shown at the top of the app page

Configure the AI SDK

To route all AI SDK requests through Zuplo instead of directly to the API of the chosen provider, you must set baseURL in the SDK configuration to point to your app's API URL with /v1 appended. The app page in the Zuplo Portal shows the URL, which ends in the app's ID.

Additionally, you will need to change the value of apiKey to the API key of the app you have configured in Zuplo.

Models are referenced as providerName/model, where providerName is the provider name configured in your gateway. By default an app can reach any model offered by the providers configured for the Zuplo project. To limit it to a curated set, add the Model Filtering policy to the app—it applies separate rules to completions (generateText, streamText) and embeddings (embed), and rejects a capability it doesn't configure.

Each provider package appends its own operation path to baseURL, so pick the model factory that targets an endpoint the gateway serves: /v1/chat/completions for OpenAI-compatible requests, /v1/messages for Anthropic and other providers' Claude models, /v1/embeddings for every provider with embedding models, and /v1/responses for OpenAI and the other providers whose models serve it (see AI Providers for the matrix). The examples below use the right factory for each provider.

OpenAI

TypeScriptCode
import { createOpenAI } from "@ai-sdk/openai"; import { generateText } from "ai"; const openai = createOpenAI({ apiKey: process.env.ZUPLO_AI_GATEWAY_API_KEY, baseURL: "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1", }); const { text } = await generateText({ model: openai.chat("openai/gpt-6-luna"), prompt: "Write a one-sentence bedtime story about a unicorn.", });

Anthropic

Pass the app's API key as authToken, not apiKey. The provider sends apiKey as the x-api-key header, which the gateway doesn't read, while authToken is sent as Authorization: Bearer. Setting both throws an InvalidArgumentError.

TypeScriptCode
import { createAnthropic } from "@ai-sdk/anthropic"; import { generateText } from "ai"; const anthropic = createAnthropic({ authToken: process.env.ZUPLO_AI_GATEWAY_API_KEY, baseURL: "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1", }); const { text } = await generateText({ model: anthropic("anthropic/claude-sonnet-5"), prompt: "Write a one-sentence bedtime story about a unicorn.", });

Google

The @ai-sdk/google provider speaks Gemini's native protocol: it posts to a {model}:generateContent path and authenticates with the x-goog-api-key header, neither of which the AI Gateway serves. Use the OpenAI-compatible provider instead—the AI Gateway translates OpenAI-format requests to Google upstream.

TypeScriptCode
import { createOpenAICompatible } from "@ai-sdk/openai-compatible"; import { generateText } from "ai"; const gateway = createOpenAICompatible({ name: "zuplo-ai-gateway", apiKey: process.env.ZUPLO_AI_GATEWAY_API_KEY, baseURL: "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1", }); const { text } = await generateText({ model: gateway("google/gemini-3.5-flash"), prompt: "Write a one-sentence bedtime story about a unicorn.", });

Mistral

TypeScriptCode
import { createMistral } from "@ai-sdk/mistral"; import { generateText } from "ai"; const mistral = createMistral({ apiKey: process.env.ZUPLO_AI_GATEWAY_API_KEY, baseURL: "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1", }); const { text } = await generateText({ model: mistral("mistral/mistral-large-latest"), prompt: "Write a one-sentence bedtime story about a unicorn.", });

xAI

Call xai.chat(...) rather than xai(...). The bare callable targets xAI's Responses API, and xAI's models do not serve /v1/responses through the gateway—an xAI model sent there returns a 400. The endpoint is capability-gated per model rather than restricted to one provider, so which models reach it is the matrix in AI Providers.

TypeScriptCode
import { createXai } from "@ai-sdk/xai"; import { generateText } from "ai"; const xai = createXai({ apiKey: process.env.ZUPLO_AI_GATEWAY_API_KEY, baseURL: "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1", }); const { text } = await generateText({ model: xai.chat("xai/grok-4.3"), prompt: "Write a one-sentence bedtime story about a unicorn.", });

Azure AI

Use @ai-sdk/azure. Set baseURL to your app's URL plus /v1, and pass the app's API key through tokenProvider—not apiKey. The provider sends apiKey as the api-key header, which the gateway doesn't read, so the request fails with a 401; tokenProvider puts the same key on Authorization: Bearer, which the gateway does read. Leave useDeploymentBasedUrls off—it moves the deployment into the path as /deployments/{id}/chat/completions, which isn't a gateway endpoint and returns a 404. To keep useDeploymentBasedUrls: true—or to authenticate with apiKey rather than tokenProvider—install the SDK path shim, a custom policy that rewrites the deployment path and maps the api-key header.

Reference models by deployment name, as providerName/deploymentName—see Azure serves deployments, not model names.

TypeScriptCode
import { createAzure } from "@ai-sdk/azure"; import { generateText } from "ai"; const appKey = process.env.ZUPLO_AI_GATEWAY_API_KEY; if (!appKey) { throw new Error("Set ZUPLO_AI_GATEWAY_API_KEY to the app's API key"); } const azure = createAzure({ baseURL: "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1", tokenProvider: async () => appKey, }); const { text } = await generateText({ model: azure.chat("azureai/my-gpt"), prompt: "Write a one-sentence bedtime story about a unicorn.", });

Call azure.chat(id) for chat completions and azure.textEmbeddingModel(id) for embeddings. The bare azure(id) callable targets the Responses API, which Azure serves for its OpenAI-compatible deployments, so that form works too.

For a Claude deployment on a Foundry resource, either call azure.chat("azureai/my-claude")—the gateway translates the chat completion to the Messages API—or use @ai-sdk/anthropic with authToken for the native Messages API:

TypeScriptCode
import { createAnthropic } from "@ai-sdk/anthropic"; import { generateText } from "ai"; const anthropic = createAnthropic({ authToken: process.env.ZUPLO_AI_GATEWAY_API_KEY, baseURL: "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1", }); const { text } = await generateText({ model: anthropic("azureai/my-claude"), prompt: "Write a one-sentence bedtime story about a unicorn.", });

Vertex AI

The @ai-sdk/google-vertex provider posts to Vertex's own publisher paths— {model}:generateContent for Gemini, and {model}:rawPredict for Claude on its /anthropic entry—neither of which the AI Gateway serves, so both return a 404. Use the OpenAI-compatible provider for Gemini and Model Garden models, and @ai-sdk/anthropic for Claude. For Claude, the SDK path shim can instead repoint @ai-sdk/google-vertex/anthropic onto /v1/messages; the Gemini entry can't be repointed.

Every Vertex model reference has two slashes, providerName/publisher/model—see Model references include the publisher prefix.

TypeScriptCode
import { createOpenAICompatible } from "@ai-sdk/openai-compatible"; import { generateText } from "ai"; const gateway = createOpenAICompatible({ name: "zuplo-ai-gateway", apiKey: process.env.ZUPLO_AI_GATEWAY_API_KEY, baseURL: "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1", }); const { text } = await generateText({ model: gateway("vertexai/google/gemini-3.7-flash"), prompt: "Write a one-sentence bedtime story about a unicorn.", });

The same provider embeds through textEmbeddingModel, which the gateway translates onto Vertex's embedding API:

TypeScriptCode
import { embedMany } from "ai"; const { embeddings } = await embedMany({ model: gateway.textEmbeddingModel("vertexai/google/gemini-embedding-2"), values: ["first document", "second document"], });

Claude models serve the native Messages API on Vertex, so use @ai-sdk/anthropic with authToken:

TypeScriptCode
import { createAnthropic } from "@ai-sdk/anthropic"; import { generateText } from "ai"; const anthropic = createAnthropic({ authToken: process.env.ZUPLO_AI_GATEWAY_API_KEY, baseURL: "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1", }); const { text } = await generateText({ model: anthropic("vertexai/anthropic/claude-haiku-4-5@20251001"), prompt: "Write a one-sentence bedtime story about a unicorn.", });

OpenRouter

Use @ai-sdk/openai. OpenRouter model references have two slashes, providerName/vendor/model—see Model references include the vendor prefix.

Which factory works depends on the model. The bare openai(id) callable targets the Responses API, which OpenRouter's Claude models don't serve through the gateway, so a Claude model sent that way returns a 400. Call openai.chat(id) for Claude—the gateway translates the chat completion to the Messages API—or use @ai-sdk/anthropic with authToken for the native Messages API. Every other chat model works with either form.

TypeScriptCode
import { createOpenAI } from "@ai-sdk/openai"; import { generateText } from "ai"; const openai = createOpenAI({ apiKey: process.env.ZUPLO_AI_GATEWAY_API_KEY, baseURL: "https://my-gateway-main-2e18f50.zuplo.app/config_fe0a04972d2848e0a94ae4b8bcd1497e/v1", }); const { text } = await generateText({ model: openai.chat("openrouter/anthropic/claude-sonnet-5"), prompt: "Write a one-sentence bedtime story about a unicorn.", });

Provider options the gateway doesn't forward

On the OpenAI-shaped endpoints (/v1/chat/completions, /v1/embeddings, and /v1/responses) the gateway rebuilds the upstream request from a per-provider parameter list instead of forwarding your body as-is. Standard AI SDK settings— messages, temperature, topP, maxOutputTokens, stopSequences, tools, toolChoice, responseFormat, presencePenalty, and frequencyPenalty—are forwarded. Options outside that list are dropped without a warning. For example, seed and providerOptions.mistral.safePrompt don't reach Mistral, and temperature is capped at Mistral's maximum of 1.

OpenRouter's model-fallback options are the exception: the gateway rejects models and route on chat completions, and fallbacks on /v1/messages, with a 400 rather than dropping them. See Using OpenRouter.

Anthropic is different: /v1/messages is a native passthrough, so @ai-sdk/anthropic requests reach Anthropic unchanged apart from the model and credential, which the gateway sets from your app configuration.

Last modified on