Skip to content
Learni
View all tutorials
Intelligence Artificielle

How to Integrate OpenRouter into an AI App in 2026

Lire en français

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

lib/openrouter.ts
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

lib/router.ts
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

lib/stream.ts
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

lib/fallback.ts
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

lib/model-selector.ts
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