Sign inGet Started

वॉइस कॉल बनाएँ

चेतावनी: Voice सीक्वेंस प्रीव्यू में हैं। चरण, एंट्री डेटा और सीक्वेंस परिभाषा का फ़ॉर्मैट इस तरह बदल सकते हैं कि मौजूदा सीक्वेंस और API अनुरोध काम करना बंद कर दें।

किसी फ़ोन नंबर पर कॉल करने के लिए POST /v1/voice/calls का उपयोग करें। प्राप्तकर्ता के कॉल उठाने पर एक प्रकाशित सीक्वेंस शुरू होता है, या अनुरोध के साथ भेजी गई सीक्वेंस परिभाषा। यह अनुरोध असली कॉल करता है, इसलिए सामान्य कॉलिंग शुल्क लागू होते हैं।

CLI और MCP प्रीव्यू: इन इंटरफ़ेस के लिए संगत क्लाइंट ज़रूरी है। जाँचें कि आपका MCP सर्वर voice_calls_create उपलब्ध कराता है, या अपने CLI में कमांड की सूची देखने के लिए bird voice --help चलाएँ। नई रिलीज़ के लिए bird update --check से जाँचें और CLI इंस्टॉलेशन देखें। अगर टूल या कमांड उपलब्ध नहीं है, तो HTTP API या SDK का उपयोग करें।

प्रीव्यू में CLI और MCP वही कॉल तैयार करते हैं, ताकि कोई व्यक्ति ब्राउज़र में उसकी समीक्षा करके उसे चला सके। व्यक्ति के अनुरोध चलाने के बाद एजेंट को दर्ज किया गया स्वीकृति परिणाम मिलता है।

शुरू करने से पहले

ये संसाधन एक ही वर्कस्पेस में तैयार करें:

  • चलाने के लिए एक सीक्वेंस: डैशबोर्ड में बना, सक्षम और अनआर्काइव्ड सक्रिय प्रकाशन वाला सीक्वेंस, या अनुरोध के साथ भेजी गई पूरी परिभाषा।
  • HTTP अनुरोधों के लिए एक API कुंजी, या CLI और MCP के लिए OAuth लॉगिन, जिसमें voice_management:write और voice:write दोनों अनुमतियाँ हों।
  • ऐसा कॉलिंग नंबर जिसे वर्कस्पेस दिखा सकता है, जैसे आपके स्वामित्व वाला या सत्यापित कॉलर ID, और एक सक्षम गंतव्य देश। प्राप्तकर्ता के देश का नंबर चुनें, क्योंकि कुछ मोबाइल नेटवर्क विदेशी कॉलर ID वाली कॉल अस्वीकार कर देते हैं।
  • पहली कॉल के लिए ऐसा प्राप्तकर्ता जिस पर आपका नियंत्रण हो।

sequence ऑब्जेक्ट में sequence.id या sequence.definition में से ठीक एक होना चाहिए। दोनों के साथ entry_node_id भी चाहिए, यानी वह Start call चरण जहाँ से कॉल शुरू होती है, और trigger_data भी, यानी उस एंट्री के डेटा स्कीमा से मेल खाने वाला ऑब्जेक्ट। अगर एंट्री खाली डेटा स्वीकार करती है, तो {} का उपयोग करें। Create Call संदर्भ में अनुरोध की सीमाएँ और वैकल्पिक रिंगिंग टाइमआउट दिए गए हैं।

डैशबोर्ड में बनाए गए सीक्वेंस से कॉल करें

डैशबोर्ड में बनाए और प्रकाशित किए गए सीक्वेंस को चलाने के लिए sequence.id का उपयोग करें। Create Call हमेशा उसका सक्रिय प्रकाशन चलाता है।

  1. Sequences में सीक्वेंस खोलें।
  2. How to run this sequence के अंतर्गत, Create a call के बगल में More details चुनें।
  3. अगर सीक्वेंस में कई एंट्री हैं, तो शुरू करने के लिए Call trigger चुनें।
  4. अनुरोध कॉपी करें। इसमें सीक्वेंस ID और एंट्री ID होती हैं।

उदाहरण वाले नंबरों की जगह अपने नंबर डालकर अनुरोध बॉडी को call.json के रूप में सेव करें:

कोड उदाहरण
{
  "from": "+12025550100",
  "to": "+12025550101",
  "sequence": {
    "id": "YOUR_SEQUENCE_ID",
    "entry_node_id": "YOUR_ENTRY_NODE_ID",
    "trigger_data": {}
  }
}

trigger_data में वे फ़ील्ड भरें जो एंट्री घोषित करती है, जिनमें नेस्टेड ऑब्जेक्ट और ऐरे भी शामिल हैं। Create Call पुराने संस्करण, ड्राफ़्ट या टेस्ट मोड स्वीकार नहीं करता। सेव किए गए ड्राफ़्ट को टेस्ट करने के लिए, डैशबोर्ड के Place a call कंट्रोल का उपयोग करें।

