Webhooks de ciclo de vida de mensajes de WhatsApp
Cada paso en el ciclo de vida de un mensaje puede enviarse a tu endpoint en el momento en que ocurre. Cada payload usa la respuesta de evento WhatsApp e incluye los campos que todo evento de mensaje incluye.
Eventos de entrega
whatsapp.accepted, whatsapp.sent, whatsapp.delivered y whatsapp.read solo incluyen los campos que todo evento de mensaje incluye. Eventos de ciclo de vida explica qué significa cada uno y cuándo se omite whatsapp.delivered.
Ejemplo de código
{
"data": {
"direction": "outbound",
"from": { "phone_number": "+13124495569" },
"metadata": { "session_id": "sess_4821" },
"tags": [{ "name": "flow", "value": "login-otp" }],
"to": { "phone_number": "+14155550100" },
"whatsapp_id": "wam_01ky7qbvswf3fvyaw3az90391c",
"workspace_id": "ws_01ky7m235keycbnwyajabe1a6b"
},
"timestamp": "2026-07-23T14:51:39.913Z",
"type": "whatsapp.delivered"
}whatsapp.failed y whatsapp.rejected también incluyen un objeto error con un Bird code estable, un description legible, un meta_error_code opcional y occurred_at. Consulta eventos de fallo para ver qué diferencia a ambos. En un fallo reportado por WhatsApp, description es la explicación propia de WhatsApp. Un mensaje de servicio cuya ventana de atención al cliente se cerró entre la aceptación y el envío falla así:
Ejemplo de código
{
"data": {
"direction": "outbound",
"error": {
"code": "service_window_expired",
"description": "Message failed to send because more than 24 hours have passed since the customer last replied to this number.",
"meta_error_code": "131047",
"occurred_at": "2026-07-23T14:51:40.201Z"
},
"from": { "phone_number": "+13124495569" },
"metadata": null,
"tags": null,
"to": { "phone_number": "+14155550100" },
"whatsapp_id": "wam_01ky7qbvswf3fvyaw3az90391c",
"workspace_id": "ws_01ky7m235keycbnwyajabe1a6b"
},
"timestamp": "2026-07-23T14:51:40.201Z",
"type": "whatsapp.failed"
}Marcar un mensaje entrante como leído registra whatsapp.read en la línea de tiempo del mensaje, pero no emite un webhook.
Mensajes entrantes
whatsapp.received incluye el contenido del mensaje junto con los campos que todo evento de mensaje incluye, de modo que un endpoint puede actuar sobre un mensaje entrante sin volver a leerlo. Un toque en un mensaje interactivo llega como interactive_reply, y in_reply_to_message_id indica el mensaje al que responde:
Ejemplo de código
{
"data": {
"direction": "inbound",
"from": {
"display_name": "Alex Rivera",
"phone_number": "+14155550100",
"username": "alexr"
},
"in_reply_to_message_id": "wam_01ky7qbvswf3fvyaw3az90391c",
"interactive_reply": {
"list": {
"description": "Next day to 2 days",
"slug": "priority_express",
"text": "Priority Mail Express"
},
"type": "list"
},
"metadata": null,
"tags": null,
"to": { "phone_number": "+13124495569" },
"whatsapp_id": "wam_01ky8b3xq4gd7pmzn2ka51f7te",
"workspace_id": "ws_01ky7m235keycbnwyajabe1a6b"
},
"timestamp": "2026-07-23T14:52:04.118Z",
"type": "whatsapp.received"
}Las demás ramas de contenido siguen la misma estructura de uno-de-estos: text, image, video, audio, sticker, document, location, contact_cards y unsupported para un tipo que API no modela. GET /v1/whatsapp/messages/{message_id} documenta cada una.
Próximos pasos
- Webhooks de reacciones: las reacciones de un contacto llegan por separado
- Recibir mensajes de WhatsApp: todas las ramas de contenido y la obtención de medios entrantes
- Eventos de ciclo de vida: consulta la línea de tiempo de un mensaje a través de API
Recursos relacionados
Continúa con la documentación, guías y ejemplos sobre este tema. Los recursos están en inglés.
Ver la guíaConnecting WhatsApp to Bird: from buying a number to a live channelComprender el conceptoWhat is the 24-hour customer service window on WhatsApp?Usar la herramientaWhatsApp message builderExplorar la funcionalidadWhatsApp
Prueba el ejercicio y obtén un resumen de implementación