Códigos de error
Un error siempre dice qué estaba mal y, cuando es posible, qué debería haberse escrito en su lugar. Esta página enumera los casos, canal por canal, y separa lo que merece un reintento de lo que no.
#La forma de un error
El detalle lo lleva la clave detail. En los errores de validación, nombra el valor erróneo y, cuando existe una lista finita, la enumera.
{
"detail": "Symbole 'PEPEUSDT' inconnu. Valeurs acceptees : BTCUSDT, ETHUSDT, ..."
}Los rechazos ligados al plan tienen una forma fija, definida por la pasarela: status, timestamp y detail, más retry_after en los rechazos temporales (también presente en la cabecera Retry-After). La cabecera X-Deny-Reason nombra el motivo: rate, quota, family, websocket o key.
{
"status": "error",
"timestamp": 1775648290510,
"detail": "Debit depasse : votre offre autorise un nombre limite de requetes par minute.",
"retry_after": 1
}El 403 de profundidad lo devuelve la propia ruta, sin X-Deny-Reason: su detail siempre empieza por « Profondeur d’historique hors offre » e indica el limit máximo utilizable en esa temporalidad. Las ventanas por plan están en la página Límites de uso.
#Códigos HTTP
| Código | Causa | Solución |
|---|---|---|
400Petición rechazada | Un símbolo desconocido o desactivado, una profundidad por encima del límite del campo, un parámetro de indicador fuera de rango. | El cuerpo de la respuesta nombra el valor erróneo y, para un símbolo, enumera los aceptados. |
403Rechazada por el plan o por la clave de API | Cuatro motivos, indicados por la cabecera X-Deny-Reason: clave de API ausente, inválida o revocada (key); familia de datos fuera del plan (family); flujo WebSocket fuera del plan (websocket); o una profundidad de historial más allá de la ventana del plan, cuyo detail empieza por « Profondeur d’historique hors offre ». | En key, comprueba que la cabecera se envía de verdad: algunos clientes HTTP la pierden tras una redirección. En family y websocket, el dato existe pero no está en tu plan. En la profundidad, el detail indica el límite máximo que puedes usar. |
422Parámetro ausente o mal formado | symbol ausente, temporalidad fuera de la lista, campo multitemporalidad solicitado sin el sufijo @tf, campo desconocido en ?fields=, cuerpo JSON no válido. | En ?fields=, la respuesta sugiere el campo más parecido. En una temporalidad, enumera los valores aceptados. |
429Velocidad o cuota superada | O más peticiones por minuto de las que permite tu plan, o una ráfaga demasiado densa (X-Deny-Reason: rate, Retry-After: 1); o la cuota mensual de la cuenta está agotada (X-Deny-Reason: quota, Retry-After: 3600). | En rate, espera el segundo que indica Retry-After. En quota, el contador se reinicia el primer día del mes (UTC); también puedes cambiar de plan desde la consola. |
503Indisponibilidad momentánea | Una dependencia de lectura se está recuperando, o se ha alcanzado el límite de conexiones simultáneas del flujo. | Reinténtalo tras el plazo que indica Retry-After. El error es transitorio por naturaleza. |
500Error inesperado | Un fallo del servicio, nunca causado por la petición. | Reinténtalo; si la respuesta persiste, notifícala con la marca de tiempo que lleva la respuesta. |
Las confusiones más frecuentes
| Síntoma | Causa real |
|---|---|
| 403 aunque la clave sea válida | Lee X-Deny-Reason. family: la familia de este endpoint no está en tu plan. websocket: el flujo no está incluido. Un detail « Profondeur d’historique hors offre »: la petición va más allá de la ventana del plan. key sin motivo aparente: un cliente HTTP que pierde las cabeceras personalizadas tras una redirección; llama a la URL final. |
| 429 aunque el ritmo sea bajo | Lo que se ha agotado es la cuota mensual de la cuenta (X-Deny-Reason: quota, Retry-After: 3600), no el límite de velocidad. Se reinicia el primer día del mes, en UTC, o en cuanto cambia el plan. |
| 422 sin mensaje claro en un snapshot | Un campo multitemporalidad pedido sin su sufijo @tf, o lo contrario en un campo de forma única. |
| 400 en una profundidad que parece razonable | Cada campo del snapshot tiene su propio límite, en su propia unidad. El CVD llega hasta 200 ventanas, los diferenciales entre mercados hasta 50. |
| 422 en una temporalidad válida en otro sitio | El ratio largo/corto rechaza 1m, los instrumentos macro intradía rechazan 30m y la semana solo existe en los indicadores. |
| Una respuesta vacía que no es un error | Una stablecoin en una métrica de futuros, u opciones en un activo distinto de BTC y ETH. La clave unavailable del snapshot dice cuál de los tres motivos se aplica. |
| Un parámetro ignorado | Las claves desconocidas del snapshot se ignoran en silencio. Un campo mal escrito simplemente no aparece en la respuesta. |
#Indicadores
La validación sigue un orden fijo (temporalidad, número de resultados, símbolo, análisis de los indicadores, regla del límite, lectura de las velas), y gana el primer fallo. Un cuerpo corregido puede por tanto revelar un segundo error.
| Caso | Código |
|---|---|
| Temporalidad no válida, results inferior a 1, símbolo desconocido | 400 |
| Lista indicators vacía, o una entrada que no es un objeto | 400 |
| Falta la clave id o type, id mal formado para este tipo | 400 |
| Tipo no admitido | 400 |
| Parámetro desconocido para este tipo (obv con un periodo, por ejemplo) | 400 |
| Parámetro del tipo equivocado, o inferior a su mínimo | 400 |
| macd o adosc con fast mayor o igual que slow | 400 |
| sar con acceleration mayor que maximum | 400 |
| Identificador duplicado | 400 |
| Cuerpo mal formado, más de 50 instancias, campo demasiado largo | 422 |
| results más warm-up supera 1000 | 422 |
| Datos insuficientes para esta temporalidad, stablecoins incluidas | 422 |
#Flujo WebSocket
Toda petición imposible recibe un mensaje op: error que dice lo que se esperaba: la lista de símbolos válidos, la de los canales, los límites de depth. Tres situaciones no producen un error sino un cierre:
| Código | Motivo |
|---|---|
| 4003 · límite | Se alcanzó el límite de conexiones simultáneas del plan. El motivo indica el límite. Una desconexión libera su plaza al instante. |
| 4003 · cliente demasiado lento | La cola de envío se ha desbordado diez veces. Consume más rápido o reduce el número de canales. El motivo distingue ambos casos. |
| 4001 | Trama de auth explícita rechazada: la clave que lleva es inválida. |
| 4002 | Sesión nunca autenticada en cinco segundos. Un caso residual, ya que la clave se comprueba en el handshake. |
La clave se comprueba en el handshake, antes de la apertura: una clave ausente o inválida, o un plan sin el flujo (Free), recibe un 403 en el handshake, con X-Deny-Reason key o websocket. Un 429 en ese momento indica un ritmo de apertura demasiado alto. Una vez conectado, un canal cuya familia no está en el plan recibe op: error (« canal … hors offre : la famille … n’est pas incluse dans votre abonnement ») y se rechaza toda la suscripción. Ver Límites de uso.
#Servidor MCP
Los errores siguen un único patrón, Erreur (HTTP NNN) : message, para que un agente solo tenga un caso que reconocer. Cada llamada de herramienta se evalúa como una petición REST con la clave del cliente: un 403 por una familia fuera del plan o un 429 por cuota se devuelven tal cual, con su detail. Dos familias le son propias:
- Métrica desconocida: el mensaje enumera las cuarenta y seis métricas válidas.
- Selección no válida: dos objetivos a la vez, objetivo ausente, objetivo equivocado o un objetivo pasado a una métrica de todo el mercado. El error nombra el parámetro esperado y se produce antes de cualquier llamada de red.
Un fallo del servidor provoca un reintento automático antes de notificarse. Un tiempo de espera agotado devuelve Erreur (HTTP 504) tras treinta segundos.
#Estrategia de reintentos
No todo se puede repetir. Repetir una petición errónea produce exactamente la misma respuesta y consume cuota para nada.
def should_retry(code: int) -> bool:
"""What is transient, and what never will be."""
# 429 and 503 will pass: the server says when.
if code in (429, 503):
return True
# 500: a fault on the service side, a retry makes sense.
if code == 500:
return True
# 400, 403, 422: the request is at fault. Replaying it as is will
# produce exactly the same response.
return False- Respeta
Retry-Afteren lugar de inventar un plazo: el servidor sabe cuándo estará listo. - Limita el número de intentos. Tres o cuatro bastan: más allá, el problema no es pasajero.
- No repitas un 4xx, salvo el 429. Corrige la petición.
- En el flujo, reconéctate con un plazo creciente, y trata un cierre
4003como señal de sobrecarga en el cliente: reconectarte sin cambiar el consumo reproducirá el corte.