Vercel AI SDK on one API key
One RelaySwitch key in the AI SDK's OpenAI-compatible provider reaches every chat model on the Models page, billed per token from a prepaid balance you top up by card or crypto.
A Vercel AI SDK API key setup here is one provider block: createOpenAICompatible with the base URL https://api.relayswitch.io/v1 and a RelaySwitch key. After that, generateText, streamText and tool calls take any model id from the Models page, Claude ids included, with no second provider package and no second key.
There is no subscription. You pay as you go: each request bills its tokens at the live catalog price against a balance you prepaid by card (Card) or crypto (USDT, USDC, BTC, ETH, SOL). This guide writes the provider, shows the three calls, prices a chat turn on each model and lists the errors you can hit.
01What you need
- A Node.js or Next.js project on the AI SDK (
aion npm). - A RelaySwitch key. Sign in with an email code at the console and create one under Keys. Keys start with
sk-relay-; the full key shows once at creation, so copy it then. - A balance. Top-ups start at $10, by card or crypto, with no subscription and no KYC. Before the first top-up the console chat gives you 12 free turns a day to try models; SDK requests bill the balance.
02Vercel AI SDK API key and provider setup
- Install the SDK core and the OpenAI-compatible provider package.bash1
pnpm add ai @ai-sdk/openai-compatible - Put the key in the environment, never in source. One key per app keeps the console Usage page readable.bash1
# .env.local (Next.js reads it; other runtimes use dotenv or the shell)2RELAYSWITCH_KEY=sk-relay-... - Build the provider once in a shared module and import it wherever you call a model.ts1
// lib/relayswitch.ts2// Options per the AI SDK OpenAI-compatible providers docs, read 2026-10-28:3// https://ai-sdk.dev/providers/openai-compatible-providers4import { createOpenAICompatible } from '@ai-sdk/openai-compatible';56export const relayswitch = createOpenAICompatible({7name: 'relayswitch',8baseURL: 'https://api.relayswitch.io/v1',9apiKey: process.env.RELAYSWITCH_KEY,10// Adds token counts to streamed answers (stream_options.include_usage).11includeUsage: true,12});
name labels the provider inside the SDK; it is also the key under providerOptions if you ever pass provider-specific options. baseURL keeps the /v1; the SDK appends /chat/completions. apiKey goes out as a Bearer token. Option names follow the OpenAI-compatible providers docs (read 2026-10-28).
03generateText, streamText and tools
relayswitch(id) returns a chat model, the same as relayswitch.chatModel(id). The id is the one the Models page shows, with no vendor prefix.
import { generateText } from 'ai';import { relayswitch } from '@/lib/relayswitch'; const { text, usage } = await generateText({ model: relayswitch('claude-sonnet-5-5'), prompt: 'Explain what an API gateway does in one sentence.',});console.log(text, usage);Streaming uses the same model object. With includeUsage on, the final chunk carries the token counts, so the result.usage promise resolves after the stream ends (streamText reference, read 2026-10-28).
import { streamText } from 'ai';import { relayswitch } from '@/lib/relayswitch'; const result = streamText({ model: relayswitch('claude-sonnet-5-5'), system: 'Answer in plain English.', messages: [{ role: 'user', content: 'Count to five.' }],});for await (const part of result.textStream) { process.stdout.write(part);}console.log(await result.usage); // present because includeUsage is onTool calling works the SDK way: each entry in tools is a tool() with a description, an inputSchema and an execute function, and stopWhen: stepCountIs(n) bounds a multi-step run (tool calling docs, read 2026-10-28). Every chat model answers the OpenAI chat completions format, and the Claude ids answer it as well as the Anthropic one, so the same provider covers Claude, GPT, Gemini, DeepSeek and GLM.
If @ai-sdk/openai is already in the project, it works here with the base URL set. Pick the Chat Completions factory:
// If @ai-sdk/openai is already in the project. Its default factory uses the// Responses API; openai.chat() selects Chat Completions (docs read 2026-10-28:// https://ai-sdk.dev/providers/ai-sdk-providers/openai).import { createOpenAI } from '@ai-sdk/openai'; const openai = createOpenAI({ baseURL: 'https://api.relayswitch.io/v1', apiKey: process.env.RELAYSWITCH_KEY,});const model = openai.chat('claude-sonnet-5-5');04Which model to pick
A chat app resends the whole conversation every turn, so the input rate is most of the bill once a thread is long. The output rate matters for long answers and code generation. Of the models here, Claude Haiku 5.5 has the lowest input rate today at $0.0582 per million tokens.
| Model | Input | Cached | Output | Developer list in / out | Context |
|---|---|---|---|---|---|
| Claude Sonnet 5.5 | $1.20 (40% under) | $0.075 | $3.00 (70% under) | $2.00 / $10.00 | 1M tokens |
| Claude Opus 5.5 | $2.716 (32% under) | $0.1455 | $9.70 (51% under) | $4.00 / $20.00 | 1M tokens |
| Claude Haiku 5.5 | $0.0582 (41% under) | $0.01 | $0.1455 (70% under) | $0.10 / $0.50 | 1M tokens |
| GPT-5.5 | $1.80 (64% under) | $0.16 | $9.00 (70% under) | $5.00 / $30.00 | 1.1M tokens |
| GPT-6.1 Sol | $0.582 (70% under) | $0.0582 | $2.91 (70% under) | $2.00 / $10.00 | 1.1M tokens |
| Gemini 4 Argon | $0.60 (70% under) | $0.06 | $3.00 (70% under) | $2.00 / $10.00 | 1M tokens |
| DeepSeek V4 Pro 0423 | $0.792 (40% under) | $0.0264 | $2.376 (40% under) | $1.32 / $3.96 | 1M tokens |
| GLM 5.3 | $0.3178 (70% under) | $0.066 | $0.9987 (70% under) | $1.092 / $3.432 | 1M tokens |
USD per million tokens, read from the RelaySwitch catalog when this page was built. Developer list: the catalog's record of the developer's own price.
Swapping models is one string: change the id in relayswitch(id). The full list, with every price and context size, is on the Models page. How the balance and the cached rate work is on Pricing.
05What a chat turn costs
The turn: 2,000 input tokens (a system prompt plus a short history) and 500 output tokens back. Those sizes are an assumption; the usage object on each result and the console Usage page show the real ones.
| Model | Input / M | Output / M | One turn |
|---|---|---|---|
| Claude Haiku 5.5 | $0.0582 | $0.1455 | $0.00019 |
| GLM 5.3 | $0.3178 | $0.9987 | $0.0011 |
| GPT-6.1 Sol | $0.582 | $2.91 | $0.0026 |
| Gemini 4 Argon | $0.60 | $3.00 | $0.0027 |
| DeepSeek V4 Pro 0423 | $0.792 | $2.376 | $0.0028 |
| Claude Sonnet 5.5 | $1.20 | $3.00 | $0.0039 |
| GPT-5.5 | $1.80 | $9.00 | $0.0081 |
| Claude Opus 5.5 | $2.716 | $9.70 | $0.0103 |
2,000 in and 500 out at the live per-token prices when this page was built. Cached input, where the model has a cached rate, bills lower.
The same turn runs $0.00019 on Claude Haiku 5.5 and $0.0103 on Claude Opus 5.5. A cheap model for routine turns and a dear one for the hard question is a reasonable split; the provider block does not change.
06Check the key before the SDK
Two curl calls rule out the key and the base URL before you debug the SDK. The first lists every model id your key can call:
curl https://api.relayswitch.io/v1/models -H "Authorization: Bearer sk-relay-..."The second sends one small request the way the SDK does. -i prints the headers, including the request id and, on a non-streamed answer, the charge in USD.
curl -i https://api.relayswitch.io/v1/chat/completions \ -H "Authorization: Bearer sk-relay-..." \ -H "Content-Type: application/json" \ -d '{"model": "claude-sonnet-5-5", "messages": [{"role": "user", "content": "Say ok."}]}'If both work, any failure left is in the provider block. Each SDK call then shows on the console's Usage page within seconds, with its tokens and its charge.
07Errors and fixes
401: the key is wrong, revoked or unset.process.env.RELAYSWITCH_KEYis undefined when.env.localis missing or the variable name differs. Paste the key again from the console and run the curl check.402: the balance is too low for the request. Top up in the console; the key works again at once.404on the model: the id is not in the catalog. Check for a typo or a display name in place of the id.404on the route: the base URL is missing/v1or carries a trailing path. Usehttps://api.relayswitch.io/v1exactly.429: the key hit its rate limit. Back off and retry, or create a key with a higher Requests / min in the console.result.usageis empty on a stream:includeUsageis off. Set it totruein the provider block.400from@ai-sdk/anthropicon a non-Claude id: that package sends the Anthropic format to/v1/messages, which only the Claude ids answer. The OpenAI-compatible provider covers Claude and the rest with no second package.
Questions
- Which base URL does the Vercel AI SDK need?
- https://api.relayswitch.io/v1, with the /v1 at the end. The OpenAI-compatible provider appends /chat/completions to it.
- Does the Vercel AI SDK work with Claude on one key?
- Yes. The Claude ids on RelaySwitch answer the OpenAI chat completions format, so relayswitch('claude-sonnet-5-5') works with generateText, streamText and tool calls, with no @ai-sdk/anthropic package and no second key.
- Is there a free Vercel AI SDK API key?
- Keys are free to create, and the console chat runs 12 free turns a day before your first top-up. SDK requests bill a prepaid balance, from $10, by card or crypto.
- Do I need a subscription?
- No. You pay as you go: each request bills its tokens at the live catalog price against credit you prepaid with Card or USDT, USDC, BTC, ETH, SOL. There is no monthly fee and no KYC.
- How do I see what each request cost?
- Every result carries a usage object with the token counts, and the console Usage page lists each request with its tokens and its charge in USD. On a non-streamed curl call the charge is in the response headers.
- Can I use @ai-sdk/openai instead of @ai-sdk/openai-compatible?
- Yes. createOpenAI with baseURL set to https://api.relayswitch.io/v1 and your RelaySwitch key works; use openai.chat(id) for the Chat Completions API. The OpenAI-compatible provider is the shorter path for a mixed model list.