OpenRouter para agentes IA: una API, fallbacks y créditos
Resumen
OpenRouter es un proxy OpenAI-compatible hacia cientos de modelos: una key, credits, models[] para fallback y provider para enrutar. Distinto de LiteLLM (lo operas tú) y de AI Gateway de Vercel/Cloudflare. 402 no es 429. :free son 20 RPM y 50 RPD sin créditos. La key vive fuera del prompt.

Qué resuelve
Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.
OpenRouter es un único endpoint OpenAI-compatible (https://openrouter.ai/api/v1) que enruta tu llamada a cientos de modelos. Pagas créditos en dólares. El precio de inferencia se pasa tal cual del proveedor; OpenRouter cobra fee al comprar créditos (5.5% + mínimo $0.80 por Stripe; 5% en crypto), no un markup sobre el token.
Baratear el modelo es APIs baratas. El patrón de cambiar de modelo cuando el primario no responde vive en fallback de modelos. Aquí va el cómo con OpenRouter: key, models[], provider, 402/429/503 y por qué :free no es producción. Mapa: seguridad, coste y operación. Siguiente paso: curso de instalar un agente.
Qué es y qué no es
| Pieza | Quién opera | Para qué |
|---|---|---|
| OpenRouter | Ellos | Una key, muchos labs, fallbacks y Activity en un dashboard |
| LiteLLM / proxy propio | Tú | Mismo contrato OpenAI, pero el proceso, logs y cuota son tuyos |
| Vercel / Cloudflare AI Gateway | Ellos, sobre tu key de lab | Presupuesto, allowlist y fallback del gateway, no un catálogo de terceros |
Tres integraciones oficiales (Quickstart, 2026-09-07): REST a /api/v1/chat/completions, Client SDK (@openrouter/sdk / pip install openrouter) y Agent SDK (@openrouter/agent). Si el agente ya habla OpenAI SDK, cambia baseURL; no reescribas el harness.
Arranque: key, créditos, SDK
- Cuenta en OpenRouter y créditos en Settings → Credits. Sin saldo positivo, incluso un modelo
:freepuede devolver 402. - Crea una API key en openrouter.ai/keys. Opcional: tope de crédito por key.
- La key es un secreto de runtime. Vive en el entorno, no en el system prompt. Ver secretos y variables.
Drop-in con el SDK de OpenAI (docs Authentication / OpenAI SDK):
from openai import OpenAI
import os
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.environ["OPENROUTER_API_KEY"],
)
completion = client.chat.completions.create(
extra_headers={
"HTTP-Referer": "https://tu-dominio.example",
"X-OpenRouter-Title": "agente-soporte",
},
extra_body={
"models": [
"openai/gpt-4o-mini",
"google/gemini-2.0-flash",
],
},
model="openai/gpt-4o-mini",
messages=[{"role": "user", "content": "ping"}],
)
HTTP-Referer y X-OpenRouter-Title son opcionales (app attribution). El slug ~openai/gpt-latest es un alias que resuelve al flagship actual; para un agente en producción pinnea un slug concreto y muévelo con un deploy, no con un alias mágico.
Consulta saldo y tope de la key antes de que el agente se quede mudo:
curl https://openrouter.ai/api/v1/key \
-H "Authorization: Bearer $OPENROUTER_API_KEY"
La respuesta trae limit / limit_remaining (tope de la key o null), usage_daily / usage_monthly y is_free_tier. El objeto rate_limit en esa respuesta está deprecado: ignóralo.

