Wiring the Vercel AI SDK to a non-OpenAI gateway is painless because the SDK speaks the OpenAI wire format. This tutorial shows how to connect Vercel AI SDK to n4n.ai API using its OpenAI-compatible endpoint, so you can route more than 240 models through one interface without rewriting your app.
Step 1: Prerequisites
Confirm you have a TypeScript project (Next.js 14+ recommended) running on Node 18 or later. You need an API key and the base URL exposed by the gateway (both shown in its dashboard). If you already use the Vercel AI SDK with OpenAI, the only real change is the baseURL and the model identifier convention.
What the endpoint guarantees
The gateway exposes a single OpenAI-compatible surface: /chat/completions, /embeddings, and the SSE stream format all match OpenAI’s spec. That means you do not need a vendor-specific client—just point the existing SDK at a different host.
Step 2: Install dependencies
Add the Vercel AI SDK core and the OpenAI compatibility wrapper. The wrapper is a thin layer that configures the SDK to talk to any OpenAI-shaped server.
npm install ai @ai-sdk/openai
# pnpm add ai @ai-sdk/openai
Pin majors in production. As of this writing ai is at v3.x and @ai-sdk/openai at v1.x; mismatch across minors can break the streamText response shape.
Step 3: Configure environment variables
Keep credentials out of source control. Create .env.local:
GATEWAY_BASE_URL=https://api.n4n.ai/v1
GATEWAY_API_KEY=sk-your-key-here
Also commit a .env.example with empty values so teammates know what to provision. Restart the dev server after editing env files—Next.js reads process.env at server boot, not on every request.
Step 4: Point the OpenAI provider at the gateway
The @ai-sdk/openai package exports createOpenAI, which accepts a baseURL. This is the only wiring required to shift traffic away from OpenAI’s servers.
// lib/gateway.ts
import { createOpenAI } from '@ai-sdk/openai';
export const gateway = createOpenAI({
baseURL: process.env.GATEWAY_BASE_URL!,
apiKey: process.env.GATEWAY_API_KEY!,
compatibility: 'compatible',
});
Use compatibility: 'compatible' (the default) rather than 'strict'. The gateway may return extra routing metadata in the JSON; strict mode will throw on unknown fields.
Step 5: Write a streaming chat route
In a Next.js app router, create app/api/chat/route.ts. Use streamText to return a data stream that the Vercel useChat hook consumes directly.
import { streamText } from 'ai';
import { gateway } from '@/lib/gateway';
export const runtime = 'edge';
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: gateway('anthropic/claude-3.5-sonnet'),
messages,
temperature: 0.7,
maxTokens: 1024,
});
return result.toDataStreamResponse();
}
Model strings follow provider/model. Because the gateway addresses 240+ models, you can replace anthropic/claude-3.5-sonnet with openai/gpt-4o or meta-llama/llama-3-70b without touching any other line.
Client-side hookup
'use client';
import { useChat } from 'ai/react';
export default function Chat() {
const { messages, input, handleInputChange, handleSubmit } = useChat();
return (
<form onSubmit={handleSubmit}>
<input value={input} onChange={handleInputChange} placeholder="Ask…" />
<button type="submit">Send</button>
{messages.map(m => (
<p key={m.id}><strong>{m.role}:</strong> {m.content}</p>
))}
</form>
);
}
The Edge runtime reduces cold starts but lacks some Node APIs. If you need fs or certain crypto, drop the runtime export and run on Node.
Step 6: Send routing directives and cache hints
Production traffic needs control over which upstream handles a call and whether prompts should be cached. The gateway honors client routing directives and forwards provider cache-control hints. Pass them as headers on the provider instance.
export const cachedGateway = createOpenAI({
baseURL: process.env.GATEWAY_BASE_URL!,
apiKey: process.env.GATEWAY_API_KEY!,
headers: {
'x-gateway-route': 'provider:anthropic',
'x-cache-ttl': '3600',
},
});
If you need per-request overrides, build a fresh provider inside the handler. Headers are forwarded untouched to the upstream, so provider-specific cache blocks (e.g., Anthropic’s cache_control) work as documented. Avoid stuffing secrets into headers—only routing and cache metadata.
Step 7: Handle degradation and errors
The gateway provides automatic fallback when a provider is rate-limited or degraded, so a single model ID rarely fails outright. You still need defensive code for malformed input or auth errors.
export async function POST(req: Request) {
try {
const { messages } = await req.json();
if (!Array.isArray(messages)) throw new Error('bad shape');
const result = streamText({
model: gateway('openai/gpt-4o-mini'),
messages,
});
return result.toDataStreamResponse({
onError: (e) => {
console.error('stream failure', e);
return 'Upstream error';
},
});
} catch (err) {
return new Response('Bad request', { status: 400 });
}
}
toDataStreamResponse catches non-fatal stream errors and emits a client-visible string. For observability, map gateway error codes to metrics rather than logging raw payloads.
Step 8: Verify the integration
Start the dev server and hit the route with curl to confirm tokens stream and usage is metered.
curl -i -X POST http://localhost:3000/api/chat \
-H 'content-type: application/json' \
-d '{"messages":[{"role":"user","content":"Return the word hi in JSON"}]}'
You should see SSE chunks prefixed with 0:". A 401 means the key is wrong; a 404 means the model ID or base URL is off.
Check metering and frontend
The gateway returns per-token usage metering in response headers (e.g., x-usage-prompt-tokens). Inspect them with the -i flag above or in the browser network tab. In the UI, type a message and watch the useChat state append tokens live—if the stream renders incrementally, the full path works.
Step 9: Swap models without code changes
Because the SDK treats the gateway as a drop-in OpenAI substitute, drive model selection from config:
const modelId = process.env.CHAT_MODEL ?? 'anthropic/claude-3.5-sonnet';
const result = streamText({ model: gateway(modelId), messages });
This is the payoff: one client, one endpoint, 240+ models, automatic fallback, and cache hints—no lock-in.
Step 10: Production considerations
- Timeouts: Edge functions default to 30s; long completions need a Node runtime or streaming keep-alive.
- Key rotation: Rotate
GATEWAY_API_KEYvia env orchestration, never hardcoded. - Model casing: The gateway uses lowercase
provider/model.GPT-4owill 404. - Header stripping: Routing and cache headers are forwarded; arbitrary debug headers may be dropped.
Following these steps gives you a shipping-ready chat route backed by the Vercel AI SDK and a gateway that handles routing, fallback, and metering. The snippets above are the same shape we deploy in real services.