AI Gateway Provider

The AI Gateway provider connects you to models from multiple AI providers through a single interface. Instead of integrating with each provider separately, you can access OpenAI, Anthropic, Google, Meta, xAI, and other providers and their models.

Features

  • Access models from multiple providers without having to install additional provider modules/dependencies
  • Use the same code structure across different AI providers
  • Switch between models and providers easily
  • Automatic authentication when deployed on Vercel
  • View pricing information across providers
  • Observability for AI model usage through the Vercel dashboard

Setup

The Vercel AI Gateway provider is part of the AI SDK.

Basic Usage

For most use cases, you can use the AI Gateway directly with a model string:

// use plain model string with global provider
import { generateText } from 'ai';
const { text } = await generateText({
model: 'openai/gpt-5.4',
prompt: 'Hello world',
});
// use provider instance (requires version 5.0.36 or later)
import { generateText, gateway } from 'ai';
const { text } = await generateText({
model: gateway('openai/gpt-5.4'),
prompt: 'Hello world',
});

The AI SDK automatically uses the AI Gateway when you pass a model string in the creator/model-name format.

Provider Instance

The gateway provider instance is available from the ai package in version 5.0.36 and later.

You can also import the default provider instance gateway from ai:

import { gateway } from 'ai';

You may want to create a custom provider instance when you need to:

  • Set custom configuration options (API key, Vercel access token, base URL, headers)
  • Use the provider in a provider registry
  • Wrap the provider with middleware
  • Use different settings for different parts of your application

To create a custom provider instance, import createGateway from ai:

import { createGateway } from 'ai';
const gateway = createGateway({
apiKey: process.env.AI_GATEWAY_API_KEY ?? '',
});

You can use the following optional settings to customize the AI Gateway provider instance:

  • baseURL string

    Use a different URL prefix for API calls. The default prefix is https://ai-gateway.vercel.sh/v4/ai.

  • apiKey string

    API key or Vercel access token that is being sent using the Authorization header. It defaults to the AI_GATEWAY_API_KEY environment variable. Supports AI Gateway API keys, Vercel personal access tokens, and Vercel app access tokens.

  • teamIdOrSlug string

    Vercel team ID or slug used to scope model requests when authenticating with multi-team Vercel access tokens.

  • headers Record<string,string>

    Custom headers to include in the requests.

  • fetch (input: RequestInfo, init?: RequestInit) => Promise<Response>

    Custom fetch implementation. Defaults to the global fetch function. You can use it as a middleware to intercept requests, or to provide a custom fetch implementation for e.g. testing.

  • metadataCacheRefreshMillis number

    How frequently to refresh the metadata cache in milliseconds. Defaults to 5 minutes (300,000ms).

Authentication

The Gateway provider supports the following authentication methods:

API Key Authentication

Set your API key via environment variable:

AI_GATEWAY_API_KEY=your_api_key_here

Or pass it directly to the provider:

import { createGateway } from 'ai';
const gateway = createGateway({
apiKey: 'your_api_key_here',
});

Vercel Access Token Authentication for Model Requests

For dynamic runtime authentication of model requests, pass a Vercel personal access token or Vercel app access token to a custom Gateway provider instance:

import { createGateway } from 'ai';
const gateway = createGateway({
apiKey: 'your_vercel_access_token_here',
teamIdOrSlug: 'your-team', // required for multi-team tokens
});

apiKey takes precedence over AI_GATEWAY_API_KEY and OIDC.

Vercel access tokens with teamIdOrSlug are supported for model requests. Gateway helper methods such as getCredits, getSpendReport, and getGenerationInfo require an AI Gateway API key or OIDC authentication.

OIDC Authentication (Vercel Deployments)

When deployed to Vercel, the AI Gateway provider supports authenticating model requests using OIDC (OpenID Connect) tokens without API Keys.

How OIDC Authentication Works

  1. In Production/Preview Deployments:

    • OIDC authentication is automatically handled
    • No manual configuration needed
    • Tokens are automatically obtained and refreshed
  2. In Local Development:

    • First, install and authenticate with the Vercel CLI
    • Run vercel env pull to download your project's OIDC token locally
    • For automatic token management:
      • Use vercel dev to start your development server - this will handle token refreshing automatically
    • For manual token management:
      • If not using vercel dev, note that OIDC tokens expire after 12 hours
      • You'll need to run vercel env pull again to refresh the token before it expires

If an API key or Vercel access token is present (either passed directly or via environment), it will always be used instead of OIDC, even if invalid.

Read more about using OIDC tokens in the Vercel AI Gateway docs.

Bring Your Own Key (BYOK)

You can connect your own provider credentials to use with Vercel AI Gateway. This lets you use your existing provider accounts and access private resources.

To set up BYOK, add your provider credentials in your Vercel team's AI Gateway settings. Once configured, AI Gateway automatically uses your credentials. No code changes are needed.

For providers like Azure where you can use custom deployment names, you can configure model mappings to map gateway model slugs to your deployment names. See model mappings for details.

Learn more in the BYOK documentation.

Language Models

You can create language models using a provider instance. The first argument is the model ID in the format creator/model-name:

import { generateText } from 'ai';
const { text } = await generateText({
model: 'openai/gpt-5.4',
prompt: 'Explain quantum computing in simple terms',
});

AI Gateway language models can also be used in the streamText function and support structured data generation with Output (see AI SDK Core).

When an upstream provider reports a well-formed error after streaming has started, AI SDK Core exposes it as a StreamProviderError. Use its type, code, statusCode, and isRetryable metadata to classify the failure without inspecting the Gateway's serialized error payload.

Batch

Batch support is experimental and the API may change in patch releases.

AI Gateway supports durable text batches through experimental_startBatch, experimental_getBatchStatus, and experimental_getBatchResults. See Batch for the provider-agnostic workflow, and the AI Gateway batch processing guide for supported models, limits, and Gateway-specific behavior.

Pass a publicly reachable HTTPS webhookUrl when starting a batch to receive a terminal notification instead of polling. AI Gateway sends batch.completed, batch.failed, or batch.cancelled. The event contains terminal status information but not batch results. Completion webhooks are an AI Gateway capability; direct Anthropic and OpenAI batch providers return an unsupported warning when this option is provided.

