La API usa los códigos HTTP de siempre: 2xx salió bien, 4xx hay algo para corregir en la llamada o en la cuenta, 5xx falló algo de nuestro lado o de Meta.

Formato

Casi todos los errores tienen esta forma:
  • error: explica el problema en español. Está pensado para mostrarlo tal cual a tu equipo.
  • cause: detalle para tu código. Es null salvo en los errores de plan (402) y de cupo mensual (429).
Los mensajes de error usan el español de Argentina (“usá”, “elegí”), igual que la app de MINDO.

Errores de validación

Cuando al cuerpo o a los parámetros les falta algo o tienen un tipo equivocado, la respuesta 400 tiene otra forma: error.message es un JSON (en texto) con la lista de problemas. path dice qué campo y message por qué.
Para leerlo:

Códigos

Algo del pedido no es válido. Los casos más comunes:
  • Falta un campo obligatorio (phone en contactos, to en mensajes).
  • Mandaste text y template a la vez, o ninguno de los dos: “Mandá text o template, uno de los dos.”
  • El teléfono no es válido: “El teléfono “123” no es válido. Usá formato internacional, por ejemplo +5491123456789.” Revisa Formato de teléfonos.
  • limit fuera de rango (1 a 200) o after que no es un UUID.
Qué hacer: corrige el pedido. Reintentar igual va a fallar igual.
Falta la clave, está mal escrita o fue revocada.
Qué hacer: revisa que el encabezado sea Authorization: Bearer etk_live_… y que la clave siga activa en Ajustes › API y webhooks.
La cuenta no tiene un plan que permita esto. cause.reason te dice por qué:cause.suggested es el plan que lo resolvería.
Qué hacer: avisa a quien administra la cuenta. Se resuelve en Ajustes › Plan y uso. El límite de contactos solo se aplica al crear contactos nuevos (con POST /contacts o al mandar un mensaje a un teléfono que no estaba).
El recurso no existe en esta cuenta: “Mensaje no encontrado.” o “La plantilla ya no existe.”Qué hacer: revisa el id. Los ids son de cada cuenta: una clave no ve lo de otra cuenta.
El pedido es válido, pero WhatsApp no deja hacerlo en este momento:
  • “Pasaron más de 24 horas desde el último mensaje del cliente. Para escribirle, usá una plantilla.” → manda una plantilla en vez de text.
  • “La plantilla todavía no está aprobada por Meta.” → espera la aprobación o usa otra.
  • “No hay un número de WhatsApp conectado con ese id.” → revisa phoneNumberId.
  • “Tu WhatsApp está desconectado.” → vuelve a conectar el número en Ajustes › Números y canales.
  • “La automatización no está activa.” → publícala o actívala en Automatizaciones.
  • “Esta conversación ya tiene una automatización en curso.” → espera a que termine o detenla desde el chat.
Qué hacer: no reintentes a ciegas; cambia el pedido o resuelve el estado de la cuenta.
Llegaste a un límite de tu plan. Hay tres casos:
  • Tope por minuto de solicitudes o de mensajes. Viene con los encabezados Retry-After: 60 y X-RateLimit-Limit:
  • Cupo mensual de llamadas a la API. Trae cause con type: "upgrade", como un 402, y no trae Retry-After:
  • Demasiados intentos con claves inválidas desde la misma IP: la IP queda bloqueada un minuto.
Qué hacer: con el tope por minuto, espera lo que diga Retry-After y reintenta con espera creciente. Con el cupo mensual, deja de reintentar hasta el día 1 o hasta cambiar de plan. Los números de cada plan y un ejemplo de código están en Límites.
Meta no aceptó el envío. El mensaje incluye el motivo que dio Meta, por ejemplo:
Qué hacer: lee el motivo. Algunos son temporales (reintenta en unos minutos) y otros son de la cuenta de Meta, como que falte el medio de pago. Mira Cargar el medio de pago.
Qué hacer: reintenta con espera creciente (1 s, 2 s, 4 s…). Si se repite, escríbenos a soporte@mindo.ar con la hora y el endpoint.

Mensajes que se aceptan pero después fallan

Un 201 en POST /messages quiere decir que Meta aceptó el mensaje, no que ya llegó. La entrega puede fallar después: por ejemplo, si el número no tiene WhatsApp. En ese caso el mensaje queda con status: "failed" y un código de Meta:
Lo ves con GET /messages/{id} o con el webhook message.status. Códigos de Meta frecuentes:

Reintentos seguros

  • Reintenta solo 500, 502 temporales, 429 por tope por minuto y errores de red.
  • POST /contacts se puede reintentar sin problema: si el contacto ya existe, lo actualiza.
  • POST /messages no es idempotente: si reintentas después de un timeout, el cliente podría recibir el mensaje dos veces. Antes de reintentar, fíjate si el mensaje ya aparece en el chat o guarda el id de la primera respuesta.