Sign inGet Started

Een spraakoproep maken

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.

Gebruik POST /v1/voice/calls om een telefoonnummer te bellen en een gepubliceerde sequence, of een met het verzoek meegestuurde sequence-definitie, te starten wanneer de ontvanger opneemt. Het verzoek plaatst een echte oproep; normale belkosten zijn van toepassing.

CLI- en MCP-preview: Deze interfaces vereisen een compatibele client. Controleer of je MCP-server voice_calls_create aanbiedt, of voer bird voice --help uit om de opdrachten in je CLI weer te geven. Controleer met bird update --check of er nieuwere versies zijn en zie CLI installeren. Als de tool of opdracht niet beschikbaar is, gebruik je de HTTP-API of de SDK's.

In de preview bereiden de CLI en MCP dezelfde oproep voor zodat een persoon deze in de browser kan beoordelen en uitvoeren. De agent ontvangt het vastgelegde acceptatieresultaat nadat de persoon het verzoek heeft uitgevoerd.

Voordat je begint

Bereid de volgende resources voor in dezelfde werkruimte:

  • Een uit te voeren sequence: een ingeschakelde, niet-gearchiveerde sequence met een actieve publicatie die in het dashboard is gebouwd, of een volledige definitie die met het verzoek wordt meegestuurd.
  • Een API-key voor HTTP-verzoeken, of een OAuth-login voor CLI en MCP, met zowel voice_management:write- als voice:write-rechten.
  • Een belnummer dat de werkruimte mag presenteren, zoals een eigen of geverifieerde beller-ID, en een ingeschakeld bestemmingsland. Gebruik bij voorkeur een nummer in het land van de ontvanger: sommige mobiele netwerken weigeren een oproep met een buitenlandse beller-ID.
  • Een ontvanger die je zelf beheert voor de eerste oproep.

Het sequence-object accepteert precies één van sequence.id of sequence.definition. Beide vereisen ook entry_node_id, de Start call-stap waar het gesprek begint, en trigger_data, een object dat overeenkomt met het dataschema van die entry. Gebruik {} als de entry lege data accepteert. De Create Call-referentie documenteert aanvraaglimieten en de optionele beltimeout.

Een sequence uit het dashboard bellen

Gebruik sequence.id om een sequence uit te voeren die je in het dashboard hebt gebouwd en gepubliceerd. Create Call voert altijd de actieve publicatie uit.

  1. Open de sequence in Sequences.
  2. Selecteer onder How to run this sequence de optie More details naast Create a call.
  3. Als de sequence meerdere entries heeft, kies je de Call trigger waarmee je wilt starten.
  4. Kopieer het verzoek. Het bevat het sequence-ID en het entry-ID.

Sla de verzoekbody op als call.json en vervang de voorbeeldnummers door je eigen nummers:

Codevoorbeeld
{
  "from": "+12025550100",
  "to": "+12025550101",
  "sequence": {
    "id": "YOUR_SEQUENCE_ID",
    "entry_node_id": "YOUR_ENTRY_NODE_ID",
    "trigger_data": {}
  }
}

Vul trigger_data in met de velden die de entry declareert, inclusief geneste objecten en arrays. Create Call accepteert geen historische versies, concepten of testmodus. Gebruik om een opgeslagen concept te testen de Oproep plaatsen-bedieningselementen in het dashboard.

Een inline sequence uitvoeren

Gebruik sequence.definition om een volledige sequence met de oproep mee te sturen. Bird voert deze één keer uit en slaat hem niet op, dus de oproep heeft geen sequence-ID. Een inline-definitie past bij flows die je applicatie per oproep genereert.

Een inline definitie moet dezelfde controles doorstaan als het publiceren van een sequence. De uitvoering kan maximaal 16 opdrachten uitvoeren, inclusief gather-prompts; een oproep die een 17e nodig heeft, eindigt met de call_limit trace-fout. De node-referentie beschrijft elke stap die je kunt gebruiken, met de bijbehorende velden en uitkomsten. Om vanuit een werkende flow te beginnen, bouw en publiceer je deze in het dashboard, open je de sequence en selecteer je Copy JSON bij Definition JSON onder Published version.

Deze call.json vraagt de ontvanger om 1 te drukken voor openingstijden of 2 voor een routebeschrijving. Stilte en elke andere toets beëindigen de run met hun eigen exitredenen:

Codevoorbeeld
{
  "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": {} }
        }
      ]
    }
  }
}