start-batch.ts
import { randomUUID } from 'node:crypto';
import {
experimental_startBatch as startBatch,
type Experimental_BatchReference as BatchReference,
type GatewayProviderMetadata,
} from 'ai';
// The receiver uses this token to look up the expected batch and signing
// secret before trusting anything in the webhook body.
const token = randomUUID();
const model = 'anthropic/claude-haiku-4.5' as const;
// Reserve the token before starting so an early delivery finds a retryable
// pending record rather than an unknown callback.
await reserveBatchWebhook(token);
const batch = await startBatch({
requests: [
{
id: 'france',
type: 'text',
model,
prompt: 'What is the capital of France?',
},
{
id: 'germany',
type: 'text',
model,
prompt: 'What is the capital of Germany?',
},
],
providerOptions: {
gateway: { idempotencyKey: token },
},
webhookUrl: `https://example.com/api/batch-webhook?token=${token}`,
});
const gatewayMetadata = batch.providerMetadata?.gateway as
| GatewayProviderMetadata
| undefined;
const signingSecret = gatewayMetadata?.asyncJob?.webhookSigningSecret;
if (typeof signingSecret !== 'string') {
throw new Error('AI Gateway did not return a webhook signing secret.');
}
// Keep sensitive provider metadata out of the receiver queue and logs.
const batchReference = {
version: batch.version,
id: batch.id,
provider: batch.provider,
} satisfies BatchReference;
await completeBatchWebhookReservation(token, {
batch: batchReference,
signingSecret,
});

The signing secret is returned only in the start response. Reserve the callback token before submitting the batch, then persist the secret and minimal batch reference before the process exits. The stable providerOptions.gateway.idempotencyKey makes retrying an ambiguous start safe. Reuse the reserved token when retrying; do not generate a new one. Delete the reservation after a definitive start failure. While the reservation is still pending, the receiver should return a retryable response so an early delivery is sent again after setup completes.

The receiver must verify the x-ai-gateway-signature header against a bounded raw request body before trusting the event:

