Skip to main content

Códigos de error

La API devuelve errores con el envelope:
{
  "error": {
    "type": "invalid_request_error",
    "code": "validation_error",
    "message": "Payload does not match schema for booking.created",
    "param": "aggregate_id",
    "request_id": "req_a1b2c3d4e5f6",
    "details": [
      { "path": "aggregate_id", "message": "Required" }
    ]
  }
}
CampoTipoDescripción
typestringCategoría amplia. Ver tabla abajo.
codestringCódigo específico, machine-readable. Ver tabla abajo.
messagestringDescripción human-readable. NO confiar para lógica — usar code.
paramstring | undefinedField que causó el error (en validation_error).
request_idstringIdentificador único de la request — incluir en reportes a soporte.
detailsarray | undefinedLista detallada { path, message } — útil para errores de payload con múltiples campos inválidos.

Tipos (error.type)

TipoCuándo se devuelve
invalid_request_errorPayload mal formado, parámetros inválidos, recurso no encontrado
authentication_errorFalta o inválido el token / api-key
permission_errorAutenticado pero sin permisos para esta operación
idempotency_errorConflicto con Idempotency-Key (misma key + body distinto)
rate_limit_errorExcedido el rate limit
api_errorError interno del servidor

Códigos (error.code)

CódigoHTTPTypeNotas
validation_error400invalid_request_errorEl payload no pasó la validación. details lista cada problema.
event_type_unknown400invalid_request_errorEspecífico de /public/events/ingest: el event_type no está en el catálogo. details enumera los aceptados.
invalid_cursor400invalid_request_errorEl cursor de paginación está corrupto. Reiniciar desde primera página.
authentication_required401authentication_errorNo se envió Authorization ni x-api-key.
authentication_invalid401authentication_errorLas credenciales enviadas son inválidas o expiradas.
permission_denied403permission_errorEl caller existe pero no tiene rol/permiso requerido.
resource_missing404invalid_request_errorEl recurso solicitado no existe.
idempotency_conflict409idempotency_errorReintento incoherente con la request original.
idempotency_key_in_use409idempotency_errorMisma Idempotency-Key con un body distinto al primer POST.
rate_limit_exceeded429rate_limit_errorExcedido el límite. Header Retry-After indica cuándo reintentar.
internal_error500api_errorError inesperado del servidor. Reintentar con backoff.
service_unavailable503api_errorDependencia (DB, etc.) caída. Reintentar más tarde.

Ejemplos por status code

400 — Validation error

{
  "error": {
    "type": "invalid_request_error",
    "code": "validation_error",
    "message": "Payload does not match schema for booking.created",
    "param": "payload.bookingId",
    "request_id": "req_abc",
    "details": [
      { "path": "payload.bookingId", "message": "Required" },
      { "path": "payload.startDate", "message": "Invalid datetime" }
    ]
  }
}

400 — Event type desconocido

{
  "error": {
    "type": "invalid_request_error",
    "code": "event_type_unknown",
    "message": "event_type \"booking.foo\" is not registered",
    "param": "event_type",
    "request_id": "req_abc",
    "details": [
      { "path": "event_type", "message": "user.welcomed" },
      { "path": "event_type", "message": "booking.created" }
    ]
  }
}

401 — API key inválida

{
  "error": {
    "type": "authentication_error",
    "code": "authentication_invalid",
    "message": "Invalid API key",
    "request_id": "req_abc"
  }
}

409 — Idempotency conflict

{
  "error": {
    "type": "idempotency_error",
    "code": "idempotency_key_in_use",
    "message": "Idempotency-Key already used with a different request body",
    "param": "Idempotency-Key",
    "request_id": "req_abc"
  }
}

429 — Rate limit

HTTP/1.1 429 Too Many Requests
Retry-After: 23
X-RateLimit-Limit: 200
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 23

{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limit_exceeded",
    "message": "ThrottlerException: Too Many Requests",
    "request_id": "req_abc"
  }
}

Cómo manejar errores en el cliente

  1. Lee error.code para lógica, nunca error.message (puede cambiar sin previo aviso).
  2. Adjunta request_id en cualquier ticket a soporte — lo encontramos en logs en segundos.
  3. Reintenta con backoff exponencial ante rate_limit_exceeded, internal_error, service_unavailable. Respeta Retry-After cuando esté presente.
  4. Para idempotency_key_in_use: cambia la key o asegúrate de enviar el mismo body. Es probablemente un bug en el cliente.
  5. Para validation_error: corrige el payload antes de reintentar. Usa details[].path para el field específico.