इनलाइन सीक्वेंस चलाएँ

कॉल के साथ पूरा सीक्वेंस भेजने के लिए sequence.definition का उपयोग करें। Bird इसे एक बार चलाता है और सेव नहीं करता, इसलिए कॉल की कोई सीक्वेंस ID नहीं होती। इनलाइन परिभाषा उन फ़्लो के लिए उपयुक्त है जिन्हें आपका एप्लिकेशन हर कॉल के लिए बनाता है।

इनलाइन परिभाषा को वही जाँचें पास करनी होती हैं जो सीक्वेंस प्रकाशित करने पर होती हैं। उसका रन अधिकतम 16 कमांड चला सकता है, जिनमें gather प्रॉम्प्ट भी शामिल हैं; जिस कॉल को 17वीं कमांड की ज़रूरत होती है, वह call_limit ट्रेस त्रुटि के साथ समाप्त हो जाती है। नोड संदर्भ में हर उपलब्ध चरण उसके फ़ील्ड और परिणामों के साथ दिया गया है। किसी काम करने वाले फ़्लो से शुरू करने के लिए, उसे डैशबोर्ड में बनाकर प्रकाशित करें, सीक्वेंस खोलें, और Published version के अंतर्गत Definition JSON पर Copy JSON चुनें।

यह call.json प्राप्तकर्ता से खुलने के समय के लिए 1 या रास्ते की जानकारी के लिए 2 दबाने को कहता है। चुप रहने या कोई अन्य कुंजी दबाने पर रन अपने-अपने निकास कारणों के साथ समाप्त होता है:

कोड उदाहरण
{
  "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": {} }
        }
      ]
    }
  }
}

हर नोड का connections किसी परिणाम को अगले नोड से जोड़ता है। मेनू का matches उसके विकल्पों के नाम तय करता है, और connections इन्हीं नामों के साथ बिल्ट-इन timeout और fallback परिणामों का उपयोग करता है।

इनलाइन सीक्वेंस को वैयक्तिकृत करें

आप जो फ़ील्ड भेजते हैं, उन्हें एंट्री के data_schema में घोषित करें, फिर किसी $expr मान में उन्हें trigger.data.<field> के रूप में पढ़ें। यह कॉल प्राप्तकर्ता का नाम लेकर अभिवादन करती है और उनकी अपॉइंटमेंट की पुष्टि करती है या उसे चिह्नित करती है:

कोड उदाहरण
{
  "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 और reason पुष्टि, मदद के अनुरोध और कोई जवाब न मिलने को अलग-अलग करते हैं। जो trigger_data ऑब्जेक्ट data_schema से मेल नहीं खाता, वह सत्यापन में विफल होता है, उसका स्थान /sequence/trigger_data में दिया जाता है, और कोई कॉल नहीं की जाती।

अनुरोध भेजें

सहेजे गए call.json के लिए नीचे दी गई अनुरोध विधियों में से एक चुनें।

इस इच्छित कॉल के लिए एक बार एक नई, अद्वितीय idempotency कुंजी चुनें। फिर से प्रयास करने या पुष्टि पुनः प्राप्त करने के लिए वह कुंजी और मूल इनपुट संभालकर रखें। जब आप एक अलग नई कॉल करना चाहें, तो मूल कॉल के किसी भी अज्ञात परिणाम को सुलझाने के बाद दूसरी कुंजी चुनें।

शेल उदाहरणों के लिए, भेजने से पहले IDEMPOTENCY_KEY को अपने चुने हुए मान पर सेट करें। अगर यह सेट नहीं है या खाली है, तो उदाहरण रुक जाते हैं; दोहराने पर वे कोई दूसरी कुंजी नहीं बनाते।

HTTP के लिए, BIRD_API_KEY को अपनी कुंजी पर और BIRD_API_URL को उसके क्षेत्रीय बेस URL पर सेट करें, जैसे eu1 कुंजी के लिए https://eu1.platform.bird.com, फिर अनुरोध भेजें:

कोड उदाहरण
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

CLI प्रीव्यू के लिए, दोनों write अनुमतियों के साथ साइन इन करें और उसी फ़ाइल से कॉल तैयार करें:

कोड उदाहरण
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}"

