n4nAI

Connect Vercel AI SDK to n4n.ai's OpenAI-compatible API

Step-by-step guide to connect Vercel AI SDK to n4n.ai API via the OpenAI-compatible endpoint, covering auth, model routing, streaming, and verification.

n4n Team3 min read733 words

Audio narration

Coming soon — every post will get a voice note here.

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_KEY via env orchestration, never hardcoded.
  • Model casing: The gateway uses lowercase provider/model. GPT-4o will 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.

Tagsvercel-ai-sdkn4n-aiopenai-compatibleapi-setup

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All vercel ai sdk getting started with n4n.ai posts →