Errores
Los fallos de Platform API utilizan códigos de estado HTTP estándar. Casi todos los fallos
incluyen una cadena subcode estable sobre la que los clientes deben decidir — los códigos de estado
por sí solos son ambiguos (403 cubre scope, producto, origin, IP y tipo de clave).
Envelope
La mayoría de los errores devuelven un contenedor detail al estilo FastAPI:
{ "detail": "<subcode>" }
Los payloads estructurados 429 (map_load_quota_exceeded, b2b_overloaded,
org_overloaded, tile_access_restricted) son objetos planos en el nivel
superior — sin wrapper detail:
{ "error": "map_load_quota_exceeded", "meter": "map_loads", "limit": 50000, "used": 50000 }
Los 429 con string-detail (map-load hard stops) mantienen el wrapper:
{ "detail": "map_load_hard_stop" }
Algunos endpoints sin streaming informan de errores como HTTP 200 con una clave error —
principalmente POST /chat/control/route. Cualquiera que decida solo según el
status los interpretará como éxito. Lee siempre el body.
Tabla
| Estado | Subcode | Significado | Qué hacer |
|---|---|---|---|
| 401 | (no detail) | Clave ausente / no válida / revocada / caducada | Comprueba el valor de la clave y que no esté revocada. Viewer no necesita clave. |
| 401 | publishable_requires_session | Se envió una clave publishable (kld_pk_…) como bearer directo | Úsala mediante el SDK, que la intercambia por una sesión. |
| 403 | insufficient_scope | Clave válida, pero no tiene el scope de la ruta | Crea / vuelve a crear una clave con el scope adecuado (ai / maps / design). |
| 403 | tier_capability_not_allowed | La clave almacenada tenía la capacidad, pero el nivel actual de la organización ya no la admite (normalmente downgrade Pro→Free) | Mejora el plan o utiliza un producto admitido por el nivel actual. |
| 403 | origin_required | Se utilizó una clave publishable sin un Origin de navegador (p. ej. desde servidor) | Las claves publishable son solo para navegador. |
| 403 | session_origin_mismatch | El Origin de la solicitud no está en la allowlist de la clave | Actualiza los allowed origins de la clave (consulta Obtener una clave API). |
| 403 | product_not_allowed | La clave no está permitida para este producto | Crea una clave con el producto autorizado (o utiliza viewer, que no necesita clave). |
| 403 | server_key_in_browser | Se utilizó una server key (kld_sk_…) desde un navegador | Las server keys son solo para servidor; también están bloqueadas por CORS. |
| 403 | ip_not_allowed | Se utilizó una server key desde una IP fuera de su allowlist | Actualiza la allowlist de IP de la clave o llama desde una dirección permitida. |
| 403 | publishable_key_required | Se intentó el SDK session exchange con algo distinto de una clave publishable | Utiliza una clave kld_pk_… en el paso de session-exchange. |
| 403 | sessions_disabled | La emisión de sesiones está deshabilitada para este deployment | Contacta con soporte — es un estado operativo, no una configuración del cliente. |
| 403 | sessions_not_configured | La infraestructura de sesiones no está configurada | Contacta con soporte. |
| 422 | (various) | Body de solicitud malformado | Corrige el payload (consulta Endpoints). Durante mint, unknown_scope / unknown_product indican un valor no reconocido; publishable_live_requires_origins significa que se creó una clave publishable live sin allowed origins. |
| 429 | (flat) map_load_quota_exceeded | Se agotó la asignación mensual de map-loads de la organización | Mejora el plan o reduce las cargas de mapa base. |
| 429 | map_load_hard_stop | La organización de pago supera 5× su asignación de map-loads | El servicio se detiene aquí; la banda flexible por encima de la asignación sigue funcionando. |
| 429 | (flat) tile_access_restricted | Solicitud de Tile rechazada (normalmente por falta del origin en la allowlist). Incluye Retry-After: 3600 | Añade el origin de la página a la allowlist de la clave; vuelve a intentarlo después del intervalo del header. |
| 429 | (flat) b2b_overloaded | Está activo el descarte global de solicitudes | Reduce el ritmo y vuelve a intentarlo con jitter. |
| 429 | (flat) org_overloaded | Descarte por organización | Reduce el ritmo y vuelve a intentarlo. |
| 429 | limiter_unavailable | El rate limiter no está disponible temporalmente | Trátalo como transitorio; vuelve a intentarlo. |
| 429 | rate_limited | Demasiadas solicitudes en este momento | Respeta Retry-After. |
| 503 | (no detail) | Servicio de claves no disponible temporalmente | Transitorio — vuelve a intentarlo pronto. |
Gestión de claves
Fallos de POST/PATCH/DELETE /shared-api/api-keys/* (Cognito org-admin
JWT, no una platform key):
| Estado | Subcode | Significado |
|---|---|---|
| 403 | free_plan_publishable_only | Las organizaciones Free solo pueden crear claves publishable. |
| 403 | plan_required | La organización no tiene una fila de plan API reconocida. |
| 403 | tier_capability_not_allowed | Un PATCH intentó ampliar una clave más allá de lo admitido por el nivel actual de la organización. |
| 403 | vendor_scope_requires_acknowledgement | El scope vendor requiere una marca explícita de confirmación por clave. |
| 409 | key_limit_reached | La organización alcanzó el límite de claves por organización de su plan. |
Consulta Obtener una clave API para ver el flujo completo de mint y la ruta de actualización PATCH.
Errores de streaming
En un stream SSE, un fallo terminal llega como un evento error en lugar de
un estado HTTP (la respuesta ya empezó con 200):
event: error
data: { "type":"error", "message":"…", "code":"…", "partial_text":"…" }
Trata un evento error como el final de ese stream. Un evento quota a mitad del stream
no es un error — es el medidor que indica cuánto presupuesto
queda. Los clientes deben ignorar nombres de eventos desconocidos — se pueden añadir nuevos eventos
dentro del contrato estable sin cambiar de versión.
CORS "bloqueado" en el navegador
Si el navegador informa de un bloqueo CORS en una solicitud real, el Origin de la solicitud
no está en la allowlist de la clave — no es un fallo de auth. Consulta
CORS & allowed origins.