कमांड ब्राउज़र में समीक्षा का एक लिंक दिखाती है और पूरा होने की प्रतीक्षा करती है। लिंक खोलें, कॉलर, प्राप्तकर्ता, सीक्वेंस और एंट्री डेटा जाँचें, और अनुरोध खुद चलाएँ। अनुरोध तैयार करने से कॉल नहीं होती। पुष्टि बनाए बिना CLI अनुरोध देखने के लिए --dry-run जोड़ें। अगर पुष्टि की अवधि समाप्त हो जाती है, वह रद्द हो जाती है, या कोई परिणाम दर्ज हुए बिना खत्म हो जाती है, तो कमांड 5 के साथ बाहर निकलती है; दूसरा अनुरोध करने से पहले फिर से प्रयास के दिशानिर्देश का पालन करें।

MCP प्रीव्यू में, call.json के फ़ील्ड और आवश्यक idempotency_key के साथ voice_calls_create को कॉल करें। <unique-key-for-this-request-reuse-for-retries> की जगह अपनी चुनी हुई कुंजी डालें:

कोड उदाहरण
{
  "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>"
}

अनुरोध चलाने के लिए लौटाए गए ब्राउज़र समीक्षा लिंक पर जाएँ। डायनेमिक MCP एंडपॉइंट पर, execute के ज़रिए voice_calls_create चुनें। OAuth सहमति वर्कस्पेस अनुमतियाँ देती है; ब्राउज़र समीक्षा यह विशिष्ट कॉल चलाती है।

202 Accepted प्रतिक्रिया पुष्टि करती है कि कॉल स्वीकार हो गई है। प्राप्तकर्ता के जवाब देने के बाद सीक्वेंस शुरू होता है। स्वीकृति के बाद नया संस्करण प्रकाशित करने से इस कॉल की चुनी गई परिभाषा या एंट्री डेटा नहीं बदलता।

स्वीकृति परिणाम पढ़ें

सहसंबंध के लिए प्रतिक्रिया के id, initial_leg_id और sequence.run_id सहेजकर रखें। शीर्ष-स्तर का id कॉल को उसके सभी लेग में पहचानता है; initial_leg_id उसके पहले लेग को पहचानता है।

प्रतिक्रिया स्वीकृति का एक अपरिवर्तनीय स्नैपशॉट है। इसके started_at और ended_at का मान null होता है, अवलोकन बूलियन false होते हैं, और parties खाली होता है। ये फ़ील्ड स्वीकृति का वर्णन करते हैं, इसलिए अनुरोध दोबारा चलाने पर ये लाइव स्थिति रिपोर्ट नहीं बनते।

प्रगति देखने के लिए सीक्वेंस के Runs खोलें। इनलाइन कॉल किसी सीक्वेंस से जुड़ी नहीं होती, इसलिए उसके लेग को देखें; यदि वह लेग दर्ज होने से पहले विफल हो जाए, तो उसे देखने का अभी कोई तरीका नहीं है। लेग रिकॉर्ड बन जाने पर initial_leg_id के साथ GET /v1/voice/legs/{leg_id} का उपयोग करें, या कॉल लॉग देखें। लेग पढ़ने के लिए voice:read अनुमति चाहिए, जो voice:write में शामिल है।

status rejected वाला लेग कनेक्ट होने से पहले अस्वीकार कर दिया गया था, इसलिए उसका सीक्वेंस नहीं चला। यदि अस्वीकृति का कारण नहीं दिया गया है, तो दूसरी ओर से कॉल अस्वीकार की गई; अस्वीकृत कॉल देखें।

CLI के साथ, bird voice calls get YOUR_CALL_ID कॉल और उसके पक्षों को दिखाता है। bird voice legs trace YOUR_LEG_ID दिखाता है कि कौन-से चरण चले, एकत्र किए गए अंक (जब तक gather निजी न हो), और निकास की स्थिति और कारण। ट्रेस कॉल खत्म होने के कुछ ही देर बाद तैयार होता है; तब तक कमांड त्रुटि लौटाती है, इसलिए उसे चलाने का फिर से प्रयास करें। अस्वीकृत लेग का सीक्वेंस कभी नहीं चला, इसलिए हो सकता है उसका कोई ट्रेस न हो।

स्वीकृति इस बात की गारंटी नहीं देती कि नंबर डायल होगा, जवाब मिलेगा या पढ़ने योग्य कॉल रिकॉर्ड बनेगा। पंजीकरण से पहले विफल होने वाली कॉल लेग रिकॉर्ड के बिना रन इतिहास में दिख सकती है। जवाब मिल जाने से भी यह सिद्ध नहीं होता कि सीक्वेंस ने अपना इच्छित व्यावसायिक काम पूरा किया।

त्रुटियाँ और फिर से प्रयास संभालें

