Errores
Todas las respuestas de error tienen el mismo formato, con un nombre estable para que lo trates en tu código.
#Formato
Las respuestas con estado 2xx salieron bien. En caso de error, el cuerpo es siempre un JSON con tres campos:
{
"statusCode": 422,
"name": "validation_error",
"message": "Missing `subject` field."
}
| Campo | Descripción |
|---|---|
statusCode | El mismo estado HTTP de la respuesta. |
name | Código estable del error, en inglés. Usa este campo en tu código. |
message | Explicación para personas, en inglés (o en portugués, con Accept-Language: pt-BR). Puede cambiar de texto; no la compares. Consulta Idioma de los mensajes. |
Algunos errores traen un campo extra: errors. En el envío público de formularios, es un objeto con los mensajes de cada campo; en las automatizaciones, una lista con cada problema de la definición (step_id y message).
#Códigos de error
| Estado | Nombre | Cuándo ocurre | Qué hacer |
|---|---|---|---|
400 | invalid_idempotency_key | La Idempotency-Key está vacía o supera los 256 caracteres. | Corrige la clave. |
401 | missing_api_key | Falta el encabezado Authorization. | Envía Authorization: Bearer ps_…. |
401 | restricted_api_key | Una clave solo de envío llamó a un endpoint que exige acceso total (solo envía, lee GET /emails/{id} de los correos electrónicos que envió y lee GET /usage). | Usa una clave de acceso total. |
403 | invalid_api_key | La clave no existe o fue eliminada. | Revisa la clave o crea otra. |
403 | restricted_api_key | La clave está restringida a otro dominio. | Usa el dominio de la clave u otra clave. |
403 | validation_error | El dominio del remitente no está verificado, no tiene envío activo o no es de tu equipo. | Verifica el dominio. |
403 | sending_paused | Los envíos del equipo se pausaron por una tasa alta de rebotes o quejas. Vale para POST /emails, el lote, el SMTP, las campañas y las direcciones de prueba. | Pide la revisión en el panel o por el formulario de contacto. |
403 | plan_limit_reached | El plan no permite más elementos (dominios, buzones de entrada, plantillas, claves de API, webhooks, contactos, segmentos, temas, formularios, automatizaciones, campañas al mes…) o no incluye el recurso pedido (envío en lote, programación, SMTP, direcciones de prueba, exportaciones, adjuntos, MCP…). Consulta la lista de recursos. | Cambia de plan o quita elementos. |
403 | paused_by_plan | El elemento (dominio, clave de API, webhook, plantilla, layout, buzón de entrada, automatización, segmento, tema o formulario) superó el límite del plan actual y se pausó: se puede leer y eliminar, pero no modificar ni usar. Una clave de API pausada responde esto en cada solicitud. | Cambia de plan o elimina otros elementos: el elemento vuelve a funcionar solo. |
403 | team_suspended | La cuenta fue suspendida por la plataforma que la gestiona. | Habla con esa plataforma. |
403 | origin_not_allowed | Un formulario recibió un envío desde un sitio que no está en allowed_domains. | Incluye el dominio en el formulario. |
404 | not_found | El recurso no existe, es de otro equipo o la ruta no existe. | Revisa el ID y la ruta. |
405 | method_not_allowed | La ruta existe, pero no con ese método. | Revisa el método. |
409 | invalid_idempotent_request | La misma Idempotency-Key se usó con otro cuerpo. | Usa una clave nueva por envío. |
409 | concurrent_idempotent_requests | Una solicitud con la misma clave sigue en curso. | Espera y vuelve a intentarlo. |
409 | segment_in_use | El segmento recibe los contactos de un formulario y no se puede eliminar. | Cambia antes el segmento del formulario. |
409 | tag_in_use | La etiqueta la usan automatizaciones y no se puede eliminar. | Quita antes la etiqueta de las automatizaciones. |
409 | merge_in_progress | Otra fusión de segmentos sigue en marcha. | Espera a que termine y vuelve a intentarlo. |
409 | invalid_merge_status | Solo se puede repetir una fusión que falló. | Revisa el status de la fusión. |
409 | invalid_segment_type | El segmento ya es estático y no se puede convertir. | Nada que hacer. |
409 | invalid_broadcast_status | La campaña (/broadcasts) no está en un estado que permita la acción: editar o eliminar una que ya salió, enviar una cancelada, cancelar un borrador. | Revisa el status de la campaña. |
410 | form_closed | Un envío JSON llegó a un formulario que ya no recibe respuestas: pasó la fecha de cierre (closes_at), alcanzó el límite de envíos (max_submissions) o se pausó con un mensaje de cierre. El message es el mensaje de cierre del formulario. | Muestra el mensaje a la persona; no lo vuelvas a intentar. |
422 | validation_error | Algún campo no es válido. El mensaje indica cuál. | Corrige el cuerpo; no lo repitas igual. |
422 | email_suppressed | La dirección está en la lista de supresión y por eso no se convierte en contacto. | Quita antes la dirección de la lista, si corresponde. |
422 | ai_refused | La IA rechazó la solicitud. | Reescribe la solicitud. |
429 | rate_limit_exceeded | Se superó el límite de solicitudes por segundo del plan. También vale cuando ya hay demasiadas exportaciones, importaciones de contactos o verificaciones de correos en curso (el mensaje dice cuáles), y en los envíos a un formulario público (5 por minuto por IP). | Espera Retry-After segundos, o a que termine lo que está en curso. |
429 | daily_quota_exceeded | La cuota diaria de envíos se agotó (se renueva a las 00:00 UTC): el límite diario del plan o el tope de la reputación de la cuenta, el que sea menor. Cuando es la reputación la que limita, el message indica el nivel y el tope. | Espera. El límite del plan cambia con el plan; el tope de la reputación crece con cada día de envíos sin rebotes ni quejas. |
429 | monthly_quota_exceeded | La cuota mensual de envíos se agotó (y la reserva del Adicional de envíos, si el equipo tiene una). | Cambia de plan, activa el envío por encima de la cuota o, cuando el plan lo ofrece, compra el Adicional de envíos. |
429 | verification_credits_exhausted | Los créditos de verificación de correos se agotaron (o no alcanzan para la lista). | Espera al día 1, compra el Adicional de validación o cambia de plan. |
429 | ai_credits_exhausted | Los créditos de IA del mes se agotaron. | Espera al día 1.º o cambia de plan. |
500 | internal_server_error | Error inesperado en Postal. | Vuelve a intentarlo con una espera creciente. |
502 | crm_request_failed | El CRM conectado rechazó la llamada de Postal o no respondió (prueba de la conexión, campos, etapas o sincronización). | Revisa el token y el CRM, y vuelve a intentarlo. |
502 | ai_error | La IA no devolvió una respuesta válida. | Vuelve a intentarlo. |
503 | ai_unavailable | El servicio de IA está ocupado. | Vuelve a intentarlo en unos instantes. |
503 | ai_not_configured | El asistente de IA no está disponible. | Inténtalo más tarde. |
4xx/5xx | application_error | Otro error HTTP que no tiene nombre propio. El statusCode y el message dicen qué ocurrió. | Sigue el estado: 4xx, corrige la solicitud; 5xx, vuelve a intentarlo. |
#Cuándo reintentar
- Vuelve a intentarlo en
429 rate_limit_exceeded,409 concurrent_idempotent_requests,5xxy fallos de red (timeout, conexión rechazada). Espera un poco más en cada intento (1 s, 2 s, 4 s…) y respeta elRetry-Aftercuando llegue. - No repitas igual en
400,401,403,404,410y422: la respuesta será la misma hasta que corrijas la solicitud o la configuración. - En los envíos, manda siempre una
Idempotency-Key: si el primer intento llegó a salir bien, la repetición devuelve la misma respuesta sin enviar de nuevo.