Voice-Events
Bird sendet Webhook-Events, wenn ein Anruf startet, angenommen wird und endet. Nutzen Sie diese, um Ihre Systeme ohne Polling zu aktualisieren. Siehe Webhooks für Subscriptions, Signaturen, Retries und Replay.
Der Weg eines Anrufs durch die Event-Typen:
- voice_call.initiated: Bird hat die Rufaufbau-Anfrage (einen SIP INVITE) angenommen und begonnen, den Anruf zu routen
- voice_call.answered: die angerufene Nummer hat abgenommen. Nur beantwortete Anrufe erhalten dieses Event
- voice_call.ended: der Anruf ist beendet, und das Event enthält das Ergebnis
voice_call.initiated bestätigt, dass ein Anruf existiert, während voice_call.ended sein Ergebnis meldet. Ein Anruf, den Bird nach Annahme des INVITE ablehnt, sendet trotzdem voice_call.ended mit status: "failed" und sip_response_code: 503.
Der Event-type ist ein offenes Enum: Bird kann im Laufe der Zeit Typen hinzufügen. Verarbeiten Sie daher die Typen, die Sie kennen, und ignorieren Sie den Rest, statt einen unbekannten Typ als Fehler zu behandeln.
Der Event-Envelope
Voice-Events werden im selben verschachtelten Envelope wie jedes andere Bird-Event zugestellt, beschrieben im Webhooks-Leitfaden: type, timestamp und ein typspezifisches data-Objekt. Die Identität des Events steht im webhook-id-HTTP-Header, nicht im Body.
| Feld | Beschreibung |
|---|---|
| type | Einer der drei Typen auf dieser Seite, zum Beispiel voice_call.ended |
| timestamp | Zeitpunkt des Events (RFC 3339). Sortieren Sie danach, nie nach Eingangsreihenfolge |
| data | Eventspezifischer Payload, enthält immer dieselben Anruf-Identitätsfelder |
Das data jedes Voice-Events enthält dieselben Identitätsfelder zur Korrelation. Beide Nummern verwenden das E.164-Format: ein führendes +, Ländervorwahl und nationale Nummer.
| Feld | Beschreibung |
|---|---|
| call_id | Die ID des Anrufdatensatzes (vcl_…), dieselbe, die im Call log angezeigt wird |
| session_id | Wird von jedem Abschnitt eines weitergeleiteten oder Mehrparteien-Anrufs geteilt (vcs_…). Null, wenn keine Session-Korrelation zutrifft |
| workspace_id | Der Workspace, zu dem der Anruf gehört |
| direction | outbound für Anrufe, die Ihre Anlage aufgebaut hat |
| from | Die anrufende Nummer |
| to | Die angerufene Nummer |
voice_call.initiated
Bird hat den INVITE empfangen und mit dem Routing begonnen.
Codebeispiel
{
"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
Der Empfänger hat abgenommen, und die abrechenbare Zeit hat begonnen. Ein unbeantworteter Anruf sendet dieses Event nicht.
Der Payload entspricht den Anruf-Identitätsfeldern, die jedes Voice-Event enthält, wobei timestamp auf den Zeitpunkt der Annahme gesetzt ist.
voice_call.ended
Der Anruf ist beendet. Dieses Event fügt das Ergebnis hinzu:
| Feld | Beschreibung |
|---|---|
| status | Wie der Anruf endete: answered, no_answer, failed, rejected oder unknown (siehe Statuses) |
| sip_response_code | Der finale SIP-Code des Anrufs, zum Beispiel 200 oder 486. Ein von Bird abgelehnter Anruf enthält 503; null, wenn kein finaler Code aufgezeichnet wurde |
| duration_ms | Gesamtdauer des Anrufs in Millisekunden, vom Zeitpunkt, an dem Bird den Anruf empfangen hat, bis zum Auflegen |
| billable_ms | Gesprächszeit in Millisekunden; ein unbeantworteter Anruf meldet null |
Codebeispiel
{
"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
}
}Der Anrufdatensatz enthält zwei Details, die dieses Event auslässt: den Ablehnungsgrund und die Kosten. Öffnen Sie den Anruf im Call log, um eine Bird-Ablehnung von einem Carrier-Fehler zu unterscheiden. Die Kosten erscheinen nach Abschluss der Tarifierung.
Sichere Verarbeitung
- Deduplizieren Sie anhand von webhook-id. Bird liefert mindestens einmal zu, und das initiated-Event eines Anrufs kann mehrfach veröffentlicht werden, wenn ein Signalisierungs-Retry es erneut sendet. Gleicher Anruf, gleiche Phase, gleiche webhook-id – das Schlüsseln darauf eliminiert das Duplikat.
- Verlassen Sie sich nicht auf die Reihenfolge. Zustellungen sind nicht geordnet, sodass answered Sie nach ended erreichen kann. Sortieren Sie nach timestamp, und lassen Sie ein später eintreffendes Event mit einem früheren Zeitstempel verlieren.
- Behandeln Sie ended als einziges zuverlässiges Ergebnis. Es ist das Event, das Status und Dauern enthält, und dasjenige, an dem Sie Ihre eigenen Datensätze ausrichten sollten.
- Gleichen Sie mit Anrufdatensätzen ab. Events liefern zeitnahe Updates, während das Call log den Anrufdatensatz enthält. Exportieren Sie Anrufe als CSV zum Abgleich.
Nächste Schritte
| Seite | Inhalt |
|---|---|
| Webhooks & Events | Endpoint-Einrichtung, Signaturprüfung, Retries und Replay |
| Call log | Alle Felder eines Anrufdatensatzes und CSV-Export |
Verwandte Ressourcen
Weiter mit der Dokumentation, Anleitungen und Beispielen zu diesem Thema. Die Ressourcen sind auf Englisch.
Das Konzept verstehenWhat is a voice API?Die Funktion erkundenVoiceImplementierungsleitfadenVoice overview
Implementierungs-Briefing erhalten