Skip to main content
This guide shows you how to route the Vercel AI SDK through the to11 gateway using the OpenAI provider with a custom base URL.
These examples use the AI SDK 5+ API (inputSchema, message.parts, toUIMessageStreamResponse). On AI SDK 4 the option and method names differ.

Installation

npm install ai@^5 @ai-sdk/openai @ai-sdk/react

Configuration

Create an OpenAI provider instance pointing at the to11 gateway:
import { createOpenAI } from "@ai-sdk/openai";

const to11 = createOpenAI({
  baseURL: "https://gw.to11.ai/v1",
  apiKey: "<your OpenAI API key>", // provider credential, forwarded upstream
  headers: {
    "x-to11-authorization": "Bearer <your to11 API key>", // to11 auth — Settings → API keys
    "x-to11-project-id": "<your project id>",
  },
});

Generate text

import { generateText } from "ai";

const { text } = await generateText({
  model: to11("gpt-4o"),
  prompt: "Hello from to11!",
});
console.log(text);

Stream text

import { streamText } from "ai";

const result = streamText({
  model: to11("gpt-4o"),
  prompt: "Count to 10",
});

for await (const chunk of result.textStream) {
  process.stdout.write(chunk);
}

Use with Next.js

In a Next.js route handler:
// app/api/chat/route.ts
import { streamText, convertToModelMessages, type UIMessage } from "ai";
import { createOpenAI } from "@ai-sdk/openai";

const to11 = createOpenAI({
  baseURL: "https://gw.to11.ai/v1",
  apiKey: process.env.OPENAI_API_KEY!,
  headers: {
    "x-to11-authorization": `Bearer ${process.env.TO11_API_KEY!}`,
    "x-to11-project-id": process.env.TO11_PROJECT_ID!,
  },
});

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

  const result = streamText({
    model: to11("gpt-4o"),
    messages: convertToModelMessages(messages),
  });

  return result.toUIMessageStreamResponse();
}
On the client side, the useChat hook posts to /api/chat by default. Manage the input yourself and send messages with sendMessage:
// components/chat.tsx
"use client";
import { useChat } from "@ai-sdk/react";
import { useState } from "react";

export default function Chat() {
  const [input, setInput] = useState("");
  const { messages, sendMessage } = useChat();

  return (
    <div>
      {messages.map((message) => (
        <div key={message.id}>
          {message.role === "user" ? "User: " : "AI: "}
          {message.parts.map((part, i) =>
            part.type === "text" ? <span key={i}>{part.text}</span> : null,
          )}
        </div>
      ))}
      <form
        onSubmit={(e) => {
          e.preventDefault();
          sendMessage({ text: input });
          setInput("");
        }}
      >
        <input value={input} onChange={(e) => setInput(e.target.value)} />
      </form>
    </div>
  );
}

Cross-format routing

The to11 gateway routes based on the model field. You can target Anthropic models through the same OpenAI provider:
const { text } = await generateText({
  model: to11("claude-sonnet-4-6"),
  prompt: "Hello from to11!",
});
The gateway translates the OpenAI-format request to Anthropic format and returns the response in OpenAI format, so the Vercel AI SDK works without changes.

Tool calling

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

const { text, toolCalls } = await generateText({
  model: to11("gpt-4o"),
  prompt: "What's the weather in Paris?",
  tools: {
    getWeather: tool({
      description: "Get current weather for a location",
      inputSchema: z.object({
        location: z.string(),
      }),
      execute: async ({ location }) => {
        return { temperature: 18, unit: "celsius", location };
      },
    }),
  },
});