Respuestas de error
Para desarrolladores
La plataforma responde todos los errores con el mismo formato: RFC 9457 application/problem+json. Para decidir cómo reaccionar ante un error, use el campo code (un identificador que no cambia, pensado para que lo lea su sistema), no el texto de detail.
Campos del error
Campos del body de error:
| Campo | Tipo | Presencia | Significado |
|---|---|---|---|
type | string (URI) | siempre | URL de la documentación del error: https://docs.fidelizador.com/errors/<code>, con el code escrito con guiones en lugar de guiones bajos. |
title | string | siempre | Frase HTTP del status (Conflict, Not Found, ...). |
status | number | siempre | Código HTTP, repetido en el body. |
detail | string | siempre | Mensaje de respaldo, en inglés. Es descriptivo en 402, 404, 409 y 422, y genérico en 401, 403 y 5xx, donde no se informa el motivo. Para mostrar mensajes traducidos, derívelos de code. |
code | string | siempre | Identificador estable del error, independiente del status y del type. Úselo para distinguir un error de otro. |
trace_id | string | siempre | ID de traza para correlación. Útil al reportar un problema a soporte. |
errors | array | solo 422 | Lista de errores por campo (ver Errores por campo). |
Campos adicionales: algunos errores agregan campos propios en el nivel superior de la respuesta (p. ej.
limityupgrade_urlen el 402 del plan). Un cliente debe ignorar los campos que no conoce.
Ejemplo (401):
{
"type": "https://docs.fidelizador.com/errors/unauthorized",
"title": "Unauthorized",
"status": 401,
"detail": "Authentication required.",
"code": "unauthorized",
"trace_id": "dbb56202f13e1c15473bc6044ede8539"
}
Toda respuesta, de éxito o de error, lleva además el header X-Request-Id, y a veces X-Trace-Id. El identificador del request no viene en el body. Los headers y el formato de las respuestas exitosas están en Paginación y formato de respuesta.
Tabla resumen
El sufijo de type es siempre el code con guiones.
bad_request | Request mal formado (query/body inválido). | |
|---|---|---|
idempotency_key_required | El endpoint exige el header Idempotency-Key y el request no lo trae. |
unauthorized | Credencial ausente, inválida o expirada, o X-Instance-Slug inexistente. Revise la API key y el slug. |
|---|
plan_send_limit_exceeded | Enviar supera la cuota de envíos del plan para el período vigente (incluye limit/remaining/reset_at). | |
|---|---|---|
plan_webhooks_limit_exceeded | Crear un webhook supera el cupo de webhooks del plan. | |
plan_consent_management_unavailable | Una escritura del módulo de consentimientos (finalidades, términos, ítems de consentimiento de un formulario, registros, exigencia de consentimiento de un remitente) cuando el plan no lo incluye. | |
plan_mcp_unavailable | Una llamada del servidor MCP sobre una instancia cuyo plan no incluye el acceso por MCP. | |
subscription_inactive | La cuenta no tiene una suscripción activa o válida, o el plan no incluye envíos. Si al plan le falta otra funcionalidad, se devuelve el código de esa funcionalidad. |
forbidden | Sin permiso: scope, rol, o instancia deshabilitada. | |
|---|---|---|
ip_not_allowed | La dirección de origen no está en la lista de IPs permitidas de la instancia o en la de la API key. |
<recurso>_not_found (not_found solo en path inexistente) | El recurso no existe. | |
|---|---|---|
mail_outside_retention | El mail_id consultado es anterior a la ventana de retención en línea. |
method_not_allowed | Verbo HTTP incorrecto. |
|---|
<regla> (p. ej. sandbox_relay_restricted) | Violación de unicidad o regla de negocio. El code siempre es específico. | |
|---|---|---|
idempotency_key_in_progress | Otro request con la misma Idempotency-Key sigue en curso (incluye header Retry-After). | |
reply_mailbox_code_recently_sent | Se envió un código de confirmación del buzón de respuestas hace menos de un minuto. | |
reply_mailbox_code_expired | El código de confirmación del buzón de respuestas venció (vale 15 minutos). | |
reply_mailbox_code_attempts_exhausted | Se agotaron los 5 intentos para confirmar el buzón de respuestas. |
job_file_expired | El archivo que dejó un trabajo venció y ya no se puede descargar. | |
|---|---|---|
reply_content_expired | El contenido de una respuesta a un correo ya no se guarda: sigue en el listado, sin asunto, texto ni adjuntos. |
request_too_large | El request supera algún límite de tamaño (body, descompresión, adjunto o mensaje). |
|---|
unsupported_media_type | Content-Type no soportado. |
|---|
validation_error | Falla de validación de esquema (incluye errors[]). | |
|---|---|---|
idempotency_key_reused | La Idempotency-Key ya se usó con un request distinto. | |
rate_limit_cost_exceeds_quota | El envío tiene más destinatarios que el cupo de envío entero de la API key. | |
reply_mailbox_address_invalid | La dirección del buzón de respuestas no tiene forma de dirección de correo. | |
reply_mailbox_platform_domain | El dominio de la dirección del buzón de respuestas es de la instancia, o su MX apunta a la plataforma. | |
reply_mailbox_code_invalid | El código de confirmación no es el que recibió el buzón de respuestas. |
rate_limit_exceeded | Se agotó por ahora el cupo de envío de la API key o la tasa de la instancia. limit_scope indica cuál, y la respuesta incluye el header Retry-After. En el correo transaccional, la tasa rechaza solo si la demora superaría 30 minutos. Con una demora menor, acepta el correo, lo demora y responde 200 con un warning. | |
|---|---|---|
rate_limit_exceeded | Un dataset superó su tasa de ingreso de contactos; limit_scope: dataset (incluye header Retry-After). |
internal_error | Error no manejado. El detail es un texto genérico. |
|---|
service_unavailable | Una dependencia no respondió. |
|---|