Cookbook
Copy-paste recipes for the things teams build most often. Each one is complete: paste, set your key, run.
The cheapest model that supports tools
Filter the catalog by capability and price instead of hard-coding a model. The same query powers the MCP search_models tool.
import { ElevenRouter } from '@elevenrouter/sdk';
const client = new ElevenRouter();
const { data } = await client.models.list();
const perMillion = (v?: string) => Number(v ?? 0) * 1_000_000;
const candidates = data
.filter((m) => m.supported_parameters.includes('tools') && m.availability !== 'unavailable' && (m.context_length ?? 0) >= 128_000)
.sort((a, b) => perMillion(a.pricing.prompt) + perMillion(a.pricing.completion) - (perMillion(b.pricing.prompt) + perMillion(b.pricing.completion)));
const [primary, fallback] = candidates;
const res = await client.chat.completions.create({
model: primary!.id,
models: fallback ? [fallback.id] : undefined,
tools: [{ type: 'function', function: { name: 'lookup_order', parameters: { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] } } }],
messages: [{ role: 'user', content: 'Where is order 4821?' }],
});Reliable JSON extraction
Ask for a schema, let the gateway repair malformed output, and validate. Works on models without native structured outputs because response-healing fixes trailing commas, fences and truncated objects before you see them.
from elevenrouter import ElevenRouter
client = ElevenRouter()
schema = {"type": "object", "properties": {"name": {"type": "string"}, "total": {"type": "number"}, "currency": {"type": "string"}}, "required": ["name", "total"]}
res = client.chat.completions.create(
model="openai/gpt-5.6-luna",
temperature=0,
response_format={"type": "json_schema", "json_schema": {"name": "invoice", "schema": schema}},
plugins=[{"id": "response-healing"}],
messages=[{"role": "user", "content": f"Extract the invoice fields as JSON:\n{invoice_text}"}],
)
data = json.loads(res["choices"][0]["message"]["content"])Long documents without overflow
middle-out trims the least important middle of a conversation when it exceeds the model's context, keeping the system prompt and the latest turns. Combined with a cheap fallback that has a bigger window, long inputs never fail.
curl https://elevenrouter.com/api/v1/chat/completions -H "Authorization: Bearer $ELEVENROUTER_API_KEY" -H "Content-Type: application/json" -d '{
"model": "anthropic/claude-sonnet-5",
"models": ["openai/gpt-5.6-terra"],
"transforms": ["middle-out"],
"messages": [{ "role": "system", "content": "Summarise the document." }, { "role": "user", "content": "<very long text>" }]
}'One key per customer (SaaS metering)
Create an inference key per tenant with its own monthly limit through the management API, then bill from Activity or the analytics API grouped by key. Delete the key to cut a tenant off instantly.
const admin = new ElevenRouter({ apiKey: process.env.ELEVENROUTER_MANAGEMENT_KEY });
// On tenant signup
const { data: key, key: plaintext } = await admin.keys.create({
name: `tenant-${tenant.id}`,
workspace_id: 'production',
limit: tenant.plan.monthlyUsd,
limit_reset: 'monthly',
allowed_models: ['openai/gpt-5.6-luna', 'anthropic/claude-haiku-4.5'],
});
await vault.store(tenant.id, plaintext);
// Month-end: spend per tenant
const usage = await admin.analytics.query({ range: { from, to }, metrics: ['cost', 'requests'], dimensions: ['api_key'] });Cost per conversation
Send the same X-ER-Session-Id on every turn of a conversation. Logs → Sessions groups the turns and sums their cost; the analytics API can do the same with the session dimension.
const res = await client.chat.completions.create(
{ model: 'anthropic/claude-sonnet-5', messages },
{ headers: { 'X-ER-Session-Id': conversationId, 'X-ER-User-Id': userId } },
);Cache-aware chat
Put the stable prefix (system prompt, documents) first with a cache_control breakpoint so the vendor bills cache reads, and turn on the response cache for repeated identical prompts.
curl https://elevenrouter.com/api/v1/chat/completions \
-H "Authorization: Bearer $ELEVENROUTER_API_KEY" -H "Content-Type: application/json" \
-H "X-ER-Cache: true" -H "X-ER-Cache-TTL: 3600" \
-d '{
"model": "anthropic/claude-sonnet-5",
"messages": [
{ "role": "system", "content": [{ "type": "text", "text": "<policy manual, 40k tokens>", "cache_control": { "type": "ephemeral", "ttl": "1h" } }] },
{ "role": "user", "content": "What is the refund window?" }
]
}'
# Second identical call: X-ER-Cache: HIT, cost $0Guardrails for a user-facing bot
Redact personal data before it leaves your account, flag injection attempts while you tune, cap cost per request, and pin the whole configuration to the bot's key as a preset.
M="Authorization: Bearer $ELEVENROUTER_MANAGEMENT_KEY"; B=https://elevenrouter.com/api/v1/management
curl -X POST $B/policies -H "$M" -d '{
"name": "Support bot guardrails",
"rules": {
"sensitiveInfo": { "action": "redact", "detectors": ["email", "phone", "card", "secret"], "direction": "input" },
"promptInjection": { "action": "flag" },
"limits": { "maxCostUsdPerRequest": 0.25, "maxOutputTokens": 1200 }
},
"assignments": [{ "target_type": "api_key", "target_id": "<bot key id>" }]
}'
curl -X POST $B/presets -H "$M" -d '{ "slug": "support-bot", "name": "Support bot", "config": { "models": ["anthropic/claude-sonnet-5", "openai/gpt-5.6-terra"], "systemPrompt": "You are the support assistant…", "parameters": { "temperature": 0.3, "max_tokens": 800 } } }'
curl -X PATCH https://elevenrouter.com/api/v1/keys/<bot key id> -H "$M" -d '{ "preset_id": "support-bot" }'Claude models through the Anthropic SDK — and GPT too
Point the Anthropic SDK at https://elevenrouter.com/api/v1; the Messages endpoint accepts any model in the catalog, so the same client can call GPT or Gemini with Anthropic-style requests.
import anthropic
client = anthropic.Anthropic(base_url="https://elevenrouter.com/api/v1", api_key=os.environ["ELEVENROUTER_API_KEY"])
msg = client.messages.create(model="openai/gpt-5.6-luna", max_tokens=300, messages=[{"role": "user", "content": "Hello from the Anthropic SDK"}])More recipes live in the integrations guide (Vercel AI SDK, LangChain, LiteLLM, PydanticAI, coding agents) and the SDK reference.