app/api/batch-webhook/route.ts
import { createHmac, timingSafeEqual } from 'node:crypto';
const MAX_AGE_SECONDS = 5 * 60;
const MAX_BODY_BYTES = 64 * 1024;
export async function POST(request: Request) {
const token = new URL(request.url).searchParams.get('token');
if (token == null) return new Response(null, { status: 401 });
const record = await loadBatchWebhook(token);
if (record == null) return new Response(null, { status: 401 });
if (record.state !== 'ready') return new Response(null, { status: 503 });
const declaredLength = request.headers.get('content-length');
if (declaredLength != null && Number(declaredLength) > MAX_BODY_BYTES) {
return new Response(null, { status: 413 });
}
const rawBody = await readBodyWithLimit(request, MAX_BODY_BYTES);
if (rawBody == null) return new Response(null, { status: 413 });
const signature = request.headers.get('x-ai-gateway-signature');
if (
signature == null ||
!verifySignature({
header: signature,
rawBody,
secret: record.signingSecret,
})
) {
return new Response(null, { status: 401 });
}
let event: { data?: { jobId?: string; status?: string } };
try {
event = JSON.parse(rawBody);
} catch {
return new Response(null, { status: 400 });
}
const jobId = event.data?.jobId;
const status = event.data?.status;
if (
jobId !== record.batch.id ||
(status !== 'cancelled' && status !== 'completed' && status !== 'failed')
) {
return new Response(null, { status: 401 });
}
// The header is not signed, so require it to match the signed event body.
const deliveryId = `${jobId}-${status}`;
if (request.headers.get('x-ai-gateway-idempotency-key') !== deliveryId) {
return new Response(null, { status: 401 });
}
await enqueueBatchResultFetch({
batch: record.batch,
deliveryId,
});
return new Response(null, { status: 204 });
}
async function readBodyWithLimit(request: Request, maxBytes: number) {
if (request.body == null) return '';
const reader = request.body.getReader();
const decoder = new TextDecoder();
let body = '';
let size = 0;
try {
while (true) {
const { done, value } = await reader.read();
if (done) return body + decoder.decode();
size += value.byteLength;
if (size > maxBytes) {
await reader.cancel();
return undefined;
}
body += decoder.decode(value, { stream: true });
}
} finally {
reader.releaseLock();
}
}
function verifySignature({
header,
rawBody,
secret,
}: {
header: string;
rawBody: string;
secret: string;
}) {
const timestamp = header.match(/(?:^|,)t=(\d+)/)?.[1];
const digest = header.match(/(?:^|,)v1=([0-9a-f]{64})(?:,|$)/)?.[1];
if (timestamp == null || digest == null) return false;
const expected = createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`, 'utf8')
.digest('hex');
const provided = Buffer.from(digest, 'hex');
const computed = Buffer.from(expected, 'hex');
if (provided.length !== computed.length) return false;
if (!timingSafeEqual(provided, computed)) return false;
return Math.abs(Date.now() / 1000 - Number(timestamp)) <= MAX_AGE_SECONDS;
}

The signature header has the form t=<unix seconds>,v1=<hex digest>, where v1 is the HMAC-SHA256 digest of "<t>.<raw body>". Verify a size-limited raw request body rather than a re-serialized object, use a timing-safe comparison, reject stale timestamps, and reject events whose data.jobId does not match the persisted batch.id.

AI Gateway expects a 2xx response within 10 seconds and retries failed deliveries. It does not follow redirects, so the callback endpoint itself must return the 2xx response. Retries carry the same x-ai-gateway-idempotency-key value (<jobId>-<status>), which receivers can use for deduplication. After verification, pass the persisted batch reference to experimental_getBatchStatus and experimental_getBatchResults. Delivery is best-effort, so periodically reconcile persisted batches by status as a fallback for a notification that exhausts its retries.

Each request specifies its type and model. AI Gateway currently requires every text request in a batch to use the same model and throws before submission when the models differ.

Reranking Models

You can create reranking models using the rerankingModel method on the provider instance:

import { rerank } from 'ai';
import { gateway } from '@ai-sdk/gateway';
const { ranking } = await rerank({
model: gateway.rerankingModel('cohere/rerank-v3.5'),
query: 'What is the capital of France?',
documents: [
'Paris is the capital of France.',
'Berlin is the capital of Germany.',
'Madrid is the capital of Spain.',
],
topN: 2,
});
console.log(ranking);
// [
// { originalIndex: 0, score: 0.89, document: 'Paris is the capital of France.' },
// { originalIndex: 2, score: 0.15, document: 'Madrid is the capital of Spain.' },
// ]

Reranking models are useful for improving search results in retrieval-augmented generation (RAG) pipelines by re-scoring candidate documents after an initial retrieval step.

Realtime Models

Realtime support is experimental and the API may change in patch releases.

You can create realtime models for bidirectional audio/text WebSocket sessions using the experimental_realtime method on the provider instance. The first argument is the model ID in the format creator/model-name:

import { gateway } from '@ai-sdk/gateway';
const model = gateway.experimental_realtime('openai/gpt-realtime-2');

The Gateway normalizes realtime the same way it normalizes every other modality: your client speaks the normalized AI SDK realtime protocol and the Gateway translates to and from the upstream provider server-side. This means the same client code works regardless of which provider backs the model.

Realtime sessions run in the browser and require a short-lived Gateway client secret created on your server with gateway.experimental_realtime.getToken(). The method uses your Gateway credential (apiKey, AI_GATEWAY_API_KEY, or Vercel OIDC token) to mint a vcst_ client secret and returns the WebSocket URL for the model.

app/api/realtime/setup/route.ts
import { gateway } from 'ai';
export async function POST() {
const token = await gateway.experimental_realtime.getToken({
model: 'openai/gpt-realtime-2',
expiresAfterSeconds: 60 * 10,
});
return Response.json(token);
}

Use the matching Gateway realtime model in the browser. Creating the model is safe in browser code; only getToken() is server-side.

app/realtime/page.tsx
'use client';
import { experimental_useRealtime } from '@ai-sdk/react';
import { gateway } from 'ai';
export default function RealtimePage() {
const realtime = experimental_useRealtime({
model: gateway.experimental_realtime('openai/gpt-realtime-2'),
api: {
token: '/api/realtime/setup',
},
});
// ...
}

Do not expose your Gateway API key or OIDC token to browser clients. Only return the short-lived setup response from getToken().

The Gateway WebSocket route transports the short-lived auth token via the versioned Sec-WebSocket-Protocol subprotocol and the model id via the ?ai-model-id= query - the WebSocket transport of the Authorization and ai-model-id headers the HTTP routes use. Subprotocol values must fit the WebSocket token grammar, and the complete Sec-WebSocket-Protocol header should stay compact (under an 8 KiB safe header budget).

Provider Options

Gateway provider optionstags, user, byok, compliance flags, and so on — are set under providerOptions.gateway in the session configuration, mirroring how they ride the request body on the non-realtime routes. Include them in the session configuration you send to the Gateway, and the Gateway applies them server-side:

import type { GatewayProviderOptions } from '@ai-sdk/gateway';
const gatewayOptions: GatewayProviderOptions = {
tags: ['cooking-coach', 'v2'],
user: 'user-123',
};
const sessionConfig = {
instructions: 'You are a concise voice assistant.',
providerOptions: { gateway: gatewayOptions },
};

The GatewayProviderOptions type is exported from @ai-sdk/gateway for stable client-facing fields. The type also accepts service-owned option keys so the Gateway service can add or change server-side options without requiring an SDK release for every schema change. Runtime validation is owned by the Gateway service.

Provider options are sent in the initial session update after the socket opens, so connect-time options such as byok and quota selection require a Gateway that resolves them from that update. Routing knobs like order / only do not apply to realtime, where the Gateway selects the WebSocket-capable provider.

Available Models

The AI Gateway supports models from OpenAI, Anthropic, Google, Meta, xAI, Mistral, DeepSeek, Amazon Bedrock, Cohere, Perplexity, Alibaba, and other providers.

For the complete list of available models, see the AI Gateway documentation.

Dynamic Model Discovery

You can discover available models programmatically:

import { gateway, generateText } from 'ai';
const availableModels = await gateway.getAvailableModels();
// List all available models
availableModels.models.forEach(model => {
console.log(`${model.id}: ${model.name}`);
if (model.description) {
console.log(` Description: ${model.description}`);
}
if (model.pricing) {
console.log(` Input: $${model.pricing.input}/token`);
console.log(` Output: $${model.pricing.output}/token`);
if (model.pricing.cachedInputTokens) {
console.log(
` Cached input (read): $${model.pricing.cachedInputTokens}/token`,
);
}
if (model.pricing.cacheCreationInputTokens) {
console.log(
` Cache creation (write): $${model.pricing.cacheCreationInputTokens}/token`,
);
}
}
});
// Use any discovered model with plain string
const { text } = await generateText({
model: availableModels.models[0].id, // e.g., 'openai/gpt-5.4'
prompt: 'Hello world',
});

Credit Usage

You can check your team's current credit balance and usage:

import { gateway } from 'ai';
const credits = await gateway.getCredits();
console.log(`Team balance: ${credits.balance} credits`);
console.log(`Team total used: ${credits.total_used} credits`);

The getCredits() method returns your team's credit information based on the authenticated API key or OIDC token:

  • balance number - Your team's current available credit balance
  • total_used number - Total credits consumed by your team

Generation Lookup

Look up detailed information about a specific generation by its ID, including cost, token usage, latency, and provider details. Generation IDs are available in providerMetadata.gateway.generationId on both generateText and streamText responses.

When streaming, the generation ID is injected on the first content chunk, so you can capture it early in the stream without waiting for completion. This is especially useful in cases where a network interruption or mid-stream error could prevent you from receiving the final response — since the gateway records the final status server-side, you can use the generation ID to look up the results (including cost, token usage, and finish reason) later via getGenerationInfo().

import { gateway, generateText } from 'ai';
// Make a request
const result = await generateText({
model: gateway('anthropic/claude-sonnet-4'),
prompt: 'Explain quantum entanglement briefly',
});
// Get the generation ID from provider metadata
const generationId = result.providerMetadata?.gateway?.generationId;
// Look up detailed generation info
const generation = await gateway.getGenerationInfo({ id: generationId });
console.log(`Model: ${generation.model}`);
console.log(`Cost: $${generation.totalCost.toFixed(6)}`);
console.log(`Latency: ${generation.latency}ms`);
console.log(`Prompt tokens: ${generation.promptTokens}`);
console.log(`Completion tokens: ${generation.completionTokens}`);

With streamText, you can capture the generation ID from the first chunk via stream:

import { gateway, streamText } from 'ai';
const result = streamText({
model: gateway('anthropic/claude-sonnet-4'),
prompt: 'Explain quantum entanglement briefly',
});
let generationId: string | undefined;
for await (const part of result.stream) {
if (!generationId && part.providerMetadata?.gateway?.generationId) {
generationId = part.providerMetadata.gateway.generationId as string;
console.log(`Generation ID (early): ${generationId}`);
}
}
// Look up cost and usage after the stream completes
if (generationId) {
const generation = await gateway.getGenerationInfo({ id: generationId });
console.log(`Cost: $${generation.totalCost.toFixed(6)}`);
console.log(`Finish reason: ${generation.finishReason}`);
}

You can also capture the generation ID for every completed model call with onLanguageModelCallEnd. The callback runs before client-side tools execute, so the metadata remains available even if the operation is later aborted while a tool is running:

import { gateway, generateText } from 'ai';
await generateText({
model: gateway('anthropic/claude-sonnet-4'),
prompt: 'Explain quantum entanglement briefly',
onLanguageModelCallEnd({ providerMetadata }) {
const generationId = providerMetadata?.gateway?.generationId as
| string
| undefined;
if (generationId) {
console.log(`Completed Gateway generation: ${generationId}`);
}
},
});

The getGenerationInfo() method accepts:

  • id string - The generation ID to look up (format: gen_<ulid>, required)

It returns a GatewayGenerationInfo object with the following fields:

  • id string - The generation ID
  • totalCost number - Total cost in USD
  • upstreamInferenceCost number - Upstream inference cost in USD (relevant for BYOK)
  • usage number - Usage cost in USD (same as totalCost)
  • createdAt string - ISO 8601 timestamp when the generation was created
  • model string - Model identifier used
  • isByok boolean - Whether Bring Your Own Key credentials were used
  • providerName string - The provider that served this generation
  • streamed boolean - Whether streaming was used
  • finishReason string - Finish reason (e.g. 'stop')
  • latency number - Time to first token in milliseconds
  • generationTime number - Total generation time in milliseconds
  • promptTokens number - Number of prompt tokens
  • completionTokens number - Number of completion tokens
  • reasoningTokens number - Reasoning tokens used (if applicable)
  • cachedTokens number - Cached tokens used (if applicable)
  • cacheCreationTokens number - Cache creation input tokens
  • billableWebSearchCalls number - Number of billable web search calls

Examples

Basic Text Generation

import { generateText } from 'ai';
const { text } = await generateText({
model: 'anthropic/claude-sonnet-4.6',
prompt: 'Write a haiku about programming',
});
console.log(text);

Streaming

import { streamText } from 'ai';
const { textStream } = await streamText({
model: 'openai/gpt-5.4',
prompt: 'Explain the benefits of serverless architecture',
});
for await (const textPart of textStream) {
process.stdout.write(textPart);
}

Tool Usage

import { generateText, tool } from 'ai';
import { z } from 'zod';
const { text } = await generateText({
model: 'xai/grok-4.6',
prompt: 'What is the weather like in San Francisco?',
tools: {
getWeather: tool({
description: 'Get the current weather for a location',
inputSchema: z.object({
location: z.string().describe('The location to get weather for'),
}),
execute: async ({ location }) => {
// Your weather API call here
return `It's sunny in ${location}`;
},
}),
},
});

