Introduction
OpenRouter centralizes access to over 200 language models through a single API. For expert developers, it is a strategic tool for optimizing costs, latency, and model availability. This tutorial guides you through building a robust TypeScript client with dynamic routing, SSE streaming, and automatic fallback mechanisms. You will learn professional error handling and how to implement model selection logic based on business criteria.
Prerequisites
- Node.js 20+
- TypeScript 5.4+
- OpenRouter account with API key
- Strong knowledge of async/await and error handling
Basic Client Configuration
import { OpenAI } from 'openai';
export const openrouter = new OpenAI({
baseURL: 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY,
defaultHeaders: {
'HTTP-Referer': 'https://votre-app.com',
'X-Title': 'MonAppIA'
}
});This reusable client configures OpenRouter as an OpenAI-compatible provider. The headers are required for tracking and ranking applications on the platform.
Simple Call with Routing
export async function generateCompletion(prompt: string, model = 'anthropic/claude-3.5-sonnet') {
const response = await openrouter.chat.completions.create({
model,
messages: [{ role: 'user', content: prompt }],
temperature: 0.7,
max_tokens: 1024
});
return response.choices[0].message.content;
}Basic function to route to any OpenRouter model. Use identifiers like 'openai/gpt-4o' or 'google/gemini-1.5-pro' to switch providers instantly.
Streaming Implementation
export async function* streamCompletion(prompt: string, model: string) {
const stream = await openrouter.chat.completions.create({
model,
messages: [{ role: 'user', content: prompt }],
stream: true
});
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content;
if (content) yield content;
}
}SSE streaming is native. This generator function enables token-by-token consumption on the client side with minimal latency.
Advanced Fallback Logic
export async function generateWithFallback(prompt: string) {
const models = ['anthropic/claude-3.5-sonnet', 'openai/gpt-4o', 'google/gemini-1.5-pro'];
for (const model of models) {
try {
return await generateCompletion(prompt, model);
} catch (error) {
console.warn(`Failed on ${model}, trying next...`);
continue;
}
}
throw new Error('All models failed');
}Sequential fallback mechanism critical in production. It ensures high availability even if a provider experiences an outage.
Dynamic Model Selection
interface ModelCriteria {
maxCost: number;
minContext: number;
preferredProvider?: string;
}
export function selectModel(criteria: ModelCriteria): string {
if (criteria.maxCost < 0.5) return 'meta-llama/llama-3.1-70b';
if (criteria.minContext > 100000) return 'google/gemini-1.5-pro';
return 'anthropic/claude-3.5-sonnet';
}Intelligent routing function based on business criteria. It automatically optimizes cost and performance according to the request context.
Best Practices
- Always define HTTP-Referer and X-Title headers
- Implement timeouts and retries with exponential backoff
- Log model_id and costs for each request
- Use fallback models from different families
- Validate responses with Zod or a strict schema
Common Errors to Avoid
- Forgetting traceability headers (403 error)
- Not handling model-specific rate limits
- Using invalid model identifiers without prior validation
- Ignoring partial responses during streaming
Going Further
Discover our advanced courses on LLM architecture and intelligent routing: https://learni-group.com/formations