Einen Sprachanruf erstellen
Warning: Voice sequences are in preview. Steps, entry data, and the sequence definition format can change in ways that break existing sequences and API requests.
Verwenden Sie POST /v1/voice/calls, um eine Telefonnummer anzurufen und eine veröffentlichte Sequenz oder eine mit der Anfrage gesendete Sequenzdefinition zu starten, wenn der Empfänger antwortet. Die Anfrage tätigt einen echten Anruf; es fallen die normalen Anrufgebühren an.
CLI- und MCP-Vorschau: Diese Schnittstellen erfordern einen kompatiblen Client. Prüfen Sie, ob Ihr MCP-Server voice_calls_create bereitstellt, oder führen Sie bird voice --help aus, um die Befehle Ihrer CLI aufzulisten. Prüfen Sie mit bird update --check, ob neuere Versionen verfügbar sind, und lesen Sie die CLI-Installationsanleitung. Wenn das Tool oder der Befehl nicht verfügbar ist, verwenden Sie die HTTP-API oder die SDKs.
In der Vorschau bereiten CLI und MCP denselben Anruf vor, damit eine Person ihn im Browser prüfen und ausführen kann. Der Agent erhält das aufgezeichnete Annahme-Ergebnis, nachdem die Person die Anfrage ausgeführt hat.
Bevor Sie beginnen
Bereiten Sie diese Ressourcen im selben Workspace vor:
- Eine auszuführende Sequenz: eine aktivierte, nicht archivierte Sequenz mit einer aktiven Veröffentlichung, die im Dashboard erstellt wurde, oder eine vollständige Definition, die mit der Anfrage gesendet wird.
- Einen API-Schlüssel für HTTP-Anfragen oder ein OAuth-Login für CLI und MCP, jeweils mit den Berechtigungen
voice_management:writeundvoice:write. - Eine Rufnummer, die der Workspace präsentieren darf, z. B. eine eigene oder verifizierte Anrufer-ID, und ein freigeschaltetes Zielland. Bevorzugen Sie eine Nummer im Land des Empfängers: Einige Mobilfunknetze lehnen Anrufe ab, die eine ausländische Anrufer-ID präsentieren.
- Einen Empfänger, den Sie für den ersten Anruf kontrollieren.
Das sequence-Objekt akzeptiert genau eines von sequence.id oder sequence.definition. Beide benötigen außerdem entry_node_id, den Start call-Schritt, an dem der Anruf beginnt, und trigger_data, ein Objekt, das dem Datenschema des Einstiegspunkts entspricht. Verwenden Sie {}, wenn der Einstiegspunkt leere Daten akzeptiert. Die Create-Call-Referenz dokumentiert Anfragelimits und das optionale Klingel-Timeout.
Eine im Dashboard erstellte Sequenz aufrufen
Verwenden Sie sequence.id, um eine Sequenz auszuführen, die Sie im Dashboard erstellt und veröffentlicht haben. Create Call führt immer die aktive Veröffentlichung aus.
- Öffnen Sie die Sequenz unter Sequences.
- Wählen Sie unter How to run this sequence die Option More details neben Create a call.
- Wenn die Sequenz mehrere Entries hat, wählen Sie den Call trigger, mit dem der Anruf starten soll.
- Kopieren Sie die Anfrage. Sie enthält die Sequenz-ID und die Entry-ID.
Speichern Sie den Anfrage-Body als call.json und ersetzen Sie die Beispielnummern durch Ihre eigenen:
{
"from": "+12025550100",
"to": "+12025550101",
"sequence": {
"id": "YOUR_SEQUENCE_ID",
"entry_node_id": "YOUR_ENTRY_NODE_ID",
"trigger_data": {}
}
}Füllen Sie trigger_data mit den Feldern, die der Entry deklariert, einschließlich verschachtelter Objekte und Arrays. Create Call akzeptiert keine historischen Versionen, Entwürfe oder den Testmodus. Um einen gespeicherten Entwurf zu testen, verwenden Sie die Anruf tätigen-Steuerung im Dashboard.
Eine Inline-Sequenz ausführen
Verwenden Sie sequence.definition, um eine vollständige Sequenz mit dem Anruf zu senden. Bird führt sie einmal aus und speichert sie nicht, der Anruf hat also keine Sequenz-ID. Eine Inline-Definition eignet sich für Abläufe, die Ihre Anwendung pro Anruf generiert.
Eine Inline-Definition muss dieselben Prüfungen bestehen wie das Veröffentlichen einer Sequenz. Ihr Durchlauf kann höchstens 16 Befehle ausführen, einschließlich Gather-Prompts; ein Anruf, der einen 17. benötigt, endet mit dem call_limit-Trace-Fehler. Die Node-Referenz listet jeden verfügbaren Schritt mit seinen Feldern und Ergebnissen auf. Um mit einem funktionierenden Ablauf zu starten, erstellen und veröffentlichen Sie ihn im Dashboard, öffnen Sie die Sequenz und wählen Sie Copy JSON unter Definition JSON bei Published version.
Diese call.json fordert den Empfänger auf, 1 für Öffnungszeiten oder 2 für eine Wegbeschreibung zu drücken. Stille und jede andere Taste beenden den Run mit eigenen Exit-Gründen:
{
"from": "+12025550100",
"to": "+12025550101",
"sequence": {
"entry_node_id": "start",
"trigger_data": {},
"definition": {
"schema_version": 1,
"expression_environment": "bird.cel.v1",
"nodes": [
{
"id": "start",
"type": "trigger.start_call",
"type_version": 1,
"config": {},
"input": {},
"connections": { "event": { "node_id": "menu", "port": "input" } }
},
{
"id": "menu",
"type": "voice.gather",
"type_version": 1,
"config": {},
"input": {
"prompts": [
{
"type": "say",
"text": "Press 1 for opening hours, or 2 for directions.",
"language": "en"
}
],
"max_digits": 1,
"timeout_seconds": 5,
"inter_digit_timeout_seconds": 2,
"finish_on_key": "#",
"private": false,
"matches": { "hours": "1", "directions": "2" }
},
"connections": {
"hours": { "node_id": "hours", "port": "input" },
"directions": { "node_id": "directions", "port": "input" },
"timeout": { "node_id": "no_input", "port": "input" },
"fallback": { "node_id": "other_input", "port": "input" }
}
},
{
"id": "hours",
"type": "voice.say",
"type_version": 1,
"config": {},
"input": { "text": "We are open Monday through Friday, nine to five.", "language": "en" },
"connections": { "next": { "node_id": "done", "port": "input" } }
},
{
"id": "directions",
"type": "voice.say",
"type_version": 1,
"config": {},
"input": {
"text": "Find directions on your appointment confirmation.",
"language": "en"
},
"connections": { "next": { "node_id": "done", "port": "input" } }
},
{
"id": "done",
"type": "logic.exit",
"type_version": 1,
"config": { "status": "succeeded", "reason": "information_played" },
"input": { "output": {} }
},
{
"id": "no_input",
"type": "logic.exit",
"type_version": 1,
"config": { "status": "succeeded", "reason": "no_input" },
"input": { "output": {} }
},
{
"id": "other_input",
"type": "logic.exit",
"type_version": 1,
"config": { "status": "succeeded", "reason": "unrecognized_input" },
"input": { "output": {} }
}
]
}
}
}Das connections jedes Knotens ordnet ein Ergebnis dem nächsten Knoten zu. matches des Menüs benennt seine Auswahlmöglichkeiten, und connections verwendet dieselben Namen zusammen mit den eingebauten Ergebnissen timeout und fallback.
Eine Inline-Sequenz personalisieren
Deklarieren Sie die Felder, die Sie senden, im data_schema des Entrys und lesen Sie sie als trigger.data.<field> in einem $expr-Wert aus. Dieser Anruf begrüßt den Empfänger mit Namen und bestätigt oder markiert seinen Termin:
{
"from": "+12025550100",
"to": "+12025550101",
"sequence": {
"entry_node_id": "start",
"trigger_data": {
"appointment_id": "apt_2048",
"customer_name": "Sam",
"appointment_time": "Tuesday at 10 AM"
},
"definition": {
"schema_version": 1,
"expression_environment": "bird.cel.v1",
"nodes": [
{
"id": "start",
"type": "trigger.start_call",
"type_version": 1,
"config": {
"data_schema": {
"type": "object",
"additionalProperties": false,
"required": ["appointment_id", "customer_name", "appointment_time"],
"properties": {
"appointment_id": { "type": "string", "minLength": 1 },
"customer_name": { "type": "string", "minLength": 1 },
"appointment_time": { "type": "string", "minLength": 1 }
}
}
},
"input": {},
"connections": { "event": { "node_id": "confirm_menu", "port": "input" } }
},
{
"id": "confirm_menu",
"type": "voice.gather",
"type_version": 1,
"config": {},
"input": {
"prompts": [
{
"type": "say",
"text": {
"$template": [
"Hello ",
{ "$expr": "trigger.data.customer_name" },
". Press 1 to confirm your appointment on ",
{ "$expr": "trigger.data.appointment_time" },
", or 2 if you need help."
]
},
"language": "en"
}
],
"max_digits": 1,
"timeout_seconds": 7,
"inter_digit_timeout_seconds": 2,
"finish_on_key": null,
"private": false,
"matches": { "confirm": "1", "help": "2" }
},
"connections": {
"confirm": { "node_id": "confirmed", "port": "input" },
"help": { "node_id": "help_requested", "port": "input" },
"timeout": { "node_id": "no_response", "port": "input" },
"fallback": { "node_id": "no_response", "port": "input" }
}
},
{
"id": "confirmed",
"type": "logic.exit",
"type_version": 1,
"config": { "status": "succeeded", "reason": "appointment_confirmed" },
"input": {
"output": { "appointment_id": { "$expr": "trigger.data.appointment_id" } }
}
},
{
"id": "help_requested",
"type": "logic.exit",
"type_version": 1,
"config": { "status": "succeeded", "reason": "appointment_help_requested" },
"input": {
"output": { "appointment_id": { "$expr": "trigger.data.appointment_id" } }
}
},
{
"id": "no_response",
"type": "logic.exit",
"type_version": 1,
"config": { "status": "failed", "reason": "appointment_no_response" },
"input": {
"output": { "appointment_id": { "$expr": "trigger.data.appointment_id" } }
}
}
]
}
}
}status und reason jedes Exits unterscheiden eine Bestätigung, eine Bitte um Hilfe und keine Antwort. Ein trigger_data-Objekt, das nicht zu data_schema passt, schlägt bei der Validierung fehl, mit seiner Position unter /sequence/trigger_data, und es wird kein Anruf getätigt.
Die Anfrage senden
Wählen Sie unten eine Anfragemethode für die call.json, die Sie gespeichert haben.
Wählen Sie einmalig einen neuen, eindeutigen Idempotenz-Schlüssel für diesen beabsichtigten Anruf. Bewahren Sie diesen Schlüssel und die ursprüngliche Eingabe für Wiederholungsversuche oder die Wiederherstellung der Bestätigung auf. Wählen Sie einen anderen Schlüssel, wenn Sie einen separaten neuen Anruf tätigen möchten, nachdem Sie ein unbekanntes Ergebnis des ursprünglichen Anrufs geklärt haben.
Setzen Sie für die Shell-Beispiele IDEMPOTENCY_KEY auf Ihren gewählten Wert, bevor Sie senden. Die Beispiele brechen ab, wenn der Wert nicht gesetzt oder leer ist; sie erzeugen bei Wiederholung keinen neuen Schlüssel.
Setzen Sie für HTTP den Wert BIRD_API_KEY auf Ihren Schlüssel und BIRD_API_URL auf die zugehörige regionale Basis-URL, z. B. https://eu1.platform.bird.com für einen eu1-Schlüssel, und senden Sie dann die Anfrage:
curl --request POST "$BIRD_API_URL/v1/voice/calls" \
--header "Authorization: Bearer $BIRD_API_KEY" \
--header 'Content-Type: application/json' \
--header "Idempotency-Key: ${IDEMPOTENCY_KEY:?Set IDEMPOTENCY_KEY to the saved key for this intended call}" \
--data-binary @call.jsonMelden Sie sich für die CLI-Vorschau mit beiden Schreibberechtigungen an und bereiten Sie den Anruf mit derselben Datei vor:
bird auth login --scope voice_management:write --scope voice:write
bird voice calls create --body-file call.json \
--idempotency-key "${IDEMPOTENCY_KEY:?Set IDEMPOTENCY_KEY to the saved key for this intended call}"Der Befehl gibt einen Browser-Prüflink aus und wartet auf den Abschluss. Öffnen Sie den Link, prüfen Sie Anrufer, Empfänger, Sequenz und Entry-Daten und führen Sie die Anfrage selbst aus. Das Vorbereiten der Anfrage tätigt den Anruf nicht. Fügen Sie --dry-run hinzu, um die CLI-Anfrage zu inspizieren, ohne eine Bestätigung zu erstellen. Wenn die Bestätigung abläuft, abgebrochen wird oder ohne aufgezeichnetes Ergebnis endet, beendet sich der Befehl mit 5; befolgen Sie die Anleitung für Wiederholungsversuche, bevor Sie eine weitere Anfrage senden.
Rufen Sie für die MCP-Vorschau voice_calls_create mit den Feldern aus call.json und einem erforderlichen idempotency_key auf. Ersetzen Sie <unique-key-for-this-request-reuse-for-retries> durch Ihren gewählten Schlüssel:
{
"from": "+12025550100",
"to": "+12025550101",
"sequence": {
"id": "YOUR_SEQUENCE_ID",
"entry_node_id": "YOUR_ENTRY_NODE_ID",
"trigger_data": {}
},
"idempotency_key": "<unique-key-for-this-request-reuse-for-retries>"
}Folgen Sie dem zurückgegebenen Browser-Prüflink, um die Anfrage auszuführen. Wählen Sie am dynamischen MCP-Endpunkt voice_calls_create über execute. Die OAuth-Einwilligung gewährt Workspace-Berechtigungen; die Browser-Prüfung führt diesen konkreten Anruf aus.
Eine 202 Accepted-Antwort bestätigt die Annahme. Die Sequenz beginnt, nachdem der Empfänger abnimmt. Das Veröffentlichen einer neueren Version nach der Annahme ändert weder die gewählte Definition noch die Entry-Daten dieses Anrufs.
Das Annahme-Ergebnis lesen
Bewahren Sie id, initial_leg_id und sequence.run_id aus der Antwort zur Korrelation auf. Die id auf oberster Ebene identifiziert den Anruf über alle seine Legs hinweg; initial_leg_id identifiziert das erste Leg.
Die Antwort ist ein unveränderlicher Annahme-Snapshot. started_at und ended_at sind null, Beobachtungs-Booleans sind false und parties ist leer. Diese Felder beschreiben die Annahme, sie werden also nicht zu einem Live-Statusbericht, wenn Sie die Anfrage erneut abspielen.
Öffnen Sie Runs der Sequenz, um den Fortschritt zu prüfen. Ein Inline-Anruf gehört zu keiner Sequenz – folgen Sie stattdessen seinem Leg; wenn er fehlschlägt, bevor sein Leg registriert wird, gibt es noch keine Möglichkeit, ihn zu inspizieren. Sobald ein Leg-Eintrag existiert, verwenden Sie GET /v1/voice/legs/{leg_id} mit initial_leg_id oder prüfen Sie das Anrufprotokoll. Das Lesen von Legs erfordert die Berechtigung voice:read, die voice:write einschließt.
Ein Leg mit status rejected wurde abgelehnt, bevor eine Verbindung zustande kam, daher wurde seine Sequenz nicht ausgeführt. Ohne Ablehnungsgrund hat die Gegenstelle den Anruf abgewiesen; siehe Abgelehnte Anrufe.
Mit dem CLI zeigt bird voice calls get YOUR_CALL_ID den Anruf und seine Teilnehmer. bird voice legs trace YOUR_LEG_ID zeigt, welche Schritte ausgeführt wurden, die gesammelten Ziffern (sofern der Gather nicht als privat markiert ist) sowie Status und Grund des Exits. Der Trace ist kurz nach Ende des Anrufs verfügbar; bis dahin gibt der Befehl einen Fehler zurück – versuchen Sie es erneut. Die Sequenz eines abgelehnten Legs wurde nie ausgeführt, daher ist möglicherweise kein Trace vorhanden.
Die Annahme garantiert weder das Wählen, noch eine Antwort, noch einen lesbaren Anrufdatensatz. Ein Anruf, der vor der Registrierung fehlschlägt, kann in der Ausführungshistorie ohne Leg-Eintrag erscheinen. Ein beantworteter Anruf belegt auch nicht, dass die Sequenz ihre beabsichtigte Geschäftsaufgabe abgeschlossen hat.
Fehler und Wiederholungsversuche behandeln
Für direkte HTTP-Anfragen ist Idempotenz optional. Ohne Schlüssel nimmt jede Anfrage einen neuen Anrufversuch an. Die SDKs erzeugen einen Schlüssel für automatische Wiederholungsversuche. Um Wiederholungsversuche über separate Anrufe oder direkte HTTP-Anfragen abzusichern, geben Sie beim ersten Versuch einen Schlüssel an und verwenden Sie ihn mit den exakt gleichen ursprünglichen Request-Bytes erneut. Siehe den Idempotenz-Leitfaden.
Ein identisches Replay innerhalb von drei Stunden gibt die ursprüngliche Annahme und Idempotency-Replay: true zurück. Geänderte Eingabe mit demselben Schlüssel gibt 409 zurück. Autorisierung und Rufnummern-Berechtigung werden beim Replay erneut geprüft. Nach dem Replay-Fenster kann der Schlüssel einen neuen Anruf annehmen – gleichen Sie daher das ursprüngliche Ergebnis ab, bevor Sie erneut senden.
Geben Sie für CLI und MCP den Idempotenz-Schlüssel beim ersten Versuch an. Das Wiederholen derselben Anfrage und desselben Schlüssels mit derselben OAuth-Genehmigung gibt die bestehende Bestätigung zurück, solange ihr Datensatz erhalten bleibt. Bewahren Sie die ursprüngliche Eingabe und die Bestätigungs-ID auf. Das Ändern des Schlüssels kann einen weiteren kostenpflichtigen Anruf vorbereiten.
Wenn der CLI-Befehl unterbrochen wird, setzen Sie ihn mit der ursprünglichen Eingabe, dem Schlüssel und der zurückgegebenen Bestätigungs-ID fort:
bird voice calls create --body-file call.json \
--idempotency-key "${IDEMPOTENCY_KEY:?Set IDEMPOTENCY_KEY to the saved key for this intended call}" \
--confirmation-id YOUR_CONFIRMATION_IDWiederholen Sie für MCP die ursprünglichen Tool-Argumente, einschließlich desselben idempotency_key, zusammen mit dem zurückgegebenen Request-State. Der State identifiziert die Bestätigung und ersetzt diese Argumente nicht. Alternativ wiederholen Sie dasselbe Tool und dieselben Argumente mit der zurückgegebenen ID in bird/confirmation-id-Request-Metadaten. Mit dynamischem MCP wiederholen Sie dieselbe execute-Anfrage und fügen diese Metadaten hinzu. Beim Fortsetzen wird die ursprüngliche Bestätigung gelesen und ihr aufgezeichnetes Ergebnis zurückgegeben, sobald sie abgeschlossen ist.
Eine Create-Call-Bestätigung läuft nach 90 Minuten ab. Eine pending- oder expired-Bestätigung ohne Ergebnis beweist nicht, dass der Anruf nie stattfand. Prüfen Sie die ursprüngliche Sequenzausführung und einen etwaigen Call-Leg-Eintrag, bevor Sie einen weiteren Anruf tätigen; erstellen Sie keinen neuen Schlüssel, um ein unbekanntes Ergebnis zu klären. Eine abgeschlossene Bestätigung mit einem 202-Ergebnis belegt die Annahme – fahren Sie mit den Annahme-Prüfungen fort, um das Ergebnis des Anrufs festzustellen.
| Symptom | Was Sie prüfen sollten |
|---|---|
400 oder 422 | Lesen Sie die Felddetails des Fehlers. Prüfen Sie Nummernformat, Rufnummern-Berechtigung und -Eigentümerschaft, Sequenz- und Entry-IDs, explizites Datenobjekt und Anfrage-Limits. |
401 oder 403 | Prüfen Sie Ihren API-Schlüssel oder Ihr OAuth-Login, beide erforderlichen Schreibberechtigungen und den Workspace-Zugriff. |
404 | Prüfen Sie, ob die Sequenz zum ausgewählten Workspace gehört und die Anruferstellung auf dem regionalen Dienst verfügbar ist. |
409 | Prüfen Sie, ob ein Wiederholungsversuch mit geändertem Body oder eine nicht verfügbare aktive Produktionssequenz vorliegt. Veröffentlichen oder setzen Sie bei Bedarf fort, bevor Sie einen neuen Anruf starten. |
429 | Befolgen Sie die Wiederholungsanleitung der Antwort. Wenn Sie einen Schlüssel angegeben haben, verwenden Sie ihn für denselben Anrufversuch erneut. |
| Angenommen, dann fehlgeschlagen | Prüfen Sie die Ausführung und einen etwaigen Leg-Eintrag auf Ziel, Limits, Guthaben oder Laufzeitfehler, bevor Sie einen weiteren Anruf tätigen. |
Nächste Schritte
Verwandte Ressourcen
Weiter mit der Dokumentation, Anleitungen und Beispielen zu diesem Thema.