LLM integration with OpenRouter
OpenRouter is a unified API gateway to hundreds of language models from providers such as OpenAI, Anthropic, Google, and Meta. You use one API key and one billing surface, and swap models by changing a provider/model slug. OpenRouter exposes a Chat Completions-compatible HTTP API.
This post shows three Node.js integration paths: the official @openrouter/sdk, the openai package with baseURL, and the Vercel AI SDK with @openrouter/ai-sdk-provider.
For deeper patterns on each stack, see the Chat Completions API, OpenAI Responses API (OpenAI direct only), and Vercel AI SDK posts.
Prerequisites
- OpenRouter account
- API key
- Credits or billing enabled as needed
- Node.js version 26
- Install packages for the path you use:
@openrouter/sdk(npm i @openrouter/sdk)openai(npm i openai)aiand@openrouter/ai-sdk-provider(npm i ai @openrouter/ai-sdk-provider)
Configuration
Read credentials from the environment in production.
| Variable | Purpose |
|---|---|
OPENROUTER_API_KEY | Bearer token from OpenRouter settings |
OPENROUTER_MODEL | Default model slug, for example openai/gpt-5.5 |
OPENROUTER_SITE_URL | Optional site URL sent as HTTP-Referer for rankings on openrouter.ai |
OPENROUTER_SITE_TITLE | Optional app name sent as X-OpenRouter-Title |
Model IDs use the provider/model format, for example openai/gpt-5.5, anthropic/claude-opus-4.8, or google/gemini-3.1-flash-lite. Browse the full catalog at openrouter.ai/models.
The examples below use openai/gpt-5.5, matching the model in the other LLM posts in this series. Override it with OPENROUTER_MODEL when you want a different model.
@openrouter/sdk
OpenRouter's official TypeScript SDK is type-safe and generated from the OpenAPI spec.
Client setup
import { OpenRouter } from '@openrouter/sdk';const client = new OpenRouter({apiKey: process.env.OPENROUTER_API_KEY,httpReferer: process.env.OPENROUTER_SITE_URL,appTitle: process.env.OPENROUTER_SITE_TITLE,});
Basic integration
const response = await client.chat.send({chatRequest: {model: process.env.OPENROUTER_MODEL ?? 'openai/gpt-5.5',messages: [{ role: 'user', content: 'Write a one-sentence bedtime story about a unicorn.' },],},});console.log(response.choices[0].message.content);
System prompt
Add a system message before the user turn to set tone, format, and role.
const response = await client.chat.send({chatRequest: {model: process.env.OPENROUTER_MODEL ?? 'openai/gpt-5.5',messages: [{ role: 'system', content: 'Reply in one short sentence. Use plain language.' },{ role: 'user', content: 'Explain what an LLM is.' },],},});console.log(response.choices[0].message.content);
Streaming
Set stream: true and read incremental text from choices[0].delta.content.
const stream = await client.chat.send({chatRequest: {model: process.env.OPENROUTER_MODEL ?? 'openai/gpt-5.5',messages: [{ role: 'user', content: 'List three colors.' }],stream: true,},});process.stdout.write('[stream] ');for await (const chunk of stream) {const delta = chunk.choices[0]?.delta?.content;if (delta) {process.stdout.write(delta);}}process.stdout.write('\n');
Model switching
Change only the model string to route the same code to a different provider.
const models = ['openai/gpt-5.5', 'google/gemini-3.1-flash-lite'];for (const model of models) {const response = await client.chat.send({chatRequest: {model,messages: [{ role: 'user', content: 'Reply with exactly one word: ok.' }],},});console.log(model, '->', response.choices[0].message.content);}
openai package
If you already use the OpenAI SDK, point it at OpenRouter with baseURL. The request shape matches the Chat Completions API.
Client setup
import OpenAI from 'openai';const client = new OpenAI({apiKey: process.env.OPENROUTER_API_KEY,baseURL: 'https://openrouter.ai/api/v1',defaultHeaders: {'HTTP-Referer': process.env.OPENROUTER_SITE_URL,'X-OpenRouter-Title': process.env.OPENROUTER_SITE_TITLE,},});
Basic integration
const completion = await client.chat.completions.create({model: process.env.OPENROUTER_MODEL ?? 'openai/gpt-5.5',messages: [{ role: 'user', content: 'Write a one-sentence bedtime story about a unicorn.' },],});console.log(completion.choices[0].message.content);
System prompt
const completion = await client.chat.completions.create({model: process.env.OPENROUTER_MODEL ?? 'openai/gpt-5.5',messages: [{ role: 'system', content: 'Reply in one short sentence. Use plain language.' },{ role: 'user', content: 'Explain what an LLM is.' },],});console.log(completion.choices[0].message.content);
Streaming
const stream = await client.chat.completions.create({model: process.env.OPENROUTER_MODEL ?? 'openai/gpt-5.5',messages: [{ role: 'user', content: 'List three colors.' }],stream: true,});process.stdout.write('[stream] ');for await (const chunk of stream) {const delta = chunk.choices[0]?.delta?.content;if (delta) {process.stdout.write(delta);}}process.stdout.write('\n');
For JSON schema output, Markdown-to-HTML, and few-shot prompting, reuse the patterns from the Chat Completions post with the OpenRouter client and model slug above.
Vercel AI SDK
The @openrouter/ai-sdk-provider package exposes OpenRouter models to generateText, streamText, and related helpers from the ai package. See the OpenRouter Vercel AI SDK guide for the full integration reference.
Client setup
import { createOpenRouter } from '@openrouter/ai-sdk-provider';const openrouter = createOpenRouter({apiKey: process.env.OPENROUTER_API_KEY,appUrl: process.env.OPENROUTER_SITE_URL,appName: process.env.OPENROUTER_SITE_TITLE,});
The returned provider is callable. Pass a model slug directly: openrouter('openai/gpt-5.5').
Basic integration
import { generateText } from 'ai';const { text } = await generateText({model: openrouter(process.env.OPENROUTER_MODEL ?? 'openai/gpt-5.5'),prompt: 'Write a one-sentence bedtime story about a unicorn.',});console.log(text);
System prompt
const { text } = await generateText({model: openrouter(process.env.OPENROUTER_MODEL ?? 'openai/gpt-5.5'),system: 'Reply in one short sentence. Use plain language.',prompt: 'Explain what an LLM is.',});console.log(text);
Streaming
import { streamText } from 'ai';const result = streamText({model: openrouter(process.env.OPENROUTER_MODEL ?? 'openai/gpt-5.5'),prompt: 'List three colors.',});process.stdout.write('[stream] ');for await (const part of result.textStream) {process.stdout.write(part);}process.stdout.write('\n');
For structured output, embeddings, and web search, see the Vercel AI SDK post. Those patterns apply when you call OpenAI directly; OpenRouter coverage depends on the model and endpoint.
Demo
Runnable scripts for each integration path live in the openrouter-demo folder. Get access via code demos.