From OpenAI

Two-line diff. Swap `baseURL` and key, keep the rest of your OpenAI code.

CleverRouter speaks the OpenAI wire format. For most apps, migration is two lines.

The minimal diff

client.ts
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY!,
});

const res = await client.chat.completions.create({
  model: 'gpt-4o-mini',
  messages: [{ role: 'user', content: 'Hello.' }],
});
client.ts
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: process.env.CLEVERROUTER_API_KEY!,
  baseURL: 'https://api.cleverouter.eu/v1',
});

const res = await client.chat.completions.create({
  model: 'mistral/mistral-small-3.2', // an EU-hosted equivalent
  messages: [{ role: 'user', content: 'Hello.' }],
});

Two lines: the baseURL, and the model id.

Optional: use the typed SDK

If you want autocomplete, typed errors, and direct helpers for embed / rerank / transcribe, add @cleverrouter/sdk:

bun add @cleverrouter/sdk@alpha
import { createCleverRouter } from '@cleverrouter/sdk';

const cr = createCleverRouter({
  apiKey: process.env.CLEVERROUTER_API_KEY!,
});

// Exactly the same OpenAI SDK, pre-configured against the gateway:
const res = await cr.openai().chat.completions.create({
  model: 'mistral/mistral-small-3.2',
  messages: [{ role: 'user', content: 'Hello.' }],
});

Model mapping cheat sheet

OpenAI modelSuggested EU equivalentNotes
gpt-4o-minimistral/mistral-small-3.2Fast, tool calls, JSON
gpt-4omistral/mistral-large-2Stronger reasoning, EU-only
gpt-4o (vision)mistral/pixtral-large-latestMultimodal Pixtral
o3-mini / o1-minideepseek/deepseek-r1-distill-llama-70bReasoning-capable
text-embedding-3-smallcohere/embed-v4Multilingual
text-embedding-3-largecohere/embed-v4 with dimensions: 1536Adjustable dimensions
whisper-1systran/faster-whisper-large-v3Faster Whisper, EU

Browse the live catalog at cleverouter.eu/models.

What stays the same

  • Streaming. SSE in OpenAI chunk format.
  • Tool calls. OpenAI function-call shape.
  • Vision. type: 'image_url' content parts.
  • JSON mode. response_format: { type: 'json_object' }.
  • Python SDK, LangChain, LlamaIndex. Anything that takes a base_url.

What changes

  • API keys are CleverRouter-issued (cr_live_*), not OpenAI's.
  • Model IDs follow <family>/<model> — no bare gpt-4o-mini.
  • Zero data retention by default. If your existing audit logs rely on retained content from your AI provider, you'll need to do that logging yourself.
  • EU-only. If a model isn't hosted in the EU, it's not in the catalog.

Tool deltas in streams

Mistral and Anthropic-via-Bedrock emit parallel tool calls more often than gpt-4o-mini. Make sure your tool loop collects all calls before dispatching — see Function calling.