Provider-Executed Tools

Some providers offer tools that are executed by the provider itself, such as OpenAI's web search tool. To use these tools through AI Gateway, import the provider to access the tool definitions:

import { generateText, isStepCount } from 'ai';
import { openai } from '@ai-sdk/openai';
const result = await generateText({
model: 'openai/gpt-5.4-mini',
prompt: 'What is the Vercel AI Gateway?',
stopWhen: isStepCount(10),
tools: {
web_search: openai.tools.webSearch({}),
},
});
console.dir(result.text);

Some provider-executed tools require account-specific configuration (such as Claude Agent Skills) and may not work through AI Gateway. To use these tools, you must bring your own key (BYOK) directly to the provider.

Gateway Tools

The AI Gateway provider includes built-in tools that are executed by the gateway itself. These tools can be used with any model through the gateway.

The Perplexity Search tool enables models to search the web using Perplexity's search API. This tool is executed by the AI Gateway and returns web search results that the model can use to provide up-to-date information.

import { gateway, generateText } from 'ai';
const result = await generateText({
model: 'openai/gpt-5.4-nano',
prompt: 'Search for news about AI regulations in January 2025.',
tools: {
perplexity_search: gateway.tools.perplexitySearch(),
},
});
console.log(result.text);
console.log('Tool calls:', JSON.stringify(result.toolCalls, null, 2));
console.log('Tool results:', JSON.stringify(result.toolResults, null, 2));

You can also configure the search with optional parameters:

import { gateway, generateText } from 'ai';
const result = await generateText({
model: 'openai/gpt-5.4-nano',
prompt:
'Search for news about AI regulations from the first week of January 2025.',
tools: {
perplexity_search: gateway.tools.perplexitySearch({
maxResults: 5,
searchLanguageFilter: ['en'],
country: 'US',
searchDomainFilter: ['reuters.com', 'bbc.com', 'nytimes.com'],
}),
},
});
console.log(result.text);
console.log('Tool calls:', JSON.stringify(result.toolCalls, null, 2));
console.log('Tool results:', JSON.stringify(result.toolResults, null, 2));

The Perplexity Search tool supports the following optional configuration options:

  • maxResults number

    The maximum number of search results to return (1-20, default: 10).

  • maxTokensPerPage number

    The maximum number of tokens to extract per search result page (256-2048, default: 2048).

  • maxTokens number

    The maximum total tokens across all search results (default: 25000, max: 1000000).

  • searchLanguageFilter string[]

    Filter search results by language using ISO 639-1 language codes (e.g., ['en'] for English, ['en', 'es'] for English and Spanish).

  • country string

    Filter search results by country using ISO 3166-1 alpha-2 country codes (e.g., 'US' for United States, 'GB' for United Kingdom).

  • searchDomainFilter string[]

    Limit search results to specific domains (e.g., ['reuters.com', 'bbc.com']). This is useful for restricting results to trusted sources.

  • searchRecencyFilter 'day' | 'week' | 'month' | 'year'

    Filter search results by relative time period. Useful for always getting recent results (e.g., 'week' for results from the last week).

The tool works with both generateText and streamText:

import { gateway, streamText } from 'ai';
const result = streamText({
model: 'openai/gpt-5.4-nano',
prompt: 'Search for the latest news about AI regulations.',
tools: {
perplexity_search: gateway.tools.perplexitySearch(),
},
});
for await (const part of result.stream) {
switch (part.type) {
case 'text-delta':
process.stdout.write(part.text);
break;
case 'tool-call':
console.log('\nTool call:', JSON.stringify(part, null, 2));
break;
case 'tool-result':
console.log('\nTool result:', JSON.stringify(part, null, 2));
break;
}
}

