Enviar mensajes

Mandar un mensaje con tu clave, saber qué pasó con él y qué hacer cuando una regla de WhatsApp lo frena o la llamada no responde.

Vas a mandar un mensaje a un contacto desde uno de tus números, guardar su id y enterarte de qué pasó con él. El envío pide el permiso conversations:send y pasa por las reglas de WhatsApp: la ventana de 24 horas en los números de WhatsApp Cloud, los frenos contra spam y el ritmo por número.

Lo que necesitás

  • Una clave con conversations:send para mandar y conversations:read para consultar el mensaje después. Si además querés el aviso message.status_changed, webhooks:write para suscribirte.
  • El id del contacto (Listar contactos) y el device_id del número por el que sale (Listar números). Si respondés a un mensaje que te llegó, message.received ya trae los dos.

Qué operaciones de envío existen

Qué puede mandar cada número lo dice su ficha, en capabilities.messages: ver Mensajes.

1. Mandá el mensaje

curl -X POST "https://api.funnelchat.com/api/v1/contacts/2001/message" \
  -H "Authorization: Bearer <id>|fc_live_..." \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "device_id": 3,
    "contact_id": 2001,
    "text": "¡Hola! Tu pedido ya salió.",
    "client_reference": "pedido-1001"
  }'

client_reference es opcional: de 1 a 64 caracteres visibles, sin espacios, con lo que te sirva para reconocer el envío en tu sistema. No pongas datos personales: la ven todas las claves y todas las suscripciones de la cuenta.

2. Guardá el id

La llamada no espera a WhatsApp: responde 200 con el mensaje ya registrado y en cola.

{
  "message": {
    "id": 1001,
    "contact_id": 2001,
    "device_id": 3,
    "direction": "outbound",
    "type": "text",
    "status": "queued",
    "error": null,
    "client_reference": "pedido-1001",
    "created_at": "2026-10-22T12:00:00Z",
    "updated_at": "2026-10-22T12:00:00Z"
  }
}

En cola no es enviado. El mensaje sale enseguida, desde la cola. No lo reenvíes porque siga queued: lo duplicarías.

3. Enterate de qué pasó

Dos caminos, que dan lo mismo:

  • El aviso message.status_changed, con message_id, status (sent, delivered, read o failed) y tu client_reference. Se pide por su nombre al suscribirte (Webhooks).
  • La consulta Ver un mensaje, con el id del paso anterior.

Si termina failed, error.reason te dice por qué cuando lo frenó Funnelchat (por ejemplo window_closed o insufficient_balance). Qué hacer con cada motivo: Estados de mensaje.

Si una regla lo frena

El envío no sale ni queda registrado, y la respuesta es { "error": "<código>", "message": "<explicación>" }:

RespuestaQué pasóQué hacer
422 window_closedUn mensaje que no es plantilla con la ventana de 24 horas cerrada, en un número de WhatsApp Cloud.Mandá una plantilla aprobada.
422 antiblock_duplicate_contentEl mismo contenido por tercera vez en 24 horas al mismo contacto.Cambiá el contenido.
422 antiblock_unanswered_limitEl sexto mensaje seguido a alguien que no contesta.Esperá a que el contacto responda.
422 recipient_unsupportedEl contacto es un grupo, una lista de difusión o un canal.Por la API solo se les escribe a personas.
429 rate_limitedSuperaste el ritmo del número. Trae Retry-After.Esperá esos segundos y reintentá.

Decidí por el código y por error, no por el texto de message. El detalle está en Reglas de WhatsApp.

Si la llamada no responde

Con un error 5xx o sin respuesta no sabés si el mensaje quedó registrado. No reintentes enseguida: esperá al menos un minuto y buscá tu client_reference en el historial del contacto.

  • Si aparece, el mensaje quedó registrado: no lo reenvíes; su resultado llega por message.status_changed o por la consulta del mensaje.
  • Si no aparece, no salió nada y podés reintentar.

Repetir la misma client_reference no evita duplicados: dos llamadas con la misma referencia registran dos mensajes. Las tarjetas de contacto y los reenvíos tienen sus propias reglas para este caso: están en la página de cada endpoint.

Lo que sigue cerrado

  • Lo que puede producir muchos mensajes con una sola llamada (ejecutar una difusión, arrancar un flujo, disparadores, agregar o quitar etiquetas a contactos, porque una etiqueta puede disparar un flujo): queda fuera del piloto y responde 403 route_not_available con cualquier permiso. Ver Qué está abierto a claves.
  • Grupos (communities): en v0, una clave lee grupos y participantes; por la API solo se les escribe a personas. Ver Grupos.

Relacionado

  • Armá tu propio flujo: un flujo completo, del mensaje que entra a la respuesta.
  • Mensajes: qué podés mandar, archivos por URL, plantillas y formularios.
  • Reglas de WhatsApp: la ventana, los frenos, el ritmo por número y las bajas.
  • Permisos: qué habilita cada permiso en cada dominio.

En esta página