सीधे HTTP अनुरोधों के लिए idempotency वैकल्पिक है। कुंजी के बिना, हर अनुरोध एक नया कॉल प्रयास स्वीकार करता है। SDK स्वचालित रूप से फिर से प्रयास करने के लिए एक कुंजी बनाते हैं। अलग-अलग कॉल या सीधे HTTP अनुरोधों में फिर से प्रयास को सुरक्षित रखने के लिए, पहले प्रयास पर कुंजी दें और मूल अनुरोध के बिल्कुल वही बाइट्स भेजते हुए उसे दोबारा उपयोग करें। idempotency गाइड देखें।

तीन घंटे के भीतर समान अनुरोध दोबारा भेजने पर मूल स्वीकृति और Idempotency-Replay: true लौटते हैं। उसी कुंजी के साथ बदला हुआ इनपुट भेजने पर 409 लौटता है। दोबारा भेजने पर प्राधिकरण और कॉलिंग नंबर की अनुमति फिर से जाँची जाती है। रीप्ले अवधि के बाद यह कुंजी नई कॉल स्वीकार कर सकती है, इसलिए दोबारा सबमिट करने से पहले मूल परिणाम का मिलान करें।

CLI और MCP के लिए पहले प्रयास में ही idempotency कुंजी दें। उसी OAuth अनुमति के साथ वही अनुरोध और कुंजी दोहराने पर, जब तक रिकॉर्ड रखा जाता है, मौजूदा पुष्टि लौटती है। मूल इनपुट और पुष्टि ID सँभालकर रखें। कुंजी बदलने से एक और शुल्क-योग्य कॉल तैयार हो सकती है।

यदि CLI कमांड बीच में रुक जाए, तो मूल इनपुट, कुंजी और लौटाई गई पुष्टि ID के साथ उसे फिर से शुरू करें:

कोड उदाहरण
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

MCP के लिए मूल टूल आर्ग्युमेंट, उसी idempotency_key सहित, लौटाई गई अनुरोध स्थिति के साथ दोहराएँ। यह स्थिति पुष्टि की पहचान करती है, पर उन आर्ग्युमेंट की जगह नहीं लेती। वैकल्पिक रूप से, वही टूल और आर्ग्युमेंट दोहराएँ और लौटाई गई ID को bird/confirmation-id अनुरोध मेटाडेटा में रखें। डायनेमिक MCP के साथ वही execute अनुरोध दोहराएँ और उस पर यह मेटाडेटा लगाएँ। फिर से शुरू करने पर मूल पुष्टि पढ़ी जाती है और पूरी होने पर उसका दर्ज परिणाम लौटता है।

Create Call की पुष्टि 90 मिनट बाद समाप्त हो जाती है। परिणाम के बिना pending या expired पुष्टि यह साबित नहीं करती कि कॉल कभी नहीं चली। दूसरी कॉल करने का निर्णय लेने से पहले मूल सीक्वेंस रन और किसी भी कॉल-लेग रिकॉर्ड की जाँच करें; अज्ञात परिणाम सुलझाने के लिए नई कुंजी न बनाएँ। 202 परिणाम वाली पूरी हुई पुष्टि स्वीकृति साबित करती है, इसलिए कॉल का परिणाम जानने के लिए स्वीकृति जाँचों के साथ आगे बढ़ें।

लक्षणक्या जाँचें
400 या 422त्रुटि के फ़ील्ड विवरण पढ़ें। नंबर का फ़ॉर्मैट, कॉलिंग नंबर की पात्रता और स्वामित्व, सीक्वेंस और एंट्री ID, स्पष्ट डेटा ऑब्जेक्ट और अनुरोध सीमाएँ जाँचें।
401 या 403अपनी API कुंजी या OAuth लॉगिन, दोनों आवश्यक write अनुमतियाँ और वर्कस्पेस एक्सेस जाँचें।
404जाँचें कि सीक्वेंस चुने गए वर्कस्पेस से संबंधित है और क्षेत्रीय सेवा पर कॉल बनाना उपलब्ध है।
409जाँचें कि कहीं बदले हुए बॉडी के साथ फिर से प्रयास तो नहीं किया गया, या सक्रिय प्रोडक्शन सीक्वेंस अनुपलब्ध तो नहीं है। नई कॉल शुरू करने से पहले ज़रूरत के अनुसार प्रकाशित करें या फिर से चालू करें।
429प्रतिक्रिया में दिए गए फिर से प्रयास के निर्देशों का पालन करें। अगर आपने कुंजी दी थी, तो उसी कॉल प्रयास के लिए उसे दोबारा इस्तेमाल करें।
स्वीकार हुई, फिर विफलदूसरी कॉल करने का निर्णय लेने से पहले रन और किसी भी लेग रिकॉर्ड में गंतव्य, सीमाओं, बैलेंस या रनटाइम विफलताओं की जाँच करें।

अगले चरण

इस विषय के लिए दस्तावेज़, गाइड और उदाहरणों के साथ आगे बढ़ें।