Manejo de Errores
Formato de errores, códigos de estado y soluciones para la API de integración.
Cuando una solicitud a la API de integración falla, la respuesta incluye un cuerpo JSON con información sobre el error.
Formato de error
{
"statusCode": 401,
"error": "Unauthorized",
"message": "Invalid or revoked API key"
}| Campo | Tipo | Descripción |
|---|---|---|
statusCode | number | Código de estado HTTP |
error | string | Nombre del error |
message | string | Descripción detallada del problema |
code | string | Presente solo en los errores sobre los que un cliente tiene que ramificar. Es un valor estable en UPPER_SNAKE: ramifica por code, nunca por el texto de message, que puede cambiar. Hoy el único es DEFAULT_ROOT_CONFIRMATION_REQUIRED (ver Publicar Config). No es la columna Código de la tabla siguiente, que es el nombre del error HTTP |
Códigos de error
| Status | Código | Descripción | Solución |
|---|---|---|---|
401 | Unauthorized | Clave de API inválida, revocada o expirada, o su dueño está inactivo | Verifica que la clave esté copiada exactamente y siga activa en Configuración → Claves API; si fue revocada o expiró, crea una nueva |
403 | Forbidden | La clave no tiene el permiso requerido, o una clave de proyecto nombra otro proyecto en x-project-id | Confirma que la clave tiene los permisos necesarios: activity:view para consultar, activity-result:submit para enviar resultados, commerce:batch-upsert / operator:batch-upsert / route:batch-upsert para los upserts por lote. Con una clave de proyecto, omite x-project-id o envía el propio proyecto de la clave |
400 | Bad Request | Error de validación en el cuerpo de la solicitud, header x-api-key faltante (Missing required header: x-tenant-id), un x-project-id que no es un UUID válido, o un resultado sin activity_id enviado sin proyecto | Revisa que el cuerpo cumpla con el formato documentado: tipos de datos y campos requeridos. Si envías x-project-id, usa el UUID de un proyecto; con una clave de tenant o un token de usuario, un resultado sin activity_id lo necesita |
404 | Not Found | Recurso no encontrado, o el proyecto que nombra x-project-id no existe | Confirma que el activity_id u otro identificador exista en el tenant, y que el proyecto de x-project-id pertenezca al tenant de la clave |
422 | Unprocessable Entity | El cuerpo es válido pero no se puede procesar: la actividad no admite un resultado en su estado o día actual, o el tipo de resultado no está activo o necesita un dato que falta | Verifica que la actividad esté en un estado que admita resultado (READY, DISPATCHED, RETRYING o COMPLETED) y que su día no haya sido cerrado por el cierre de fin de día; usa un código de resultado activo y envía future_scheduled_at (hoy o después) cuando su tipo lo requiera |
429 | Too Many Requests | Demasiadas solicitudes en poco tiempo | Espera antes de reintentar y distribuye las solicitudes en el tiempo |
Errores comunes y diagnóstico
401 — Clave no reconocida
{
"statusCode": 401,
"error": "Unauthorized",
"message": "Invalid or revoked API key"
}Causas posibles:
- La clave fue revocada desde el panel de administración
- La clave tiene una fecha de expiración vencida
- Error de formato (espacios, caracteres extra)
- El dueño de la clave está inactivo — en ese caso el
messageesAPI key owner is inactive or not found - La API no pudo validar la clave en ese momento — en ese caso el
messageesAPI key validation failed; reintenta la solicitud
Una solicitud que no lleva clave no recibe este 401. La API solo lee x-api-key como clave cuando su valor empieza con rtn_sk_; cualquier otro valor cuenta como si no hubiera clave. Sin clave y sin x-tenant-id, la API responde 400 Bad Request con Missing required header: x-tenant-id; con x-tenant-id pero sin credenciales, responde 401.
Errores de proyecto
En GET /api/integration/activities/tasks y POST /api/integration/activity-results/tasks, x-project-id es opcional: los dos son endpoints project-optional. Cuando se envía el header, la API lo verifica antes que los permisos y el cuerpo. El 400 de un resultado sin activity_id no es parte de esa verificación: llega después de validar el cuerpo, así que un error en el cuerpo se informa primero. Cómo elige su proyecto cada clave se explica en Alcance de la clave.
| Status | Cuándo | message |
|---|---|---|
400 | Un resultado sin activity_id se envía sin proyecto: una clave de tenant o un token de usuario que no envía x-project-id | Falta el header obligatorio x-project-id: un resultado sin activity_id necesita proyecto. |
400 | x-project-id no es un UUID válido (clave de tenant o token de usuario) | El header x-project-id debe ser un UUID válido. |
403 | Una clave de proyecto envía un x-project-id que no es su propio proyecto | La API key pertenece a un proyecto distinto del que declara el header x-project-id. |
404 | El proyecto de x-project-id no existe o pertenece a otro tenant | El proyecto no existe. |
403 — Permiso insuficiente
{
"statusCode": 403,
"error": "Forbidden",
"message": "Required permissions: activity:view"
}Causas posibles:
- La clave no incluye el permiso requerido para el endpoint
- Pide al dueño de la clave que edite sus permisos con
PUT /api/api-keys/:id/permissionso desde Configuración → Claves API
400 — Error de validación
La API responde 400 cuando el cuerpo no cumple el formato documentado.
Causas posibles:
- Campos requeridos faltantes:
occurred_atytask_result.resultsiempre;commerce_external_idsolo cuando no vieneactivity_id(ejecuciones independientes) - Formato de fecha inválido (debe ser ISO 8601)
activity_idno es un UUID válido- Campos que no forman parte del cuerpo documentado
422 — Estado no procesable
{
"statusCode": 422,
"error": "Unprocessable Entity",
"message": "La actividad no está en un estado válido para registrar resultado."
}Causas posibles:
- La actividad vinculada no está en un estado que admita resultado.
READY,DISPATCHEDyRETRYINGlo admiten;COMPLETEDtambién, y enviar de nuevo actualiza el resultado existente de la actividad;CANCELEDyFAILEDno —messagede arriba - La fecha de ejecución de la actividad ya cruzó el cierre de fin de día —
La actividad corresponde a un día ya cerrado y no admite registrar resultado.A partir de ese corte se ejecuta un cierre automático que puede registrar el resultado (comoNOT_EXECUTED). Las ejecuciones independientes (STANDALONE, sinactivity_id) están exentas de esta regla y de la anterior - El código de resultado de
task_result.resultno existe o no está activo —El tipo de resultado seleccionado no está activo.Consulta Listar Configuraciones para obtener códigos válidos - El tipo de resultado requiere
task_result.future_scheduled_aty no se envió —Este tipo de resultado requiere una fecha comprometida. task_result.future_scheduled_atcae en un día anterior a hoy, en la zona horaria del tenant —La fecha programada no puede ser en el pasado.