Skip to main content
Watch: Claude Code Just Killed After Effects

LLM Engineering

Vercel AI Gateway Integration

Use when routing an app's LLM calls through the Vercel AI Gateway with the AI SDK so one key reaches many providers. Covers plain string model ids, a client-safe model whitelist, and streaming. Also use when a model id works against a direct provider but fails through the gateway, or the gateway key is at risk of reaching the client. If a model call crosses a gateway, use this skill.

ai-gatewayvercelai-sdkllmstreaming

1 file

Description

Use when routing an app's LLM calls through the Vercel AI Gateway with the AI SDK so one key reaches many providers. Covers plain string model ids, a client-safe model whitelist, and streaming. Also use when a model id works against a direct provider but fails through the gateway, or the gateway key is at risk of reaching the client. If a model call crosses a gateway, use this skill.

Install
SKILL.md

name: vercel-ai-gateway-integration description: Use when wiring an app's LLM calls through the Vercel AI Gateway with the AI SDK (v5/v6), so one key reaches many providers. Covers string model ids, a client-safe model whitelist, streaming, and the Responses-API mismatch that only shows up against direct providers.

Vercel AI Gateway Integration

When to trigger

Adding chat or completion features that should reach many providers (OpenAI, Anthropic, Moonshot, Google) through one billing surface and one key, instead of wiring a client per provider.

The one thing that makes it simple

With AI_GATEWAY_API_KEY set in the environment, the AI SDK resolves a plain string model id through the gateway automatically. You do not construct a provider client or set a baseURL.

import { streamText } from "ai";

const result = streamText({
  model: "moonshotai/kimi-k2.5", // "provider/model", resolved by the gateway
  messages,
});
return result.toUIMessageStreamResponse();

The id is the gateway's provider/model form. Verify it against the gateway /v1/models list before shipping; a typo silently falls through to an error at request time, not build time.

Keep the model list client-safe

Put the offered models in a module with no secrets so both the picker UI and the route can import it. The route validates the requested id against that whitelist before it ever reaches the gateway, so a caller cannot force an arbitrary model.

export const CHAT_MODELS = [
  { id: "moonshotai/kimi-k2.5", label: "Kimi K2.5", credits: 1 },
  { id: "openai/gpt-5.4-mini", label: "GPT-5.4 Mini", credits: 1 },
] as const;
export function isChatModel(id: string) {
  return CHAT_MODELS.some((m) => m.id === id);
}

Gate before you spend

Order the checks cheap-first so a rejected request never pays for inference: auth, then config present (503 if the gateway key is missing), then rate limit, then credit balance. Deduct credits in onFinish after a successful generation, never before, so a failed or rate-limited call charges nothing.

Pitfalls

  • Passing a provider client object where a string id is expected defeats the gateway. When the key is set, pass the string.
  • The Responses-API vs Chat-Completions shape differs. Code that works through the gateway can break when pointed straight at a direct provider (for example OpenAI's Responses API), because the gateway normalizes a shape the direct endpoint does not. Test the path you actually ship.
  • A missing AI_GATEWAY_API_KEY in the deploy env builds fine and then 503s every request. Add the key to the host before shipping the feature, not after the first failed call.
  • Charging before onFinish bills users for failed generations. Deduct on success only.
AI Development Stack

Get Smarter About AI Dev

New tutorials, open-source projects, and deep dives on coding agents - delivered weekly.

One email per weekReal code, not theoryFree forever