Événements de statut des messages WhatsApp
Bird enregistre des événements pour les messages WhatsApp entrants et sortants. Une chronologie sortante montre ce qui s'est passé après qu'un envoi a renvoyé 202 : acceptation, transfert vers WhatsApp, livraison, lecture ou échec. Une chronologie entrante enregistre le moment où Bird a reçu le message.
Cette page explique comment lire cette chronologie via l'API. Pour que Bird envoie chaque événement à votre endpoint au moment où il se produit, consultez Webhooks de statut des messages. Les réactions ont leur propre historique, décrit dans Événements de réaction.
Événements du cycle de vie
Les événements apparaissent dans l'ordre chronologique. Un message sortant peut s'arrêter à whatsapp.failed ou whatsapp.rejected, et son événement whatsapp.read n'apparaît que si le destinataire ouvre le message. Une chronologie entrante commence par whatsapp.received et peut enregistrer whatsapp.read après que votre espace de travail a marqué le message comme lu.
| Événement | Signification |
|---|---|
| whatsapp.accepted | Bird a accepté la demande d'envoi. C'est ce que 202 a signalé. |
| whatsapp.sent | Bird a transmis le message au réseau WhatsApp. |
| whatsapp.delivered | WhatsApp a confirmé la livraison sur l'appareil du destinataire. |
| whatsapp.read | Le destinataire a ouvert le message. |
| whatsapp.failed | Le message n'a pas été livré. error.code indique ce qui l'a empêché. |
| whatsapp.rejected | Bird a refusé le message avant de l'envoyer. Il n'a pas été facturé. |
| whatsapp.received | Bird a reçu un message entrant d'un contact. |
Les callbacks delivered ou read applicables peuvent déclencher la part Meta du prix. Les payloads d'événement WhatsApp ne comportent aucun coût. Relisez le message avec GET /v1/whatsapp/messages/{message_id} pour voir ce qu'il a coûté. Voir Coût et facturation.
Marquer un message entrant comme lu enregistre whatsapp.read dans sa chronologie mais n'émet pas de webhook d'accusé de lecture. Le message entrant conserve son statut received et enregistre read_at après que WhatsApp a accepté l'accusé.
whatsapp.read ne change pas le status du message. Un message livré reste delivered ; le message enregistre aussi la lecture dans read_at.
whatsapp.delivered peut être entièrement absent. Lorsque le destinataire a déjà la conversation ouverte sur son appareil, Meta signale la lecture sans jamais signaler de livraison ; la chronologie se lit donc whatsapp.accepted → whatsapp.sent → whatsapp.read sans whatsapp.delivered entre les deux. Traitez read comme preuve de livraison : un consommateur qui attend delivered avant de considérer le message arrivé restera bloqué précisément sur les destinataires qui l'ont vu le plus vite, et un consommateur qui calcule un taux de livraison à partir de delivered seul le sous-estime. Le status du message reste sent dans ce cas, car seul un accusé de livraison le fait avancer.
Un callback de lecture seul peut quand même déclencher les frais Meta applicables. Bird utilise une même identité de frais pour les chemins de livraison et de lecture ; l'absence d'événement de livraison n'implique pas une composante Meta gratuite. Voir Coût et facturation.
La liste des types d'événements est ouverte : de nouveaux types peuvent être ajoutés au fil du temps, traitez donc une valeur non reconnue comme un événement futur plutôt que comme une erreur.
Événements d'échec
whatsapp.failed et whatsapp.rejected sont terminaux. Un rejet signifie que Bird a arrêté le message avant de l'envoyer à WhatsApp, il n'a donc pas été facturé. Les causes incluent un destinataire supprimé ou désinscrit, un solde de portefeuille insuffisant ou une destination sans prix configuré. Un échec signifie que le message n'a pas été livré, et error.code indique qui en a décidé. La plupart des codes portent le verdict de WhatsApp, mappé à partir du code signalé. internal_error est l'exception : il enregistre l'absence d'identifiant d'expéditeur utilisable ou l'épuisement des réessais de traitement. Une tentative de transport incertaine ne prouve pas que Meta n'a jamais reçu la requête. meta_error_code contient le code de WhatsApp lorsqu'il est disponible, et un échec internal_error n'en comporte aucun par construction.
Les deux événements contiennent un objet error avec un Bird code stable, un description lisible par l'humain, un meta_error_code optionnel et occurred_at. L'objet apparaît dans les enregistrements API et les payloads webhook uniquement pour ces types d'événements.
Lecture des événements depuis API
GET /v1/whatsapp/messages/{message_id}/events renvoie la chronologie dans l'ordre chronologique. La liste bornée n'est pas paginée. La lecture des événements nécessite une clé API avec whatsapp:read :
const { data } = await bird.whatsapp.listEvents("wa_abc123");
for (const event of data) console.log(event.type, event.occurred_at);events = client.whatsapp.list_events("wa_abc123")
for event in events.data:
print(event.type, event.occurred_at)events, err := client.Whatsapp.ListEvents(context.Background(), "wam_01krdgeqcxet5s7t44vh8rt9mg", bird.WhatsappListEventsParams{})
if err != nil {
log.Fatal(err)
}
for _, e := range events.Data {
fmt.Println(e.Id, e.Type)
}$events = $bird->whatsapp->listEvents('wamid_01krdgeqcxet5s7t44vh8rt9mg');
foreach ($events->getData() ?? [] as $event) {
echo $event->getType(), ' ', $event->getId(), "\n";
}bird whatsapp list-events <message-id>curl https://us1.platform.bird.com/v1/whatsapp/messages/wam_.../events \
-H "Authorization: Bearer $BIRD_API_KEY"Un message qui a été accepté, envoyé, livré et lu renvoie quatre événements :
Exemple de code
{
"data": [
{
"id": "ev_01ky7q6a1fejfbvs0myn41hj41",
"occurred_at": "2026-07-23T14:48:34.71Z",
"type": "whatsapp.accepted"
},
{
"id": "ev_01ky7q6a2denvtd6jg1vqwmg13",
"occurred_at": "2026-07-23T14:48:35.671Z",
"type": "whatsapp.sent"
},
{
"id": "ev_01ky7q6a2zff9r2qm74mmg1g6z",
"occurred_at": "2026-07-23T14:48:36.642Z",
"type": "whatsapp.delivered"
},
{
"id": "ev_01ky7q6c21frssf0vj8h50qysw",
"occurred_at": "2026-07-23T14:48:38.65Z",
"type": "whatsapp.read"
}
]
}Passez type pour ne renvoyer qu'un seul type d'événement public, par exemple ?type=whatsapp.failed ou ?type=whatsapp.read. Omettez-le pour obtenir la chronologie complète.
Cette même chronologie est ce que la page Journal WhatsApp affiche lorsque vous ouvrez un message.

Étapes suivantes
- Webhooks de statut des messages : recevoir chaque événement au moment où il se produit
- Événements de réaction : lire les réactions actuelles et le journal des réactions
- Marquer un message comme lu : accuser réception d'un message entrant et afficher l'indicateur de saisie
- Journal WhatsApp : la vue par message qui affiche cette chronologie
- Envoi de messages WhatsApp : là où le cycle de vie d'un message commence
Ressources associées
Poursuivez avec la documentation, les guides et les exemples sur ce sujet. Les ressources sont en anglais.
Regarder le guideConnecting WhatsApp to Bird: from buying a number to a live channelComprendre le conceptWhat is the 24-hour customer service window on WhatsApp?Utiliser l'outilWhatsApp message builderExplorer la fonctionnalitéWhatsApp
Essayez la pratique et obtenez un guide d'implémentation