The Exa Search tool enables models to search the web using Exa's Search API. This tool is executed by the AI Gateway and returns token-efficient web excerpts for agent workflows.

import { gateway, generateText } from 'ai';
const result = await generateText({
model: 'openai/gpt-5.4-nano',
prompt:
'Find the latest AI regulation updates and summarize the key changes.',
tools: {
exa_search: gateway.tools.exaSearch(),
},
});
console.log(result.text);
console.log('Tool calls:', JSON.stringify(result.toolCalls, null, 2));
console.log('Tool results:', JSON.stringify(result.toolResults, null, 2));

You can also configure the search with optional parameters:

import { gateway, generateText } from 'ai';
const result = await generateText({
model: 'openai/gpt-5.4-nano',
prompt: 'Find recent AI regulation news from trusted sources.',
tools: {
exa_search: gateway.tools.exaSearch({
type: 'fast',
numResults: 5,
category: 'news',
includeDomains: ['reuters.com', 'bbc.com', 'nytimes.com'],
contents: {
highlights: true,
maxAgeHours: 24,
},
}),
},
});
console.log(result.text);
console.log('Tool calls:', JSON.stringify(result.toolCalls, null, 2));
console.log('Tool results:', JSON.stringify(result.toolResults, null, 2));

The Exa Search tool supports the following optional configuration options:

  • type 'auto' | 'fast' | 'instant'

    Search mode. 'auto' is the default balance of speed and quality.

  • numResults number

    Maximum number of results to return (1-100, default: 10).

  • category 'company' | 'people' | 'research paper' | 'news' | 'personal site' | 'financial report'

    Focus results on a specific content type.

  • includeDomains / excludeDomains string[]

    Restrict or exclude search results by domain.

  • startPublishedDate / endPublishedDate string

    Filter results by ISO 8601 publication date.

  • contents object

    Control result extraction and freshness:

    • text - Return full page text, optionally capped with maxCharacters
    • highlights - Return token-efficient excerpts
    • maxAgeHours - Control cached content freshness
    • livecrawlTimeout - Livecrawl timeout in milliseconds
    • subpages / subpageTarget - Crawl related subpages
    • extras.links / extras.imageLinks - Extract links from pages

The tool works with both generateText and streamText.

This initial Gateway integration supports Exa's plain Search modes and token-efficient content controls. Deep synthesis modes and generated summaries are intentionally not exposed yet because they have separate pricing from standard Search.

The Tako Search tool enables models to search the web and Tako's curated knowledge graph in a single call using Tako's Search API. This tool is executed by the AI Gateway and returns token-efficient web excerpts, plus knowledge-graph results that carry structured data, premium source attribution, and an embed-ready visualization.

import { gateway, generateText } from 'ai';
const result = await generateText({
model: 'openai/gpt-5.4-nano',
prompt: 'How has Nvidia quarterly revenue changed over the last two years?',
tools: {
tako_search: gateway.tools.takoSearch(),
},
});
console.log(result.text);
console.log('Tool calls:', JSON.stringify(result.toolCalls, null, 2));
console.log('Tool results:', JSON.stringify(result.toolResults, null, 2));

Configure the search with effort, source selection, and localization defaults. These defaults override values the model includes in a tool call:

import { gateway, generateText } from 'ai';
const result = await generateText({
model: 'openai/gpt-5.4-nano',
prompt: 'AMD vs. Nvidia headcount since 2013',
tools: {
tako_search: gateway.tools.takoSearch({
effort: 'fast',
sources: {
data: {
contentFormat: 'json_compact',
includeContents: true,
maxRows: 100,
},
web: {
count: 3,
},
},
countryCode: 'US',
locale: 'en-US',
}),
},
});
console.log(result.text);

The Tako Search tool supports these optional configuration options:

  • effort 'fast' | 'instant' | 'deep' - Search effort. 'fast' is the balanced default, 'instant' favors cached low-latency results, and 'deep' broadens retrieval with reranking at higher cost and latency.
  • sources object - Omit to search both curated Tako data and the live web. When set, only source keys present are searched.
  • sources.web object - Configure web results:
    • count number - Maximum web results, 1-20.
    • category 'finance' | 'news' | 'sports' - Restrict web results to one category.
    • includeDomains / excludeDomains string[] - Only return, or drop, results from these bare domains. Up to 20 each.
    • publishedAfter / publishedBefore string - Keep results published on or after, or on or before, this YYYY-MM-DD date.
    • snippetMaxChars number - Character cap on each result's text excerpt. Defaults to 4,000; maximum 20,000.
    • highlights boolean - Return query-relevant passages as each result's snippet instead of the opening text of the page. The snippet can hold multiple passages joined by ' ... ', and a page with no highlight returns snippet: null. Defaults to true in the AI Gateway.
    • includeContents boolean - Inline each page's extracted full text in content. articleContentMaxChars caps it, defaulting to 30,000 characters (maximum 1,000,000).
  • sources.data object - Configure data results:
    • count number - Maximum data results, 1-20. Defaults to 5.
    • includeContents boolean - Inline each card's underlying rows in content.dataset as typed, unit-labeled columns. This adds a data surcharge based on the row count and dataset source. To estimate cost, first search with includeContents: false and inspect cards.content.export_pricing. Because this applies to every returned card, use count and maxRows to control cost.
    • contentFormat 'json_compact' | 'json_records' | 'csv' | 'card_json' - Serialization for inlined card data. Defaults to 'json_compact'.
    • maxRows number - Row cap per result. Omit to use the allowance in cards.content.export_pricing. A data surcharge applies per 1,000 exported rows; lower values reduce cost.
    • nodeIds string[] - Data Graph node IDs to prioritize. Up to 20.
    • strict boolean - Only return cards matching nodeIds. Requires at least one nodeIds value.
  • location object - End-user { latitude, longitude } coordinates for localized results.
  • countryCode string - ISO 3166-1 alpha-2 country code, such as 'US'.
  • locale string - BCP-47 locale, such as 'en-US'.
  • timezone string - IANA timezone, such as 'America/New_York'.
  • outputSettings object - Card rendering controls. forceRefresh is available only with 'instant' effort.
  • includeRelated number - Number of related search suggestions to include (1-20).

