Errores
Los errores responden con el código HTTP que corresponde y un cuerpo JSON. Hay dos formas:
Errores de negocio (lo que pediste no se puede hacer): traen un message para una persona y, cuando tu código necesita distinguirlos, un code estable.
{ "statusCode": 409, "code": "CONTACT_PHONE_EXISTS", "message": "Ya existe un contacto con ese teléfono.", "contactId": "0b1c2d3e-…", "fullName": "Laura Pérez" }Errores de validación (el cuerpo o los parámetros no cumplen el contrato): statusCode 400 y una lista de mensajes, uno por campo. Un campo o parámetro desconocido también se rechaza (property x should not exist): así un error de escritura no pasa como «sin filtro».
{ "statusCode": 400, "message": ["primaryPhone must be shorter than or equal to 32 characters"], "error": "Bad Request" }Códigos HTTP
| Código | Cuándo |
|---|---|
| 400 | Validación, o una acción que no procede en el estado actual (campaña ya enviada, sin destinatarios, saldo insuficiente, fecha en el pasado) |
| 401 | Clave inválida, anulada o caducada |
| 403 | Permiso que falta o ruta no abierta a claves |
| 404 | El recurso no existe o no es de tu organización |
| 409 | Conflicto: teléfono ya usado por otro contacto, identidad de canal ya vinculada, contacto con historial |
| 429 | Límite de peticiones |
| 5xx | Error nuestro: reintenta con espera creciente y, si persiste, escríbenos |
Códigos de error estables
code |
HTTP | Significado |
|---|---|---|
API_KEY_INVALID |
401 | La clave no existe, está mal escrita o se anuló |
API_KEY_EXPIRED |
401 | La clave caducó: crea otra |
API_KEY_SCOPE_MISSING |
403 | La ruta pide un permiso que la clave no tiene; el message dice cuál |
API_KEY_NOT_ALLOWED_HERE |
403 | La ruta no está abierta a claves de API |
API_KEY_RATE_LIMITED |
429 | Más de 600 peticiones en un minuto con esa clave |
CONTACT_PHONE_EXISTS |
409 | Ya hay un contacto con ese teléfono; la respuesta trae contactId y fullName |
CONTACT_HAS_HISTORY |
409 | No se elimina un contacto con conversaciones, campañas o ventas |
CAMPAIGN_VARIABLES_REQUIRED |
400 | La plantilla tiene variables y la campaña no dice de dónde salen |
PHONE_NUMBER_NOT_OWNED |
409 | El número emisor no pertenece a tu organización |
Los demás errores de negocio llegan solo con message; en la referencia de cada ruta están los más frecuentes. Trata los code como estables: no cambiarán dentro de la versión. Los message pueden mejorar con el tiempo y están pensados para mostrar, no para comparar.
Saldo insuficiente
Enviar una campaña cobra el lote de la wallet antes de llamar a Meta. Si no alcanza, POST /campaigns/{id}/send responde 400 con «Saldo insuficiente en la wallet.» y la campaña queda como estaba; si se agota en mitad de un envío escalonado, la campaña se pausa con ese motivo en stopReason y se reanuda con POST /campaigns/{id}/resume tras recargar. Consulta GET /campaigns/{id}/preview-cost antes de enviar: wallet.sufficient te lo dice sin intentar el envío.