De connections van elke node koppelt een uitkomst aan de volgende node. De matches van het menu benoemt de keuzes, en connections gebruikt dezelfde namen naast de ingebouwde timeout- en fallback-uitkomsten.

Een inline sequence personaliseren

Declareer de velden die je meestuurt in de data_schema van de entry en lees ze als trigger.data.<field> in een $expr-waarde. Deze oproep begroet de ontvanger bij naam en bevestigt of markeert hun afspraak:

Codevoorbeeld
{
  "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" } }
          }
        }
      ]
    }
  }
}

De status en reason van elke exit scheiden een bevestiging, een verzoek om hulp en geen reactie. Een trigger_data-object dat niet overeenkomt met data_schema faalt bij validatie, met de locatie onder /sequence/trigger_data, en er wordt geen oproep geplaatst.

Verstuur het verzoek

Kies hieronder één verzoekmethode voor de call.json die je hebt opgeslagen.

Kies eenmalig een nieuwe, unieke idempotency-key voor deze beoogde oproep. Bewaar die key en de oorspronkelijke invoer voor herhaalpogingen of bevestigingsherstel. Kies een andere key wanneer je een nieuwe, aparte oproep wilt plaatsen, nadat je een onbekende uitkomst van de oorspronkelijke oproep hebt opgelost.

Stel voor de shell-voorbeelden IDEMPOTENCY_KEY in op de door jou gekozen waarde voordat je verzendt. De voorbeelden stoppen als deze niet is ingesteld of leeg is; ze genereren geen nieuwe key bij herhaling.

Stel voor HTTP BIRD_API_KEY in op je key en BIRD_API_URL op de bijbehorende regionale basis-URL, zoals https://eu1.platform.bird.com voor een eu1-key, en verstuur vervolgens het verzoek:

Codevoorbeeld
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.json

Log voor de CLI-preview in met beide schrijfrechten en bereid de oproep voor met hetzelfde bestand:

Codevoorbeeld
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}"

De opdracht toont een browserbeoordelingslink en wacht op voltooiing. Open de link, controleer de beller, ontvanger, sequence en entry-data, en voer het verzoek zelf uit. Het voorbereiden van het verzoek plaatst de oproep niet. Voeg --dry-run toe om het CLI-verzoek te inspecteren zonder een bevestiging aan te maken. Als de bevestiging verloopt, wordt geannuleerd of eindigt zonder vastgelegd resultaat, sluit de opdracht af met 5; volg de richtlijnen voor opnieuw proberen voordat je een nieuw verzoek doet.

Roep voor de MCP-preview voice_calls_create aan met de velden uit call.json en een verplichte idempotency_key. Vervang <unique-key-for-this-request-reuse-for-retries> door de door jou gekozen key:

Codevoorbeeld
{
  "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>"
}

Volg de teruggegeven browserbeoordelingslink om het verzoek uit te voeren. Selecteer op het dynamische MCP-endpoint voice_calls_create via execute. OAuth-toestemming verleent werkruimterechten; de browserbeoordeling voert deze specifieke oproep uit.

Een 202 Accepted-antwoord bevestigt toelating. De sequence begint nadat de ontvanger opneemt. Het publiceren van een nieuwere versie na acceptatie wijzigt de geselecteerde definitie of entry-data van deze oproep niet.

Lees het acceptatieresultaat

Bewaar de id, initial_leg_id en sequence.run_id uit het antwoord voor correlatie. De id op het hoogste niveau identificeert de oproep over al zijn legs; initial_leg_id identificeert de eerste leg.

Het antwoord is een onveranderlijke acceptatie-snapshot. De started_at en ended_at ervan zijn null, observatie-booleans zijn false en parties is leeg. Deze velden beschrijven acceptatie en worden dus geen live statusrapport wanneer je het verzoek opnieuw afspeelt.

Open de Runs van de sequence om de voortgang te bekijken. Een inline oproep hoort bij geen sequence, dus volg in plaats daarvan het leg-record; als de oproep mislukt voordat het leg-record wordt aangemaakt, is er nog geen manier om deze te inspecteren. Zodra er een leg-record bestaat, gebruik je GET /v1/voice/legs/{leg_id} met initial_leg_id, of bekijk je het gesprekslogboek. Het lezen van legs vereist de voice:read-machtiging, die voice:write bevat.

Een leg met status rejected is geweigerd voordat er verbinding was, dus de sequence is niet uitgevoerd. Zonder weigeringsreden heeft het andere uiteinde de oproep afgewezen; zie Geweigerde oproepen.

