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 SIPINVITE) angenommen und begonnen, den Anruf zu routenvoice_call.answered: die angerufene Nummer hat abgenommen. Nur beantwortete Anrufe erhalten dieses Eventvoice_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 dessen Ergebnis meldet. Verwenden Sie bei einem abgelehnten oder fehlgeschlagenen Anruf den gemeldeten Status und die abschließende SIP-Antwort zusammen mit dem Anrufdatensatz. Schließen Sie nicht aus dem Vorhandensein eines einzelnen Events auf einen vollständigen Lebenszyklus.
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 | inbound für empfangene Anrufe; outbound für getätigte Anrufe |
from | Die anrufende Nummer |
to | Die angerufene Nummer |
Die Event-Feldnamen unterscheiden sich von der Leg-API: Event-call_id identifiziert das Leg und entspricht dem id der Leg-Antwort; Event-session_id entspricht dem call_id der Leg-Antwort. Verwenden Sie diese Zuordnung, wenn Sie Webhook-Updates mit API-Datensätzen verknüpfen.
Diese Lebenszyklus-Events nutzen den gemeinsamen Webhook-Zustellungs- und Signaturvertrag. Der synchrone Webhook-Schritt einer Sequence verwendet ein separates, unsigniertes Empfängerprotokoll; das Einrichten einer Event-Subscription authentifiziert keine Anfragen aus diesem Schritt.
voice_call.initiated
Bird hat den INVITE empfangen und mit dem Routing begonnen.
{
"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 |
{
"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. Ein Signalisierungs- oder Zustellungsretry kann ein Update wiederholen. Die wiederholte Veröffentlichung derselben Anrufphase behält ihre Zustellungsidentität bei, sodass das Schlüsseln darauf das Duplikat eliminiert. - Verlassen Sie sich nicht auf die Reihenfolge. Zustellungen sind nicht geordnet, sodass
answeredSie nachendederreichen kann. Sortieren Sie nachtimestamp, und lassen Sie ein später eintreffendes Event mit einem früheren Zeitstempel verlieren. - Verwenden Sie
endedfür das gemeldete Ergebnis. Es enthält Status und Dauern. Die Event-Veröffentlichung kann fehlschlagen, bevor die Zustellung eingereiht wird. Ein fehlendes Event bedeutet daher nicht, dass der Anruf noch aktiv ist. - 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.