Browse documentation
FrameworksVercel AI SDK

Vercel AI SDK

Integrate nRouter with Vercel AI SDK in Next.js and React apps. Stream completions, utilize guardrails, and track costs while routing to any major AI model.

Last updated

The Vercel AI SDK's @ai-sdk/openai adapter works directly with nRouter. Build it with a custom baseURL — guardrails, caching, and rate-limits auto-apply server-side.

Installation

npm install ai @ai-sdk/openai

Setup

import { createOpenAI } from "@ai-sdk/openai";

const nrouter = createOpenAI({
  apiKey: process.env.NROUTER_API_KEY,
  baseURL: "https://api.nrouter.ai/v1",
});

Generate Text (Route Handler)

// app/api/chat/route.ts
import { createOpenAI } from "@ai-sdk/openai";
import { generateText } from "ai";

const nrouter = createOpenAI({
  apiKey: process.env.NROUTER_API_KEY!,
  baseURL: "https://api.nrouter.ai/v1",
});

export async function POST(req: Request) {
  const { messages } = await req.json();

  const { text } = await generateText({
    model: nrouter("claude-sonnet-4-5-20250929"),
    messages,
  });

  return Response.json({ text });
}

Streaming with useChat

// app/api/chat/route.ts
import { streamText } from "ai";

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = streamText({
    model: nrouter("gpt-5.5"),
    messages,
  });

  return result.toDataStreamResponse();
}
// app/chat/page.tsx
"use client";
import { useChat } from "ai/react";

export default function ChatPage() {
  const { messages, input, handleInputChange, handleSubmit } = useChat();

  return (
    <form onSubmit={handleSubmit}>
      {messages.map((m) => (
        <div key={m.id}>{m.role}: {m.content}</div>
      ))}
      <input value={input} onChange={handleInputChange} />
    </form>
  );
}

Per-Request Overrides

Vercel AI forwards unknown fields to nRouter via the top-level body field of generateText:

const { text } = await generateText({
  model: nrouter("gpt-5.5"),
  messages: [{ role: "user", content: "Summarize Q1 earnings..." }],
  body: {
    nrouter_prompt_template_id: "your-summarizer-id",
    nrouter_prompt_variables: { language: "Spanish" },
    nrouter_cache: false,
  },
});

Guardrails are not passed here. You assign them in the dashboard at key, team, or organization scope — the narrowest scope that mentions a guardrail wins — and they run automatically on every request that scope covers.

Tool Calling

import { generateText, tool } from "ai";
import { z } from "zod";

const { text } = await generateText({
  model: nrouter("gpt-5.5"),
  prompt: "What's the weather in Tokyo?",
  tools: {
    weather: tool({
      description: "Get the weather in a city",
      parameters: z.object({ city: z.string() }),
      execute: async ({ city }) => `72°F and sunny in ${city}`,
    }),
  },
});

Guardrails check the input before any tool executes — prompt injection in tool-calling flows is blocked at the gateway.

Next Steps

Was this page helpful?