Met de CLI toont bird voice calls get YOUR_CALL_ID het gesprek en de betrokken partijen. bird voice legs trace YOUR_LEG_ID toont welke stappen zijn uitgevoerd, de verzamelde cijfers tenzij de gather privé is, en de status en reden van de exit. De trace is kort na het einde van het gesprek beschikbaar; tot dat moment geeft het commando een fout terug, dus probeer het opnieuw. De sequence van een geweigerde leg is nooit uitgevoerd, dus er is mogelijk geen trace.

Acceptatie garandeert niet dat er wordt gebeld, dat de oproep wordt beantwoord of dat er een leesbaar oproeprecord beschikbaar is. Een oproep die mislukt vóór registratie kan in de uitvoeringsgeschiedenis verschijnen zonder leg-record. Een beantwoorde oproep bewijst evenmin dat de sequence de beoogde bedrijfstaak heeft voltooid.

Fouten en herhaalpogingen afhandelen

Voor directe HTTP-verzoeken is idempotency optioneel. Zonder key accepteert elk verzoek een nieuwe oproeppoging. De SDK's genereren een key voor automatische herhaalpogingen. Om herhaalpogingen over afzonderlijke oproepen of directe HTTP-verzoeken te beschermen, geef je bij de eerste poging een key mee en hergebruik je die met exact dezelfde oorspronkelijke verzoekbytes. Zie de idempotency-gids.

Een identieke herhaling binnen drie uur retourneert de oorspronkelijke acceptatie en Idempotency-Replay: true. Gewijzigde invoer met diezelfde key retourneert 409. Autorisatie en oproepnummerrechten worden bij herhaling opnieuw gecontroleerd. Na het herhalingsvenster kan de key een nieuwe oproep toelaten; stem dus het oorspronkelijke resultaat af voordat je opnieuw indient.

Geef voor CLI en MCP de idempotency-key mee bij de eerste poging. Als je hetzelfde verzoek en dezelfde key herhaalt met dezelfde OAuth-toekenning, wordt de bestaande bevestiging geretourneerd zolang het record bewaard blijft. Bewaar de oorspronkelijke invoer en het bevestigings-ID. Het wijzigen van de key kan een nieuwe factureerbare oproep voorbereiden.

Als de CLI-opdracht wordt onderbroken, hervat je met de oorspronkelijke invoer, key en het geretourneerde bevestigings-ID:

Codevoorbeeld
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_ID

Herhaal voor MCP de oorspronkelijke tool-argumenten, inclusief dezelfde idempotency_key, samen met de geretourneerde request-state. De state identificeert de bevestiging en vervangt die argumenten niet. Je kunt ook dezelfde tool en argumenten herhalen met het geretourneerde ID in bird/confirmation-id-verzoekmetadata. Herhaal bij dynamische MCP hetzelfde execute-verzoek en plaats die metadata erop. Hervatten leest de oorspronkelijke bevestiging en retourneert het vastgelegde resultaat wanneer het is voltooid.

Een Create Call-bevestiging verloopt na 90 minuten. Een pending- of expired-bevestiging zonder resultaat bewijst niet dat de oproep nooit is uitgevoerd. Inspecteer de oorspronkelijke sequence-run en eventuele leg-records voordat je besluit een nieuwe oproep te plaatsen; maak geen nieuwe key aan om een onbekende uitkomst op te lossen. Een voltooide bevestiging met een 202-resultaat bewijst acceptatie; ga dus verder met de acceptatiecontroles om de uitkomst van de oproep vast te stellen.

SymptoomWat te controleren
400 of 422Lees de velddetails van de fout. Controleer nummerformaat, geschiktheid en eigendom van het oproepnummer, sequence- en entry-ID's, expliciet data-object en verzoeklimieten.
401 of 403Controleer je API-key of OAuth-login, beide vereiste schrijfrechten en werkruimtetoegang.
404Controleer of de sequence bij de geselecteerde werkruimte hoort en of het aanmaken van oproepen beschikbaar is op de regionale service.
409Controleer op een herhaalde poging met gewijzigde body of een niet-beschikbare actieve productie-sequence. Publiceer of hervat indien nodig voordat je een nieuwe oproep begint.
429Volg de richtlijnen voor opnieuw proberen in het antwoord. Als je een key hebt meegegeven, hergebruik die voor dezelfde oproeppoging.
Geaccepteerd, daarna misluktInspecteer de run en eventuele leg-records op bestemming, limieten, saldo of runtime-fouten voordat je besluit een nieuwe oproep te plaatsen.

Volgende stappen

Ga verder met de documentatie, handleidingen en voorbeelden voor dit onderwerp.