Sign inGet Started

SMS-events

Elk bericht doorloopt een levenscyclus en Bird zendt bij elke stap een event uit. Deze pagina is het volledige eventvocabulaire; hoe events bij je endpoint worden afgeleverd (handtekeningen, retries, replay) staat in de Webhooks-gids.
De bezorgingslevenscyclus als pad door de eventtypen:
  1. sms.accepted: Bird heeft het bericht en bereidt de overdracht aan een carrier voor.
  2. sms.sent: Bird heeft het bericht aan de carrier overgedragen en wacht op een ontvangstbevestiging.
  3. Eén terminaal event:
    • sms.delivered: De carrier heeft de bezorging aan het toestel bevestigd.
    • sms.undelivered: De carrier meldde een tijdelijke niet-bezorging, bijvoorbeeld een onbereikbaar toestel.
    • sms.failed: Een permanente fout heeft de bezorging gestopt.
    • sms.expired: De carrier is gestopt met pogingen en heeft het bericht als verlopen gemeld.
De terminale events bevatten de ontvangstbevestiging van de carrier, wat SMS-platforms een delivery report of DLR noemen.
De uitzondering is sms.rejected: het bericht is geweigerd (door een beleidscontrole, een afrekening die niet kon worden voltooid, of een carrier die het afwees) in plaats van geprobeerd en verloren. Een bericht dat tijdens verwerking is afgewezen draagt sms.rejected als enige event.
Bird ontvangt ook antwoorden. Wanneer een abonnee een van je nummers sms't, slaat Bird het bericht op en zendt sms.received uit, zodat je kunt handelen zonder te pollen. De payload bevat de berichttekst, segmentopsplitsing, beide nummers en de operator wanneer de carrier die meldt.
Bird evalueert het antwoord aan de hand van de trefwoordregels voor dat nummer. Een ondersteund stoptrefwoord zoals STOP registreert een afzender-en-abonnee-suppressie en zendt alsnog sms.received uit.
Het event type is een open enum: Bird kan in de loop van de tijd nieuwe eventtypen toevoegen, dus behandel een onbekende type als een toekomstig event in plaats van een fout. Match de typen die je verwerkt en negeer de rest.

De event-envelope

Events komen bij je webhook-endpoint binnen in de geneste Standard Webhooks-envelope die beschreven staat in de Webhooks-gids: drie velden, type, timestamp, en een typespecifiek data-object. De identiteit van het event zit niet in de body: die staat in de webhook-id HTTP-header, die stabiel is over retries van dezelfde bezorging en je deduplicatiesleutel is.
VeldBeschrijving
typeEen van de eventtypen op deze pagina, zoals sms.delivered
timestampWanneer het event plaatsvond (RFC 3339); sorteer hierop, nooit op aankomstvolgorde, want bezorgingen zijn niet geordend
dataEventspecifieke payload
De data van elk SMS-event bevat sms_id, workspace_id, en de to- en from-adressen. Het echoot ook de tags en metadata van de verzending, zodat je events kunt routeren en correleren zonder een extra lookup. Elk is null wanneer de verzending er geen bevatte.
Hetzelfde object bevat cost, de kosten van het bericht op het moment van dat event, opgesplitst in transaction_amount en passthrough_amount met hun som in amount. Het is null bij een event dat niets heeft geprijsd. Omdat bezorgingen niet geordend zijn, merge je cost per component in plaats van het hele object te vervangen: bewaar voor elke component de waarde van het event met de laatste timestamp. Een amount telt alleen de componenten in zijn eigen payload op, dus lees het als de kosten tot nu toe in plaats van een definitief totaal. Kosten en facturering beschrijft wat elke component betekent.
Codevoorbeeld
{
  "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" }
  }
}

Levenscyclusevents

sms.accepted