For precise entity matching, quote a phrase in the query and optionally append a label: "Tesla":PRODUCT price. Tako treats the quoted phrase as one entity before searching.

The tool works with both generateText and streamText:

import { gateway, streamText } from 'ai';
const result = streamText({
model: 'openai/gpt-5.4-nano',
prompt: 'What is the latest US inflation rate?',
tools: {
tako_search: gateway.tools.takoSearch(),
},
});
for await (const part of result.stream) {
switch (part.type) {
case 'text-delta':
process.stdout.write(part.text);
break;
case 'tool-call':
console.log('\nTool call:', JSON.stringify(part, null, 2));
break;
case 'tool-result':
console.log('\nTool result:', JSON.stringify(part, null, 2));
break;
}
}

The Parallel Search tool enables models to search the web using Parallel AI's Search API. This tool is optimized for LLM consumption, returning relevant excerpts from web pages that can replace multiple keyword searches with a single call.

import { gateway, generateText } from 'ai';
const result = await generateText({
model: 'openai/gpt-5.4-nano',
prompt: 'Research the latest developments in quantum computing.',
tools: {
parallel_search: gateway.tools.parallelSearch(),
},
});
console.log(result.text);
console.log('Tool calls:', JSON.stringify(result.toolCalls, null, 2));
console.log('Tool results:', JSON.stringify(result.toolResults, null, 2));

You can also configure the search with optional parameters:

import { gateway, generateText } from 'ai';
const result = await generateText({
model: 'openai/gpt-5.4-nano',
prompt: 'Find detailed information about TypeScript 5.0 features.',
tools: {
parallel_search: gateway.tools.parallelSearch({
mode: 'agentic',
maxResults: 5,
sourcePolicy: {
includeDomains: ['typescriptlang.org', 'github.com'],
},
excerpts: {
maxCharsPerResult: 8000,
},
}),
},
});
console.log(result.text);
console.log('Tool calls:', JSON.stringify(result.toolCalls, null, 2));
console.log('Tool results:', JSON.stringify(result.toolResults, null, 2));

The Parallel Search tool supports the following optional configuration options:

  • mode 'one-shot' | 'agentic'

    Mode preset for different use cases:

    • 'one-shot' - Comprehensive results with longer excerpts for single-response answers (default)
    • 'agentic' - Concise, token-efficient results optimized for multi-step agentic workflows
  • maxResults number

    Maximum number of results to return (1-20). Defaults to 10 if not specified.

  • sourcePolicy object

    Source policy for controlling which domains to include/exclude:

    • includeDomains - List of domains to include in search results
    • excludeDomains - List of domains to exclude from search results
    • afterDate - Only include results published after this date (ISO 8601 format)
  • excerpts object

    Excerpt configuration for controlling result length:

    • maxCharsPerResult - Maximum characters per result
    • maxCharsTotal - Maximum total characters across all results
  • fetchPolicy object

    Fetch policy for controlling content freshness:

    • maxAgeSeconds - Maximum age in seconds for cached content (set to 0 for always fresh)

The tool works with both generateText and streamText:

import { gateway, streamText } from 'ai';
const result = streamText({
model: 'openai/gpt-5.4-nano',
prompt: 'Research the latest AI safety guidelines.',
tools: {
parallel_search: gateway.tools.parallelSearch(),
},
});
for await (const part of result.stream) {
switch (part.type) {
case 'text-delta':
process.stdout.write(part.text);
break;
case 'tool-call':
console.log('\nTool call:', JSON.stringify(part, null, 2));
break;
case 'tool-result':
console.log('\nTool result:', JSON.stringify(part, null, 2));
break;
}
}

Custom Reporting

Track usage per end-user and categorize requests with tags, then query the data through the reporting API.

Usage Tracking with User and Tags

import type { GatewayProviderOptions } from '@ai-sdk/gateway';
import { generateText } from 'ai';
const { text } = await generateText({
model: 'openai/gpt-5.4',
prompt: 'Summarize this document...',
providerOptions: {
gateway: {
user: 'user-abc-123', // Track usage for this specific end-user
tags: ['document-summary', 'premium-feature'], // Categorize for reporting
} satisfies GatewayProviderOptions,
},
});

This allows you to:

  • View usage and costs broken down by end-user in your analytics
  • Filter and analyze spending by feature or use case using tags
  • Track which users or features are driving the most AI usage

Querying Spend Reports

Use the getSpendReport() method to query usage data programmatically. The reporting API is only available for Vercel Pro and Enterprise plans. For pricing, see the Custom Reporting docs.

import { gateway } from 'ai';
const report = await gateway.getSpendReport({
startDate: '2026-03-01',
endDate: '2026-03-25',
groupBy: 'model',
});
for (const row of report.results) {
console.log(`${row.model}: $${row.totalCost.toFixed(4)}`);
}

The getSpendReport() method accepts the following parameters:

  • startDate string - Start date in YYYY-MM-DD format (inclusive, required)
  • endDate string - End date in YYYY-MM-DD format (inclusive, required)
  • groupBy string - Aggregation dimension: 'day' (default), 'user', 'model', 'tag', 'provider', or 'credential_type'
  • datePart string - Time granularity when groupBy is 'day': 'day' or 'hour'
  • userId string - Filter to a specific user
  • model string - Filter to a specific model (e.g. 'anthropic/claude-sonnet-4.5')
  • provider string - Filter to a specific provider (e.g. 'anthropic')
  • credentialType string - Filter by 'byok' or 'system' credentials
  • tags string[] - Filter to requests matching these tags

Each row in results contains a grouping field (matching your groupBy choice) and metrics:

  • totalCost number - Total cost in USD
  • marketCost number - Market cost in USD
  • inputTokens number - Number of input tokens
  • outputTokens number - Number of output tokens
  • cachedInputTokens number - Number of cached input tokens
  • cacheCreationInputTokens number - Number of cache creation input tokens
  • reasoningTokens number - Number of reasoning tokens
  • requestCount number - Number of requests

You can combine tracking and querying to analyze spend by tags you defined:

import type { GatewayProviderOptions } from '@ai-sdk/gateway';
import { gateway, streamText } from 'ai';
// 1. Make requests with tags
const result = streamText({
model: gateway('anthropic/claude-haiku-4.5'),
prompt: 'Summarize this quarter's results',
providerOptions: {
gateway: {
tags: ['team:finance', 'feature:summaries'],
} satisfies GatewayProviderOptions,
},
});
// 2. Later, query spend filtered by those tags
const report = await gateway.getSpendReport({
startDate: '2026-03-01',
endDate: '2026-03-31',
groupBy: 'tag',
tags: ['team:finance'],
});
for (const row of report.results) {
console.log(`${row.tag}: $${row.totalCost.toFixed(4)} (${row.requestCount} requests)`);
}