Fallback de modelo vs routing de proveedor
Son dos palancas distintas. Mézclalas y no sabes por qué contestó Claude cuando pediste GPT.
models[] (docs Model Fallbacks): lista de slugs en orden. Si el primero está caído, rate-limited o rechaza por moderación, OpenRouter prueba el siguiente. Eso es el fallback de modelo.
provider (docs Provider Routing): dentro del mismo modelo, elige o excluye labs. Campos útiles:
| Campo | Default | Efecto |
|---|---|---|
order | — | Labs a probar en ese orden (["anthropic","openai"]) |
allow_fallbacks | true | Si false, no hay backup cuando el primario no sirve |
only / ignore | — | Allowlist / denylist de slugs de proveedor |
data_collection | "allow" | "deny" evita labs que pueden guardar datos |
zdr | — | Solo endpoints Zero Data Retention |
sort | precio | "price" (default), "throughput" o "latency" |
require_parameters | false | Solo labs que soportan todos los params del request |
max_price | — | Techo de precio de esa llamada |
Si mandas tools o tool_choice, OpenRouter intenta labs con tool use. Si pones max_tokens, descarta labs que no pueden devolver esa longitud. Un 503 significa: ningún proveedor cumple tus filtros. Relaja only/zdr/require_parameters o añade otro modelo en models[]; no reintentes el mismo request a ciegas.
El modelo y el proveedor que sí contestaron van al log (completion.model, campo provider en el chunk). No los metas al prompt.
Códigos que tu agente debe tratar distinto
La forma de error es { error: { code, message, metadata? } }. Si la request es inválida o te quedaste sin créditos, el HTTP status es ese código. Si el modelo ya empezó a generar, puedes recibir HTTP 200 y el error en el body o en un evento SSE.
| Código | Significado | Qué hace el agente |
|---|---|---|
| 401 | Key ausente, inválida o deshabilitada | No reintentar. Rotar secreto. |
| 402 | Sin créditos o tope de key | No reintentar. Recargar o subir limit. |
| 403 | Permiso, guardrail o moderación | No reintentar el mismo input. |
| 429 | Rate limit de plataforma o del lab | Backoff. Honrar Retry-After. |
| 502 | El modelo elegido está caído o respondió basura | models[] o otro slug. |
| 503 | Ningún lab cumple el routing | Relajar provider o añadir fallback. |
OpenRouter puede mandar Retry-After en 429 y 503. Los SDK de OpenAI, Anthropic, Vercel AI y OpenRouter ya lo respetan; si usas fetch, léelo. En streaming, un 429 a mitad llega como SSE con finish_reason: "error" porque el 200 ya salió.
Esto no sustituye tu política de reintentos: 401/402/403 son fail-closed; 429/502/503 son los únicos que merecen otra vuelta, y 502/503 preferible con otro modelo, no el mismo.
:free no es un plan de producción
Docs Limits + FAQ (constantes oficiales):
- Menos de $10 en créditos históricos: 20 RPM y 50 RPD en variantes
:free. - Con al menos $10 comprados: sigue en 20 RPM, sube a 1000 RPD.
- Crear más cuentas o más keys no sube el techo: el límite es global.
- Saldo negativo → 402 también en free.
- Variante: sufijo
:freeen el slug (meta-llama/llama-3.2-3b-instruct:free). El routeropenrouter/freeelige un free por ti; útil para demos, no para un webhook.
Los modelos de pago no tienen ese cap de requests. Un 429 de lab upstream es otra historia: el router reintenta otros proveedores del mismo slug; models[] cubre cuando se acaba el slug.
Prompts y completions no se loguean por defecto. Hay opt-in (1% de descuento) en preferencias. data_collection: "deny" y zdr: true recortan labs; si ningún lab calza con tu privacy toggle, la llamada falla en vez de “arreglarse”.

Checklist de un agente sobre OpenRouter
- Una key por entorno (dev/prod) con tope de crédito.
GET /api/v1/keyen el health o en un cron, no cuando ya truena el webhook. - Slug pineado +
models[]de 2–3, del más capaz al más barato que todavía pase tus evals. provider.data_collection/zdralineados con el tipo de dato del tenant. PII de clientes no viaja a un lab que entrena.- Tratar 402 ≠ 429. El primero es caja; el segundo es cola.
- Loguear
modelefectivo yprovider. Sin eso, el fallback es folklore. - No uses
:freeniopenrouter/freedetrás de un bot con usuarios reales. - BYOK (tu key del lab por OpenRouter) tiene allowance mensual ($25k list-price pay-as-you-go, $200k enterprise) y 5% de fee encima. Úsalo si ya tienes cuota y quieres el router, no para “ahorrar la key”.
FAQ
¿OpenRouter reemplaza a Vercel AI Gateway? No. Gateway envuelve tu contrato con un lab (budget, allowlist, fallback del gateway). OpenRouter es el catálogo y el prepaid. Puedes usar ambos; no son el mismo 429.
¿Puedo pegar la key en el system prompt “para que el agente recargue”? No. 401 no se arregla con un prompt. La key no entra al contexto.
¿El alias ~openai/gpt-latest es buena idea? Para un script de un día, sí. Para un agente con evals, no: el flagship cambia debajo y tus golden cases se pudren.
¿Crypto sirve si Stripe no opera en mi país? OpenRouter acepta tarjetas, AliPay y USDC. Crypto no es reembolsable. Confirma el método en FAQ el día que recargues; no asumas PayPal.
Qué hacer hoy
Pon base_url + OPENROUTER_API_KEY en el cliente que ya tienes, pineá un slug, añade un models[] de un modelo más barato que ya evaluaste, y un check de GET /api/v1/key al arrancar. Si el 402 aparece en staging, es un win: descubriste el agujero de créditos antes del grupo de Telegram.
Lecturas relacionadas
Sigue explorando AgentOps y otras piezas para builders.

LiteLLM proxy para agentes: un gateway OpenAI frente a 100+ modelos

Timeouts y cancelación de llamadas LLM: AbortSignal, no un setTimeout decorativo

CoT vs thinking models: no pidas ‘piensa paso a paso’ al modelo que ya piensa
