Événements SMS
Chaque message traverse un cycle de vie, et Bird émet un événement à chaque étape. Cette page constitue le vocabulaire complet des événements ; la livraison des événements à votre endpoint (signatures, réessais, rejeu) est traitée dans le guide Webhooks.
Le cycle de vie de la livraison, sous forme de parcours à travers les types d'événements :
- sms.accepted : Bird a reçu le message et prépare sa remise à un opérateur.
- sms.sent : Bird a remis le message à l'opérateur et attend un accusé de réception.
- Un événement terminal :
- sms.delivered : L'opérateur a confirmé la livraison au terminal.
- sms.undelivered : L'opérateur a signalé une non-livraison temporaire, par exemple un terminal indisponible.
- sms.failed : Un échec permanent a empêché la livraison.
- sms.expired : L'opérateur a cessé ses tentatives et a signalé le message comme expiré.
Les événements terminaux exposent l'accusé de réception de l'opérateur, ce que les plateformes SMS appellent un rapport de livraison ou DLR.
L'exception est sms.rejected : le message a été refusé (par un contrôle de politique, une facturation qui n'a pas abouti, ou un opérateur qui l'a rejeté) plutôt que tenté et perdu. Un message rejeté pendant le traitement porte sms.rejected comme seul événement.
Bird reçoit aussi les réponses. Quand un abonné envoie un SMS à l'un de vos numéros, Bird stocke le message et émet sms.received, pour que vous puissiez agir sans interrogation périodique. Le payload contient le corps du message, le détail des segments, les deux numéros, et l'opérateur quand celui-ci est signalé.
Bird évalue la réponse en fonction des règles de mots-clés pour ce numéro. Un mot-clé de désinscription reconnu tel que STOP enregistre une suppression expéditeur-et-abonné et émet tout de même sms.received.
L'événement type est un enum ouvert : Bird peut ajouter de nouveaux types d'événements au fil du temps, traitez donc un type non reconnu comme un événement futur plutôt qu'une erreur. Gérez les types que vous prenez en charge et ignorez les autres.
L'enveloppe d'événement
Les événements arrivent à votre endpoint webhook dans l'enveloppe imbriquée Standard Webhooks décrite dans le guide Webhooks : trois champs, type, timestamp, et un objet data spécifique au type. L'identité de l'événement ne se trouve pas dans le corps : elle est portée par l'en-tête webhook-id HTTP, qui reste stable entre les réessais d'une même livraison et constitue votre clé de déduplication.
| Champ | Description |
|---|---|
| type | Un des types d'événements de cette page, par exemple sms.delivered |
| timestamp | Date de l'événement (RFC 3339) ; triez par ce champ, jamais par ordre d'arrivée, car les livraisons ne sont pas ordonnées |
| data | Payload spécifique à l'événement |
Le data de chaque événement SMS contient sms_id, workspace_id, ainsi que les adresses to et from. Il reprend aussi les champs tags et metadata de l'envoi pour que vous puissiez router et corréler les événements sans requête supplémentaire. Chacun vaut null quand l'envoi n'en contenait pas.
Le même objet porte cost, le coût du message à la date de cet événement, décomposé en transaction_amount et passthrough_amount avec leur somme dans amount. Il vaut null sur un événement qui n'a rien facturé. Comme les livraisons ne sont pas ordonnées, fusionnez cost composant par composant au lieu de remplacer l'objet entier : pour chaque composant, conservez la valeur de l'événement dont le timestamp est le plus récent. Un amount ne totalise que les composants présents dans son propre payload, lisez-le donc comme le coût provisoire plutôt qu'un total définitif. Coût et facturation explique la signification de chaque composant.
Exemple de code
{
"type": "sms.delivered",
"timestamp": "2026-06-10T14:30:00Z",
"data": {
"sms_id": "sms_01krdgeqcxet5s7t44vh8rt9mg",
"workspace_id": "ws_01krdgeqcxet5s7t44vh8rt9mg",
"to": "+15551234567",
"from": "+12025550188",
"carrier": "Example Wireless",
"mcc_mnc": "310260",
"cost": {
"amount": "0.00990",
"currency_code": "USD",
"transaction_amount": "0.00790",
"passthrough_amount": "0.00200"
},
"tags": [{ "name": "campaign", "value": "spring-2026" }],
"metadata": { "order_id": "ord_123" }
}
}Événements du cycle de vie
sms.accepted
Se déclenche quand Bird accepte l'envoi et commence à préparer sa remise à un opérateur. Le payload ajoute segments, le détail Bird comptabilisé au moment de l'acceptation ; son count est la valeur sur laquelle l'envoi est facturé.
sms.sent
Se déclenche quand Bird a remis le message à l'opérateur et attend un accusé de réception. Le payload ajoute carrier et mcc_mnc (le réseau de traitement et son code pays/réseau mobile). Chacun est absent plutôt que null quand l'opérateur ne le signale pas. Pour mesurer la latence de traitement, comparez le timestamp de cet événement avec celui de sms.accepted.
sms.delivered
L'opérateur a confirmé que le message a atteint le terminal. Le payload ajoute carrier et mcc_mnc, chacun absent quand l'accusé de réception ne les a pas identifiés.
Événements d'échec
Le payload de chaque événement d'échec ajoute un objet error : un code stable entre les Bird (par exemple unreachable ou blocked_by_carrier), un description lisible par un humain, le carrier_error_code brut quand il a été fourni, et occurred_at.
sms.undelivered
Une non-livraison non permanente : le terminal était éteint ou injoignable.
sms.failed
Un échec de livraison permanent a arrêté le message.
sms.rejected
Le message a été refusé par les contrôles de Bird pendant le traitement, une facturation qui n'a pas abouti, ou un opérateur qui l'a rejeté. Un rejet arrête le message avant qu'une tentative de livraison n'aboutisse. Un portefeuille épuisé aboutit ici avec le code d'erreur insufficient_balance, et un message dont la facturation n'a pas abouti n'est pas facturé.
sms.expired
L'opérateur a cessé ses tentatives de livraison et a signalé le message comme expiré. L'expiration provient de l'accusé de réception de l'opérateur : Bird ne définit aucune fenêtre de validité propre et n'exécute aucun minuteur mettant fin à un message. Le error décrit pourquoi le message n'était toujours pas livré quand l'opérateur a abandonné, généralement unreachable : le terminal est resté éteint ou hors couverture pendant toute la durée.
Événements de suppression
Au-delà du cycle de vie par message, un événement signale un changement dans la liste de suppressions de l'espace de travail : sms_suppression.created se déclenche quand une suppression est créée, qu'un abonné ait envoyé un mot-clé de désinscription, que l'opérateur ait signalé un opt-out, ou que quelqu'un en ait ajouté une manuellement. Le payload contient le suppression_id, le numéro de l'abonné sous la forme destination, le originator auquel le blocage est lié (une suppression SMS correspond à la paire exacte expéditeur-et-abonné), le reason, et le workspace_id, pour que votre système puisse reproduire la liste sans interrogation périodique :
Exemple de code
{
"type": "sms_suppression.created",
"timestamp": "2026-08-25T14:52:03.192524705Z",
"data": {
"suppression_id": "ssu_01krdgeqcxet5s7t44vh8rt9mg",
"destination": "+15550001234",
"originator": "+15557654321",
"reason": "keyword_stop",
"workspace_id": "ws_01ky7m21hjffh9s8kq76gyb1xf"
}
}Un opt-out à l'échelle de l'espace de travail enregistré dans l'onglet Préférences est une préférence déclarée et non une suppression, et ne déclenche pas cet événement.
Lire la chronologie d'un message
Les webhooks livrent les événements à vos systèmes. Pour une consultation ponctuelle, le journal SMS affiche le même flux sous forme de chronologie avec horodatages, détails de l'opérateur et erreurs. Pour récupérer la chronologie par programmation, appelez GET /v1/sms/messages/{message_id}/events. Pour lire uniquement le dernier état, appelez GET /v1/sms/messages/{message_id}.
Étapes suivantes
- Webhooks et événements : configurez un endpoint, vérifiez les signatures, et gérez les réessais et le rejeu.
- Journal SMS : inspectez la chronologie par message alimentée par ces événements.
- Envoyer des SMS : définissez les champs tags et metadata repris sur chaque événement.
Ressources associées
Poursuivez avec la documentation, les guides et les exemples sur ce sujet. Les ressources sont en anglais.
Comprendre le conceptOne-way and two-way SMSExplorer la fonctionnalitéTwo-way SMSSuivre le parcours d'apprentissageBuild your first integration
Obtenir un guide d'implémentation