Códigos de error
Cada `code` posible + cómo recuperarte.
Toda respuesta de error sigue el mismo schema: code (uno de los abajo), message (humano-legible, ES), requestId (para soporte) y meta opcional con detalles específicos.
Forma del payload
{
"code": "VALIDATION_FAILED",
"message": "msisdn '+1234' is not a valid E.164 number",
"requestId": "5a92b1f8-...",
"meta": { "field": "to" }
}Catalogo
| Status | Code | Cuándo | Cómo recuperarte |
|---|---|---|---|
| 401 | UNAUTHENTICATED | Falta header o key inválida/expirada. | Verifica Authorization: Bearer rk_live_.... Si rotaste, dale 24h y reintenta con la nueva. |
| 403 | FORBIDDEN | Recurso de otro tenant, opt-in faltante en NotifyAPI, o permission denied. | Confirma que el id pertenece a tu tenant. Para NotifyAPI, agrega el msisdn al opt-in registry. |
| 402 | TRIAL_EXPIRED | 30 días de free trial vencidos sin suscribirse. | Activa una suscripción en /precios. |
| 402 | PAYMENT_REQUIRED | Última factura falló y el grace de 7 días pasó. | Actualiza método de pago en el Customer Portal. |
| 402 | SUBSCRIPTION_INACTIVE | Suscripción PAUSED o CANCELED. Sólo lectura. | Reactiva la suscripción en el dashboard. |
| 404 | NOT_FOUND | El recurso no existe en este tenant. | Verifica el id. Si es un id ajeno te dará 404 también (no leak). |
| 409 | CONFLICT | Estado incompatible (ej. editar campaign RUNNING). | Lee la respuesta message — te dice qué estado se requiere. |
| 409 | NO_CUSTOMER | Pediste portal Stripe pero el tenant no ha hecho checkout aún. | Primero pasa por POST /v1/billing/checkout. |
| 422 | VALIDATION_FAILED | Body inválido — campos faltantes, tipo equivocado, regex no matcheó. | Mira meta.field + message; corrige y reintenta. |
| 429 | RATE_LIMITED | Cap de tier o del plan excedido. | Espera al Retry-After (segundos). En NotifyAPI, considera promover el número de tier o subir de plan. |
| 503 | SESSION_NOT_CONNECTED | La sesión está LOGGED_OUT, RECONNECTING o nunca pareada. | Vuelve a vincular escaneando el QR. Para PAUSADA/RECONNECTING, espera 30s. |
| 503 | SESSION_QUARANTINED | El health scorer puso al número en quarantine. | Espera 7 días para auto-release o contacta soporte si es false positive. |
| 503 | BILLING_DISABLED | Stripe no está configurado en este deploy (self-hosted sin keys). | Setea STRIPE_SECRET_KEY y STRIPE_WEBHOOK_SECRET. |
| 500 | INTERNAL_ERROR | Bug nuestro. | Comparte el requestId al equipo — vive en Sentry. |
Sentry + requestId
Cuando llames a soporte sobre un error, pásanos el requestId. Lo buscamos en Sentry + en los logs estructurados del API y vemos la stack trace exacta.