Provider Options

The AI Gateway provider accepts provider options that control routing behavior and provider-specific configurations.

Gateway Provider Options

You can use the gateway key in providerOptions to control how AI Gateway routes requests:

import type { GatewayProviderOptions } from '@ai-sdk/gateway';
import { generateText } from 'ai';
const { text } = await generateText({
model: 'anthropic/claude-sonnet-4.6',
prompt: 'Explain quantum computing',
providerOptions: {
gateway: {
order: ['vertex', 'anthropic'], // Try Vertex AI first, then Anthropic
only: ['vertex', 'anthropic'], // Only use these providers
} satisfies GatewayProviderOptions,
},
});

The following gateway provider options are available:

  • order string[]

    Specifies the sequence of providers to attempt when routing requests. The gateway will try providers in the order specified. If a provider fails or is unavailable, it will move to the next provider in the list.

    Example: order: ['bedrock', 'anthropic'] will attempt Amazon Bedrock first, then fall back to Anthropic.

  • only string[]

    Restricts routing to only the specified providers. When set, the gateway will never route to providers not in this list, even if they would otherwise be available.

    Example: only: ['anthropic', 'vertex'] will only allow routing to Anthropic or Vertex AI.

  • sort 'cost' | 'ttft' | 'tps'

    Sorts available providers by a performance or cost metric before routing. The gateway will try the best-scoring provider first and fall back through the rest in sorted order. If unspecified, providers are ordered using the gateway's default system ranking.

    • 'cost' — lowest cost first
    • 'ttft' — lowest time-to-first-token first
    • 'tps' — highest tokens-per-second first

    When combined with order, the user-specified providers are promoted to the front while remaining providers follow the sorted order.

    Example: sort: 'ttft' will route to the provider with the fastest time-to-first-token.

    When sort is active, the response's providerMetadata.gateway.routing.sort object contains the sort option used, the resulting execution order, per-provider metric values, and any providers that were deprioritized.

  • models string[]

    Specifies fallback models to use when the primary model fails or is unavailable. The gateway will try the primary model first (specified in the model parameter), then try each model in this array in order until one succeeds.

    Example: models: ['openai/gpt-5.4-nano', 'gemini-3-flash-preview'] will try the fallback models in order if the primary model fails.

  • user string

    Optional identifier for the end user on whose behalf the request is being made. This is used for spend tracking and attribution purposes, allowing you to track usage per end-user in your application.

    Example: user: 'user-123' will associate this request with end-user ID "user-123" in usage reports.

  • tags string[]

    Optional array of tags for categorizing and filtering usage in reports. Useful for tracking spend by feature, prompt version, or any other dimension relevant to your application.

    Example: tags: ['chat', 'v2'] will tag this request with "chat" and "v2" for filtering in usage analytics.

  • byok Record<string, Array<Record<string, unknown>>>

    Request-scoped BYOK (Bring Your Own Key) credentials to use for this request. When provided, any cached BYOK credentials configured in the gateway system are not considered. Requests may still fall back to use system credentials if the provided credentials fail.

    Each provider can have multiple credentials (tried in order). The structure is a record where keys are provider slugs and values are arrays of credential objects.

    Each credential can optionally include a modelMappings array to map AI Gateway model slugs to your deployment names (for example, custom Azure deployment names). If a BYOK request fails, the gateway falls back to system credentials using the default model name.

    Examples:

    • Single provider: byok: { 'anthropic': [{ apiKey: 'sk-ant-...' }] }
    • Multiple credentials: byok: { 'vertex': [{ project: 'proj-1', googleCredentials: { privateKey: '...', clientEmail: '...' } }, { project: 'proj-2', googleCredentials: { privateKey: '...', clientEmail: '...' } }] }
    • Multiple providers: byok: { 'anthropic': [{ apiKey: '...' }], 'bedrock': [{ accessKeyId: '...', secretAccessKey: '...' }] }
    • With model mappings: byok: { 'azure': [{ apiKey: '...', resourceName: '...', modelMappings: [{ gatewayModelSlug: 'openai/gpt-5.4-nano', customModelId: 'my-deployment' }] }] }
  • zeroDataRetention boolean

    Restricts routing to providers with zero data retention agreements with Vercel for AI Gateway. BYOK credentials are skipped by default, since your provider agreements differ from Vercel's. When this filter is on, AI Gateway routes only to providers Vercel has ZDR agreements with for the model. If you have BYOK keys marked as ZDR, those keys are tried first, then AI Gateway falls back to its system credentials. You are responsible for the accuracy of that marking. Applies to both account-wide and request-level ZDR. The request fails if no ZDR-eligible credentials are available. Request-level ZDR is only available for Vercel Pro and Enterprise plans.

  • disallowPromptTraining boolean

    Restricts routing to providers that have agreements with Vercel for AI Gateway to not use prompts for model training. When using BYOK credentials, this filter is not applied. If BYOK credentials fail and the request falls back to system credentials, only providers that do not train on prompt data will be used. If there are no providers available for the model that disallow prompt training, the request will fail.

  • quotaEntityId string

    The unique identifier for the entity against which quota is tracked. Used for quota management and enforcement purposes.

  • has Array<'implicit-caching' | 'vision'>

    Restricts routing to provider models that have all of the specified capabilities. Applies to both BYOK and system credentials, since the capability is a property of the model rather than the credential. If no provider model for the requested model satisfies the capabilities, the request fails. Unsupported values are rejected.

    Supported capabilities:

    • 'implicit-caching' — models that perform automatic (implicit) prompt caching.
    • 'vision' — models that accept image input.

    Example: has: ['implicit-caching'] will only route to models that support implicit caching. Example: has: ['vision'] will only route to models that accept image input.

  • providerTimeouts object

    Per-provider timeouts for BYOK credentials in milliseconds. Controls how long to wait for a provider to start responding before falling back to the next available provider.

    Example: providerTimeouts: { byok: { openai: 5000, anthropic: 2000 } }

    For full details, see Provider Timeouts.

  • serviceTier 'flex' | 'priority'

    Unified service tier intent. The gateway translates it into whichever per-provider option each provider expects, and overrides any tier also set in the per-provider options. Leave unset for provider default. See the OpenAI, Google Generative AI, and Google Vertex AI provider docs for tier semantics, model availability, and graceful downgrade behavior on each provider.

    import type { GatewayProviderOptions } from '@ai-sdk/gateway';
    import { generateText } from 'ai';
    const { text } = await generateText({
    model: 'openai/gpt-5-mini',
    prompt: 'Hello',
    providerOptions: {
    gateway: {
    serviceTier: 'priority',
    } satisfies GatewayProviderOptions,
    },
    });

