Errores y límites de solicitudes

Errores y límites de solicitudes

Todos los endpoints informan de los fallos con la misma estructura, con un código legible por máquina y un ID de solicitud.

Respuesta de error

Una llamada fallida devuelve success: false. code es estable y está pensado para programas, error es un mensaje breve en inglés pensado para personas, y request_id identifica la llamada en nuestros registros. param indica el parámetro causante cuando el problema está en los datos de entrada.

Ejemplos reales

Estas son respuestas en vivo, obtenidas de la API al generar esta página.

Falta un parámetro obligatorio · GET /api/sd/oi · HTTP 400
{
  "success": false,
  "error": "coin required",
  "code": "INVALID_PARAM",
  "request_id": "cb-mwefuknz-6c036f864c"
}
Endpoint desconocido · HTTP 404
{
  "success": false,
  "code": "NOT_FOUND",
  "error": "unknown endpoint: GET /api/this-endpoint-does-not-exist",
  "request_id": "cb-mwefuknz-7768c7f02d"
}

Códigos de error

CódigoHTTPSignificadoQué hacer
INVALID_PARAM400Falta un parámetro obligatorio o un valor no se acepta. `param` indica el nombre del parámetro cuando se conoce.No reintente sin cambios; corrija la solicitud.
UNAUTHORIZED401Se envió la cabecera `CB-API-KEY`, pero la clave es desconocida o está revocada. Los datos públicos no necesitan clave: elimine la cabecera o use una clave válida.No reintente sin cambios.
FORBIDDEN403La ruta no forma parte de la API pública (interna o solo para cuentas).No reintente.
NOT_FOUND404Ruta desconocida, o la moneda / el exchange / el fondo solicitado no existe.No reintente; compruebe la ruta y los identificadores en el catálogo.
RATE_LIMITED429Más solicitudes que el límite por minuto. `Retry-After` indica los segundos de espera.Espere el tiempo de `Retry-After` y después reintente con espera progresiva.
INTERNAL500Error inesperado del servidor. El mensaje es genérico por diseño; cite `request_id` al informar del error.Reintente una vez tras unos segundos; si persiste, infórmelo con el ID de solicitud.
UPSTREAM_FAILED503La fuente de datos de este endpoint no respondió a tiempo. No se devuelven cifras desactualizadas ni sustitutas en su lugar.Reintente con espera progresiva; consulte la página de estado.
UNAVAILABLE501 / 503El conjunto de datos no está listo temporalmente (calentamiento de la caché) o el endpoint aún no tiene una fuente pública lícita.Reintente más tarde; el catálogo marca los endpoints que no están disponibles por diseño.
REQUEST_FAILED200Algunos endpoints antiguos responden HTTP 200 con `success: false`. Compruebe siempre `success`, no solo el estado HTTP.Depende del mensaje; trátelo como una solicitud fallida.
Los endpoints más antiguos pueden responder HTTP 200 con success: false y el código REQUEST_FAILED cuando falta un elemento. Compruebe success en cada respuesta.

ID de solicitud

Cada respuesta incluye una cabecera X-Request-Id. Las respuestas fallidas la repiten en el cuerpo como request_id. Las respuestas servidas desde la caché de borde de corta duración repiten el ID de la solicitud que las generó, de modo que dos ID idénticos en llamadas consecutivas indican que se recibió una copia en caché.

Límites de solicitudes

Los límites se aplican por minuto: por dirección IP en las llamadas anónimas y por clave cuando se envía una cabecera CB-API-KEY válida. El límite es de 1200 solicitudes por minuto. Las solicitudes de iconos bajo /api/coin-icon no se contabilizan.

Cabeceras del límite de solicitudes

NombreDescripción
X-Request-IdIdentificador de esta solicitud. Cítelo en los informes de errores.
X-RateLimit-LimitSolicitudes permitidas en la ventana actual de un minuto.
X-RateLimit-RemainingSolicitudes restantes en la ventana actual.
X-RateLimit-ResetHora Unix, en segundos, en la que se reinicia la ventana.
Retry-AfterSe envía con HTTP 429: segundos que hay que esperar antes de reintentar.
X-CacheHIT, STALE o MISS de la caché de respuestas del servidor.

Cuando se supera el límite

La API responde HTTP 429 con el código RATE_LIMITED. Espere el número de segundos indicado en Retry-After y reintente. Consultar con más frecuencia que el TTL de caché de un endpoint devuelve la misma respuesta en caché, así que ajuste el intervalo de consulta al TTL indicado en cada página de referencia.

Reintentos con espera progresiva

JavaScript
async function getJson(url, tries = 4) {
  for (let i = 0; i < tries; i++) {
    const res = await fetch(url);
    if (res.status === 429 || res.status >= 500) {
      const wait = Number(res.headers.get("Retry-After")) || 2 ** i;
      await new Promise((r) => setTimeout(r, wait * 1000));
      continue;
    }
    const body = await res.json();
    if (body.success === false) {
      throw new Error(body.code + ": " + body.error + " (" + body.request_id + ")");
    }
    return body;
  }
  throw new Error("gave up after " + tries + " attempts");
}

La ausencia de datos no es un error

Cuando los parámetros son válidos pero no existe una fuente pública lícita para el dato, la llamada se completa con HTTP 200: los campos de valor son null, meta.quality es UNAVAILABLE y coverage.unavailable indica el motivo. Represéntelo con un guion. No lo convierta en 0.

Datos desactualizados

Si un recolector se retrasa, los endpoints siguen sirviendo los últimos valores almacenados con meta.is_stale: true hasta que superan la ventana de uso; a partir de ahí se retiran de los agregados y se listan en coverage.stale_excluded.