Wordt uitgezonden wanneer Bird de verzending accepteert en begint met de voorbereiding voor overdracht aan een carrier. De payload voegt segments toe, de opsplitsing Bird geteld op het moment van acceptatie; de count ervan is waarop de verzending wordt gefactureerd.

sms.sent

Wordt uitgezonden wanneer Bird het bericht aan de carrier heeft overgedragen en wacht op een ontvangstbevestiging. De payload voegt carrier en mcc_mnc toe (het verwerkende netwerk en de bijbehorende mobile country/network code). Elk is afwezig in plaats van null wanneer de carrier het niet meldt. Om de verwerkingslatentie te meten vergelijk je de timestamp van dit event met die van sms.accepted.

sms.delivered

De carrier heeft bevestigd dat het bericht het toestel heeft bereikt. De payload voegt carrier en mcc_mnc toe, elk afwezig wanneer de ontvangstbevestiging ze niet identificeerde.

Foutevents

De payload van elk foutevent bevat een error-object: een Bird-stabiele code (bijvoorbeeld unreachable of blocked_by_carrier), een leesbare description, de ruwe carrier_error_code wanneer er een is meegegeven, en occurred_at.

sms.undelivered

Een niet-permanente niet-bezorging: het toestel was uit of onbereikbaar.

sms.failed

Een permanente bezorgingsfout heeft het bericht gestopt.

sms.rejected

Het bericht is geweigerd door de controles van Bird tijdens verwerking, een afrekening die niet kon worden voltooid, of een carrier die het afwees. Een afwijzing stopt het bericht voordat een bezorgingspoging slaagt. Een uitgeput saldo eindigt hier met de foutcode insufficient_balance, en een bericht waarvan de afrekening niet kon worden voltooid wordt niet gefactureerd.

sms.expired

De carrier is gestopt met bezorgingspogingen en heeft het bericht als verlopen gemeld. Verlopen komt uit de ontvangstbevestiging van de carrier: Bird stelt geen eigen geldigheidsvenster in en draait geen timer die een bericht beëindigt. De error beschrijft waarom het bericht nog niet was bezorgd toen de carrier opgaf, meestal unreachable: het toestel bleef de hele tijd uit of buiten bereik.

Suppressie-events

Naast de levenscyclus per bericht meldt één event een wijziging in de suppressielijst van de werkruimte: sms_suppression.created wordt uitgezonden wanneer een suppressie wordt geopend, of een abonnee een stoptrefwoord sms'te, de carrier een opt-out meldde, of iemand er handmatig een toevoegde. De payload bevat de suppression_id, het nummer van de abonnee als destination, de originator waaraan de blokkering is gebonden (een SMS-suppressie is het exacte afzender-en-abonneepaar), de reason, en de workspace_id, zodat je eigen systeem de lijst kan spiegelen zonder te pollen:
Codevoorbeeld
{
  "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"
  }
}
Een werkruimtebrede opt-out die op het tabblad Preferences is vastgelegd, is een opgegeven voorkeur en geen suppressie, en activeert dit event niet.

De tijdlijn van een bericht lezen

Webhooks bezorgen events bij je systemen. Voor een eenmalige controle toont het SMS-log dezelfde stroom als een tijdlijn met tijdstempels, carrierdetails en fouten. Om de tijdlijn programmatisch op te halen roep je GET /v1/sms/messages/{message_id}/events aan. Om alleen de laatste status te lezen roep je GET /v1/sms/messages/{message_id} aan.

Volgende stappen

  • Webhooks & events: stel een endpoint in, verifieer handtekeningen en verwerk retries en replay.
  • SMS-log: bekijk de tijdlijn per bericht die door deze events wordt aangestuurd.
  • SMS versturen: stel de tags en metadata in die bij elk event worden meegestuurd.

Gerelateerde bronnen

Ga verder met de documentatie, gidsen en voorbeelden voor dit onderwerp. De bronnen zijn in het Engels.

Ontvang een implementatieoverzicht