You can combine these options to have fine-grained control over routing and tracking:

import type { GatewayProviderOptions } from '@ai-sdk/gateway';
import { generateText } from 'ai';
const { text } = await generateText({
model: 'anthropic/claude-sonnet-4.6',
prompt: 'Write a haiku about programming',
providerOptions: {
gateway: {
order: ['vertex'], // Prefer Vertex AI
only: ['anthropic', 'vertex'], // Only allow these providers
} satisfies GatewayProviderOptions,
},
});

Model Fallbacks Example

The models option enables automatic fallback to alternative models when the primary model fails:

import type { GatewayProviderOptions } from '@ai-sdk/gateway';
import { generateText } from 'ai';
const { text } = await generateText({
model: 'openai/gpt-5.4', // Primary model
prompt: 'Write a TypeScript haiku',
providerOptions: {
gateway: {
models: ['openai/gpt-5.4-nano', 'gemini-3-flash-preview'], // Fallback models
} satisfies GatewayProviderOptions,
},
});
// This will:
// 1. Try openai/gpt-5.4 first
// 2. If it fails, try openai/gpt-5.4-nano
// 3. If that fails, try gemini-3-flash-preview
// 4. Return the result from the first model that succeeds

Zero Data Retention Example

Set zeroDataRetention to true to route requests to providers with zero data retention agreements with Vercel for AI Gateway. BYOK credentials are skipped by default, since your provider agreements differ from Vercel's. When this filter is on, AI Gateway routes only to providers Vercel has ZDR agreements with for the model. If you have BYOK keys marked as ZDR, those keys are tried first, then AI Gateway falls back to its system credentials. You are responsible for the accuracy of that marking. Applies to both account-wide and request-level ZDR. The request fails if no ZDR-eligible credentials are available. When zeroDataRetention is false or not specified, there is no enforcement of restricting routing. Request-level ZDR is only available for Vercel Pro and Enterprise plans.

import type { GatewayProviderOptions } from '@ai-sdk/gateway';
import { generateText } from 'ai';
const { text } = await generateText({
model: 'anthropic/claude-sonnet-4.6',
prompt: 'Analyze this sensitive document...',
providerOptions: {
gateway: {
zeroDataRetention: true,
} satisfies GatewayProviderOptions,
},
});

Disallow Prompt Training Example

Set disallowPromptTraining to true to route requests to providers that have agreements with Vercel for AI Gateway to not use prompts for model training. When using BYOK credentials, this filter is not applied. If BYOK credentials fail and the request falls back to system credentials, only providers that do not train on prompt data will be used. If there are no providers available for the model that disallow prompt training, the request will fail. When disallowPromptTraining is false or not specified, there is no enforcement of restricting routing.

import type { GatewayProviderOptions } from '@ai-sdk/gateway';
import { generateText } from 'ai';
const { text } = await generateText({
model: 'anthropic/claude-sonnet-4.6',
prompt: 'Analyze this proprietary business data...',
providerOptions: {
gateway: {
disallowPromptTraining: true,
} satisfies GatewayProviderOptions,
},
});

Quota Entity ID Example

Set quotaEntityId to track and enforce quota against a specific entity. This is useful for multi-tenant applications where you need to manage quota at the entity level (e.g., per organization or team).

import type { GatewayProviderOptions } from '@ai-sdk/gateway';
import { generateText } from 'ai';
const { text } = await generateText({
model: 'anthropic/claude-sonnet-4.6',
prompt: 'Summarize this report...',
providerOptions: {
gateway: {
quotaEntityId: 'org-123',
} satisfies GatewayProviderOptions,
},
});

Filtering by Model Capability

Set has to restrict routing to provider models that have the specified capabilities. This applies to both BYOK and system credentials, since the capability is a property of the model rather than the credential. 'implicit-caching' limits routing to models that perform automatic prompt caching, and 'vision' limits routing to models that accept image input. If no provider model for the requested model satisfies the capabilities, the request fails.

import type { GatewayProviderOptions } from '@ai-sdk/gateway';
import { generateText } from 'ai';
const { text } = await generateText({
model: 'openai/gpt-5.5',
prompt: 'Summarize this report...',
providerOptions: {
gateway: {
has: ['implicit-caching'],
} satisfies GatewayProviderOptions,
},
});

Use 'vision' when the request sends image input, so the gateway only routes to provider models that can accept it:

import type { GatewayProviderOptions } from '@ai-sdk/gateway';
import { generateText } from 'ai';
import fs from 'node:fs';
const { text } = await generateText({
model: 'anthropic/claude-sonnet-4.6',
messages: [
{
role: 'user',
content: [
{ type: 'text', text: 'Describe the image in detail.' },
{
type: 'file',
mediaType: 'image/png',
data: fs.readFileSync('./data/comic-cat.png'),
},
],
},
],
providerOptions: {
gateway: {
has: ['vision'],
} satisfies GatewayProviderOptions,
},
});

Provider-Specific Options

When using provider-specific options through AI Gateway, use the actual provider name (e.g. anthropic, openai, not gateway) as the key:

import type { AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
import type { GatewayProviderOptions } from '@ai-sdk/gateway';
import { generateText } from 'ai';
const { text } = await generateText({
model: 'anthropic/claude-sonnet-4.6',
prompt: 'Explain quantum computing',
providerOptions: {
gateway: {
order: ['vertex', 'anthropic'],
} satisfies GatewayProviderOptions,
anthropic: {
thinking: { type: 'enabled', budgetTokens: 12000 },
} satisfies AnthropicLanguageModelOptions,
},
});

This works with any provider supported by AI Gateway. Each provider has its own set of options - see the individual provider documentation pages for details on provider-specific options.

Available Providers

AI Gateway supports routing to 20+ providers.

For a complete list of available providers and their slugs, see the AI Gateway documentation.

Model Capabilities

Model capabilities depend on the specific provider and model you're using. For detailed capability information, see: