Voice-events
Bird verstuurt webhook-events wanneer een oproep begint, wordt beantwoord en eindigt. Gebruik ze om je systemen bij te werken zonder te pollen. Zie Webhooks voor abonnementen, handtekeningen, retries en replay.
Het pad van een oproep door de eventtypen:
- voice_call.initiated: Bird heeft het verzoek tot oproepopbouw (een SIP INVITE) geaccepteerd en is begonnen met het routeren van de oproep
- voice_call.answered: het nummer dat je belde nam op. Alleen beantwoorde oproepen krijgen dit event
- voice_call.ended: de oproep is afgelopen en het event bevat de uitkomst
voice_call.initiated bevestigt dat een oproep bestaat, terwijl voice_call.ended de uitkomst rapporteert. Een oproep die Bird weigert na acceptatie van de INVITE verstuurt nog steeds voice_call.ended met status: "failed" en sip_response_code: 503.
Het event type is een open enum: Bird kan in de loop der tijd typen toevoegen, dus match de typen die je afhandelt en negeer de rest in plaats van een onbekend type als fout te behandelen.
De event-envelope
Voice-events komen binnen in dezelfde geneste envelope als elk ander Bird-event, beschreven in de Webhooks-gids: type, timestamp en een typespecifiek data-object. De identiteit van het event staat in de webhook-id HTTP-header, niet in de body.
| Veld | Beschrijving |
|---|---|
| type | Een van de drie typen op deze pagina, bijvoorbeeld voice_call.ended |
| timestamp | Wanneer het event plaatsvond (RFC 3339). Sorteer hierop, nooit op aankomstvolgorde |
| data | Eventspecifieke payload, altijd met dezelfde identiteitsvelden van de oproep |
De data van elk voice-event bevat dezelfde identiteitsvelden voor correlatie. Beide nummers gebruiken E.164-formaat: een voorloopteken +, landcode en nationaal nummer.
| Veld | Beschrijving |
|---|---|
| call_id | Het id van het oproeprecord (vcl_…), hetzelfde als in het Oproeplogboek |
| session_id | Gedeeld door elke leg van een doorverbonden of meervoudige oproep (vcs_…). Null wanneer er geen sessiecorrelatie van toepassing is |
| workspace_id | De werkruimte waartoe de oproep behoort |
| direction | outbound voor oproepen die je apparatuur heeft geplaatst |
| from | Het bellende nummer |
| to | Het gebelde nummer |
voice_call.initiated
Bird heeft de INVITE ontvangen en begon met routeren.
Codevoorbeeld
{
"type": "voice_call.initiated",
"timestamp": "2026-06-10T14:30:00Z",
"data": {
"call_id": "vcl_01krdgeqcxet5s7t44vh8rt9mg",
"session_id": "vcs_01krdgeqcxet5s7t44vh8rt9mh",
"workspace_id": "wsp_01krdgeqcxet5s7t44vh8rt9mj",
"direction": "outbound",
"from": "+14155551234",
"to": "+16505559876"
}
}voice_call.answered
De ontvanger nam op en de factureerbare tijd begon. Een onbeantwoorde oproep verstuurt dit event niet.
De payload bestaat uit de identiteitsvelden van de oproep die elk voice-event bevat, met timestamp ingesteld op het moment van beantwoording.
voice_call.ended
De oproep is afgelopen. Dit event voegt de uitkomst toe:
| Veld | Beschrijving |
|---|---|
| status | Hoe de oproep eindigde: answered, no_answer, failed, rejected of unknown (zie Statussen) |
| sip_response_code | De uiteindelijke SIP-code van de oproep, bijvoorbeeld 200 of 486. Een oproep die Bird weigerde bevat 503; null wanneer er geen definitieve code is vastgelegd |
| duration_ms | Totale oproepduur in milliseconden, vanaf het moment dat Bird de oproep ontving tot het ophangen |
| billable_ms | Beantwoordtijd in milliseconden; een oproep die niemand beantwoordde rapporteert nul |
Codevoorbeeld
{
"type": "voice_call.ended",
"timestamp": "2026-06-10T14:31:05Z",
"data": {
"call_id": "vcl_01krdgeqcxet5s7t44vh8rt9mg",
"session_id": "vcs_01krdgeqcxet5s7t44vh8rt9mh",
"workspace_id": "wsp_01krdgeqcxet5s7t44vh8rt9mj",
"direction": "outbound",
"from": "+14155551234",
"to": "+16505559876",
"status": "answered",
"sip_response_code": 200,
"duration_ms": 65000,
"billable_ms": 60000
}
}Het oproeprecord bevat twee gegevens die dit event weglaat: de weigeringsreden en de kosten. Open de oproep in het oproeplogboek om een Bird-weigering van een carrierstoring te onderscheiden. Kosten verschijnen nadat de tarifering is voltooid.
Veilig verwerken
- Dedupliceer op webhook-id. Bird levert minstens één keer af, en het initiated-event van een oproep kan meer dan eens worden gepubliceerd wanneer een signaleringsretry herhaalt. Dezelfde oproep, dezelfde fase, dezelfde webhook-id, dus door daarop te keyen vervalt het duplicaat.
- Vertrouw niet op volgorde. Afleveringen zijn niet geordend, dus answered kan je na ended bereiken. Sorteer op timestamp en laat een later aangekomen event met een eerder tijdstempel verliezen.
- Beschouw ended als de enige betrouwbare uitkomst. Het is het event dat status en duur bevat, en het event waarop je je eigen records baseert.
- Vergelijk met oproeprecords. Events bieden tijdige updates, terwijl het oproeplogboek het oproeprecord bevat. Exporteer oproepen als CSV voor reconciliatie.
Volgende stappen
| Pagina | Wat het behandelt |
|---|---|
| Webhooks & events | Endpoint-configuratie, handtekeningverificatie, retries en replay |
| Oproeplogboek | Elk veld op een oproeprecord en CSV-export |
Gerelateerde bronnen
Ga verder met de documentatie, gidsen en voorbeelden voor dit onderwerp. De bronnen zijn in het Engels.