Enviar mensaje de WhatsApp
Envía texto o un adjunto por URL (nunca ambos) a un contacto desde un número de WhatsApp conectado. El token del negocio se resuelve en el servidor.
El body es el mismo que el de Messenger a propósito (ADR 0019): un
cliente que atiende los tres canales solo cambia la URL. pageId es el
phone_number_id del número conectado y recipientId es el teléfono
del contacto en formato internacional.
Destino en una de dos formas:
conversationIdsolo, tomado delconversation.iddel webhook.pageId+recipientId; si además vieneconversationId, debe coincidir con ese par. El teléfono se normaliza a dígitos (sin+, espacios ni guiones), igual que elwa_idde los entrantes.
Ventana de 24 horas. Resender la evalúa localmente antes de llamar
a Meta: si el contacto no escribió en las últimas 24 horas (o nunca
escribió), responde 409 con requiresTemplate: true sin consumir
cuota. En ese caso hay que usar
POST /api/meta/whatsapp/templates/send.
Idempotency-Key es obligatoria en WhatsApp: un duplicado le llega
al teléfono del cliente final.
Texto: máximo 4096 caracteres. Adjuntos: image, video y audio
llegan con ese mismo tipo y se ven en el chat; file se envía como
document de Cloud API.
Pie de foto. attachment.caption (opcional, solo WhatsApp) es el
texto que se ve debajo del adjunto, en el mismo mensaje. Vale para
image, video y file; en audio responde 400
(attachment_caption_unsupported) porque WhatsApp no lo muestra.
Máximo 1024 caracteres. Vacío o null es "sin pie de foto".
Resender no hospeda media: Meta descarga el
archivo desde la URL y lo cachea ~10 minutos, así que la URL no puede
ser de un solo uso ni caducar en segundos. Si el origen no responde, el
envío falla con code: attachment_fetch_failed.
Authorization
ApiKey API key opaca del tenant, creada en Settings → API Tokens. Una
key revocada, inexistente o malformada responde 401 {"error":"unauthorized"}.
In: header
Header Parameters
Obligatoria en WhatsApp. Clave elegida por el cliente (1–200
caracteres). Repetirla devuelve 200 con el resultado original y
resender.idempotentReplay: true, sin volver a llamar a Meta ni
consumir cuota. Ausente, vacía o de más de 200 caracteres responde
400.
1 <= length <= 200Identificador de correlación opcional que se copia a los logs del servidor.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Destino del envío. O conversationId solo, o pageId +
recipientId (opcionalmente con conversationId, que debe
coincidir con el par).
Exactamente uno de reply o attachment.
Exactamente uno de reply o attachment.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/api/meta/whatsapp/send" \ -H "Idempotency-Key: order-8841-shipped" \ -H "Content-Type: application/json" \ -d '{ "conversationId": "6f0e5a2c-8a5e-4a3d-9c2b-1f2e3d4c5b6a", "reply": "¡Hola! Tu pedido #8841 ya salió." }'{ "meta": { "messaging_product": "whatsapp", "contacts": [ { "input": "5215512345678", "wa_id": "5215512345678" } ], "messages": [ { "id": "wamid.HBgNNTIxNTUxMjM0NTY3OBUCABEYEjBBQkNERUYxMjM0NTY3ODkwAA==" } ] }, "resender": { "conversationId": "6f0e5a2c-8a5e-4a3d-9c2b-1f2e3d4c5b6a", "messageId": "0c9d2f6e-3b7a-4e1d-8f5c-2a1b3c4d5e6f", "status": "sent" }}