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 SIPINVITE) geaccepteerd en is begonnen met het routeren van de oproepvoice_call.answered: het nummer dat je belde nam op. Alleen beantwoorde oproepen krijgen dit eventvoice_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. Gebruik bij een geweigerde of mislukte oproep de gerapporteerde status en het laatste SIP-antwoord naast het oproeprecord. Leid geen volledige levenscyclus af uit de aanwezigheid van één event.
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 | inbound voor ontvangen oproepen; outbound voor geplaatste oproepen |
from | Het bellende nummer |
to | Het gebelde nummer |
De eventveldnamen wijken af van de leg-API: event call_id identificeert de leg en komt overeen met id in het leg-antwoord; event session_id komt overeen met call_id in het leg-antwoord. Gebruik die koppeling wanneer je webhook-updates samenvoegt met API-records.
Deze lifecycle-events gebruiken het gedeelde webhook-bezorgings- en handtekeningcontract. De synchrone webhookstap van een sequence gebruikt een apart, niet-ondertekend ontvangstprotocol; het instellen van een eventabonnement authenticeert geen verzoeken van die stap.
voice_call.initiated
Bird heeft de INVITE ontvangen en begon met routeren.
{
"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 |
{
"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. Een signalerings- of bezorgingspoging kan een update herhalen. Herhaalde publicatie van dezelfde gespreksfase behoudt dezelfde bezorgingsidentiteit, dus als je daarop filtert valt het duplicaat weg. - Vertrouw niet op volgorde. Afleveringen zijn niet geordend, dus
answeredkan je naendedbereiken. Sorteer optimestampen laat een later aangekomen event met een eerder tijdstempel verliezen. - Gebruik
endedvoor de gerapporteerde uitkomst. Het bevat status en duur. Eventpublicatie kan mislukken voordat bezorging in de wachtrij staat, dus een ontbrekend event betekent niet dat de oproep nog actief is. - 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, handleidingen en voorbeelden voor dit onderwerp.