Inicio → Ayuda

Un 429 de una pasarela de API significa dos cosas distintas

Lee el cuerpo, no el código de estado. Un 429 causado por saldo agotado nunca funcionará al reintentar, por mucho que esperes. Un 429 causado por congestión del upstream suele resolverse en segundos.

Lo que ves

Por qué ocurre

HTTP no tiene un estado que signifique «te has quedado sin dinero». 402 Payment Required existe pero casi nunca se usa, así que las pasarelas reutilizan 429 tanto para facturación como para limitación. Ambos son opuestos en todo lo práctico: uno es permanente hasta que actúes, el otro es transitorio y se resuelve solo.

Esto importa porque la mayoría de los ayudantes de reintento de los SDK se basan solo en el código de estado. El cliente de Python de OpenAI reintenta los 429 por defecto. Apúntalo a una pasarela sin saldo y gastará todos sus reintentos en una petición que no puede tener éxito, para luego mostrar un timeout, lo que te manda a buscar un problema de red que no existe.

Hay una tercera causa que conviene conocer, porque se parece a la segunda y se arregla de otra forma: un límite de concurrencia por cuenta. El mensaje lo dice directamente — Concurrency limit exceeded for user, please retry later. No se trata de cuántas peticiones enviaste en un minuto, sino de cuántas había en curso a la vez. Esperar ayuda, pero la solución real es limitar el paralelismo en tu cliente; aumentarlo es lo que causó el error.

Comprueba si es esta la causa

Haz una petición y mira el cuerpo en lugar del estado:

curl -s -o /tmp/r.json -w '%{http_code}\n' \
  'YOUR_BASE_URL/chat/completions' \
  -H 'Authorization: Bearer YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"model":"YOUR_MODEL","messages":[{"role":"user","content":"hi"}],"max_tokens":1}'

cat /tmp/r.json

Un código o mensaje que menciona quota, balance o credit indica facturación. Cualquier cosa que mencione rate, busy o upstream indica limitación. Si el cuerpo está vacío, busca la cabecera Retry-After: su presencia apunta a limitación.

Cómo solucionarlo

  1. Decide según el cuerpo antes de reintentarInterpreta el JSON y trata los 429 de facturación como fatales. Reintentarlos desperdicia tus reintentos y oculta la causa real detrás de un timeout.
  2. Respeta Retry-After cuando esté presenteLas respuestas de limitación suelen incluirlo. Si falta, un backoff exponencial empezando en torno a un segundo es un valor razonable; reintentar de inmediato suele empeorar la congestión.
  3. Alerta del saldo por separado de los erroresUn saldo agotado es un evento de negocio, no un incidente. La mayoría de las pasarelas exponen el saldo en su propia API o en un panel: vigila ese número y nunca verás este 429 en producción.
  4. Limita las peticiones simultáneas, no solo la tasaSi el mensaje menciona concurrencia, un bucle de reintentos más lento no ayudará — el límite cuenta peticiones simultáneas. Un semáforo alrededor de tu cliente, dimensionado a lo que permite la pasarela, lo arregla de verdad.
  5. No subas la concurrencia para arreglar un 429 de limitaciónMás peticiones en paralelo contra un upstream saturado producen más 429, no más rendimiento. Reduce la concurrencia y deja que el backoff haga su trabajo.
En APICLAN ambos se distinguen sin adivinar. Un saldo agotado devuelve {"code":"API_KEY_QUOTA_EXHAUSTED"}; la congestión del upstream devuelve {"error":{"type":"api_error","message":"Upstream rate limit exceeded, please retry later"}}. Tu saldo está en el panel, y las recargas se aplican al instante.

Relacionado

Unexpected token '<' al llamar a una API compatible con OpenAI401 invalid API key: cuando la clave parece correcta pero sigue fallando

Revisado por última vez el 2026-10-01. Escrito a partir de problemas diagnosticados en una pasarela compatible con OpenAI en producción, no recopilado de otras webs.