---
title: "टूल इंटीग्रेशन (API) बनाएं"
description: "अपने एजेंट को बातचीत के दौरान आपके APIs कॉल करने दें — डेटाबेस खोजें, टिकट बनाएं, ऑर्डर देखें।"
---

एक **टूल इंटीग्रेशन** एक पुन: उपयोग योग्य HTTP एंडपॉइंट है जिसे एजेंट
कॉल के दौरान इनवोक कर सकता है। आप ThunderPhone को टूल का JSON-schema विवरण
और एक एंडपॉइंट URL देते हैं; एजेंट बातचीत के आधार पर तय करता है कि इसे कब कॉल करना है,
और ThunderPhone अपने सर्वरों से आउटबाउंड HTTP रिक्वेस्ट करता है और एजेंट को
रिस्पॉन्स लौटाता है।

<Note>
  इस API के बिना भी डैशबोर्ड अधिकांश टूल आवश्यकताओं को कवर करता है: **कनेक्शन
  → ऐप्स** कुछ OAuth क्लिक्स में Slack, HubSpot, Salesforce, Google Calendar,
  Google Sheets और Cal.com को कनेक्ट करता है; **कनेक्शन →
  APIs** किसी भी HTTP API को एजेंट एक्शन में बदलता है (एक cURL कमांड पेस्ट करें
  और एक AI विज़ार्ड टूल का ड्राफ़्ट बनाता है, जिसमें बिल्ट-इन टेस्ट रिक्वेस्ट होता है); और
  **कनेक्शन → MCP** MCP सर्वर जोड़ता है। देखें
  [कनेक्शन](/hi/guides/concepts)। यह गाइड APIs इंटरफ़ेस के अंतर्गत मौजूद
  मूल API के बारे में है।
</Note>

यह गाइड शुरू से अंत तक मौसम-लुकअप टूल बनाने की प्रक्रिया बताती है।

## टूल की संरचना

दो भाग:

1. **स्कीमा** — एक OpenAI-स्टाइल फ़ंक्शन डेफ़िनिशन
   (`{type: "function", function: {name, description, parameters}}`)
   जो LLM को बताता है कि टूल क्या करता है और कौन से आर्ग्युमेंट लेता है।
2. **एंडपॉइंट** — वह URL जिसे ThunderPhone के सर्वर तब कॉल करते हैं जब
   LLM टूल का उपयोग करने का निर्णय लेता है। रिक्वेस्ट JSON POST होती है, जिसमें
   LLM के चुने हुए आर्ग्युमेंट बॉडी के रूप में होते हैं।

## 1. एक एडिटर चुनें

<CardGroup cols={2}>
  <Card title="डैशबोर्ड" icon="window-maximize">
    **कनेक्शन → APIs** खोलें, API कनेक्शन बनाएं या एडिट करें,
    पैरामीटर एडिटर को **JSON** पर स्विच करें, और वहाँ फ़ॉर्मैट जोड़ें।
  </Card>
  <Card title="इंटीग्रेशंस API" icon="plug">
    `POST /v1/integrations` से स्पेक बनाएं, या इसे
    `PATCH /v1/integrations/{id}` से अपडेट करें।
  </Card>
</CardGroup>

दोनों रास्ते एक सेव किया हुआ इंटीग्रेशन बनाते हैं। सेव करने के बाद उस इंटीग्रेशन को
एजेंट से अटैच करें। Agents API में कोई लिखने योग्य इनलाइन `tools`
फ़ील्ड नहीं है। यह गाइड इंटीग्रेशंस API पाथ का उपयोग करती है।

## 2. इंटीग्रेशन बनाएँ

```bash
curl -X POST https://api.thunderphone.com/v1/integrations \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "display_name": "Weather API",
    "spec": {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Return the current weather for a zip code.",
        "parameters": {
          "type": "object",
          "properties": {
            "zip": { "type": "string", "description": "5-digit US ZIP code" }
          },
          "required": ["zip"]
        }
      }
    },
    "endpoint_url":    "https://api.example.com/weather",
    "endpoint_method": "GET",
    "headers": [
      { "key": "X-Api-Key", "value": "your-provider-key" }
    ]
  }'
```

लौटाया गया `id` (एक UUID) सहेजें। हेडर वैल्यू केवल-लिखने योग्य हैं: रिस्पॉन्स में केवल हेडर नाम सूचीबद्ध होते हैं, और बाद का `PATCH` संग्रहीत वैल्यू बनाए रखने के लिए बिना `value` के हेडर भेज सकता है।

<Tip>
  टूल और हर पैरामीटर के `description` पर वास्तविक ध्यान दें। LLM रनटाइम पर
  इन स्ट्रिंग्स का उपयोग यह तय करने के लिए करता है कि टूल को कॉल करना है या नहीं
  और कैसे करना है। अस्पष्ट विवरण → अस्पष्ट टूल कॉल।
</Tip>

### एड्रेस पैरामीटर पर `format: "email"` घोषित करें

ईमेल एड्रेस प्राप्त करने वाले पैरामीटर को अपने स्कीमा में यह बताना चाहिए:

```json
"email": { "type": "string", "format": "email", "description": "The caller's email address" }
```

`format` केवल एक हिंट से अधिक है। रिज़ॉल्व किए गए ईमेल स्कीमा के लिए, आपके
एंडपॉइंट को कॉल करने से पहले ThunderPhone वैल्यू को ट्रिम करता है, डोमेन को
लोअरकेस करता है, स्वतंत्र अंग्रेज़ी शब्दों `at`, `dot`, `underscore`,
`dash`, और `hyphen` को उनके कैरेक्टर में बदलता है, और `@`, `.`, `_`, तथा
`-` के ठीक आसपास का व्हाइटस्पेस हटा देता है। इन शब्दों का अर्थ एक ही रहता है,
चाहे ट्रांसक्रिप्ट में पहले से लिटरल `@` मौजूद हो या नहीं:
`"john dot smith at gmail dot com"` बदलकर
`john.smith@gmail.com` हो जाता है।

किसी अन्य आंतरिक व्हाइटस्पेस को चुपचाप जोड़ने के बजाय अस्वीकार कर दिया जाता
है। बोले गए सेपरेटर शब्द केवल अंग्रेज़ी के लिए हैं; गैर-अंग्रेज़ी या अपरिचित
स्पेस वाले रूप बंद स्थिति में विफल होते हैं। वैध अंतरराष्ट्रीयकृत डोमेन और
SMTPUTF8 लोकल पार्ट स्वीकार किए जाते हैं। पार्सर नॉर्मलाइज़ेशन के बाद Punycode
इनपुट Punycode ही रहता है और Unicode डोमेन इनपुट Unicode ही रहता है, इसलिए
आपकी API को कॉलर द्वारा दिया गया पारंपरिक प्रतिनिधित्व मिलता है। यदि अंतिम
वैल्यू अमान्य है, तो टूल को **कॉल नहीं किया जाता**। एजेंट को
`invalid_email_argument` मिलता है, जो उसे
कॉलर के साथ स्पेलिंग की पुष्टि करने और लिटरल एड्रेस दोबारा भेजने के लिए कहता है।

छोड़ा गया वैकल्पिक ईमेल अपरिवर्तित रहता है। `null`, एक खाली स्ट्रिंग, या केवल
व्हाइटस्पेस वाली स्ट्रिंग भी तब अपरिवर्तित रहती है जब प्रॉपर्टी वैकल्पिक या
nullable हो; आवश्यक, non-nullable ईमेल के लिए इन्हीं वैल्यू को अस्वीकार कर दिया
जाता है।

`#/$defs/email` और `#/definitions/email` जैसे लोकल स्कीमा रेफरेंस, साथ ही
`anyOf`, `oneOf`, और `allOf`, को साइकिल और डेप्थ सीमाओं के साथ निरीक्षित किया
जाता है। गैर-लोकल या अनरिज़ॉल्वेबल `$ref` एक ज्ञात एनफोर्समेंट सीमा है और उसे
बिना बदलाव के पास किया जाता है, ठीक उसी तरह जैसे उस कॉल को जिसकी टूल स्नैपशॉट
में कोई उपयोगी स्कीमा नहीं है। जब आपको इस गेट को लागू करना हो, तो ईमेल स्कीमा
लोकल रखें।

लागू किए गए ईमेल फॉर्मेट के बिना पैरामीटर को मॉडल द्वारा उत्पादित रूप में ही
पास किया जाता है।

समर्थित फॉर्मेट `date-time`, `time`, `date`, `duration`,
`email`, `hostname`, `ipv4`, `ipv6`, और `uuid` हैं; आज केवल `email` को
नॉर्मलाइज़ और एनफोर्स किया जाता है।

## 3. एंडपॉइंट का सैंडबॉक्स टेस्ट करें

इंटीग्रेशन को किसी एजेंट से लिंक करने से पहले, कनेक्टिविटी की पुष्टि करने के
लिए ThunderPhone के सर्वर से एक साइन किया हुआ रिक्वेस्ट भेजें:

```bash
curl -X POST https://api.thunderphone.com/v1/integrations/test-request \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url":    "https://api.example.com/weather?zip=94110",
    "method": "GET",
    "headers": { "X-Api-Key": "your-provider-key" }
  }'
```

```json Response
{
  "ok": true,
  "status": 200,
  "elapsed_ms": 187,
  "response_headers": { "content-type": "application/json" },
  "response_preview": "{\"temperature_f\": 64, ...}"
}
```

यह टेस्ट ThunderPhone के SSRF गार्ड्स को भी मजबूत करता है — localhost या निजी
IP रेंज के रिक्वेस्ट `400 code=url_not_allowed` लौटाते हैं।

## 4. इंटीग्रेशन को एजेंट से लिंक करें

एजेंट बनाते या अपडेट करते समय `integration_ids` के जरिए अटैच करें:

```bash
curl -X PATCH https://api.thunderphone.com/v1/agents/12 \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "integration_ids": ["f9b5a1a4-..."]
  }'
```

आप एक एजेंट से कई इंटीग्रेशन लिंक कर सकते हैं। एजेंट का प्रॉम्प्ट
उन्हें नाम से रेफर कर सकता है — "कॉलर कंडीशंस के बारे में पूछे तो
`get_weather` का उपयोग करें" — या वह स्कीमा डिस्क्रिप्शन से उन्हें
इम्प्लिसिट रूप से डिस्कवर कर सकता है।

## 5. एंडपॉइंट इम्प्लीमेंट करें

जब एजेंट टूल इनवोक करता है, ThunderPhone आपके
`endpoint_url` पर एक साइन किया हुआ POST भेजता है:

```
POST /weather HTTP/1.1
Host: api.example.com
X-Api-Key: your-provider-key
X-ThunderPhone-Signature-V2: t=<unix seconds>,v1=<HMAC-SHA256 hex>
X-ThunderPhone-Signature: <HMAC-SHA256 hex>
X-ThunderPhone-Call-ID: 987654321
Content-Type: application/json

{"zip": "94110"}
```

आपका सर्वर JSON के साथ रिस्पॉन्ड करता है, जो वापस LLM को दिया जाता है:

```json
{"temperature_f": 64, "condition": "Partly cloudy", "wind_mph": 8}
```

LLM उस रिस्पॉन्स को इनजेस्ट करता है और कॉलर को एक मानवीय सारांश बोलता है।

<Warning>
  सिग्नेचर को आपके वेबहुक एंडपॉइंट वाले उसी `secret` का उपयोग करके रॉ
  रिक्वेस्ट बॉडी पर कंप्यूट किया जाता है। **इसे वेरिफ़ाई करें** — टूल एंडपॉइंट
  इंटरनेट-फेसिंग होते हैं और वेबहुक जैसी ही स्पूफिंग संबंधी चिंताओं के अधीन होते हैं।
  देखें
  [वेबहुक सिग्नेचर वेरिफ़ाई करें](/hi/guides/verify-webhook-signatures)।
</Warning>

## 6. लूप टेस्ट करें

एजेंट के खिलाफ एक [माइक सेशन](/api-reference/mic-sessions) चलाएँ
और वह प्रश्न पूछें जिसे आपका टूल हैंडल करता है ("94110 में मौसम
कैसा है?")। कॉल का ट्रांसक्रिप्ट पूरा राउंड ट्रिप दिखाता है:

```json
{
  "call_id": 987654321,
  "transcripts": [
    { "role": "user",
      "content": "What's the weather in 94110?" },
    { "role": "tool_call",
      "content": "{\"tool_call\": \"get_weather\", \"arguments\": {\"zip\": \"94110\"}}" },
    { "role": "tool_response",
      "content": "{\"tool_name\": \"get_weather\", \"response\": {\"temperature_f\": 64, \"condition\": \"Partly cloudy\"}}" },
    { "role": "agent",
      "content": "It's 64 degrees and partly cloudy." }
  ]
}
```

आप इसे
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript) के जरिए प्राप्त कर सकते हैं;
रॉ इवेंट स्ट्रीम (हर एंट्री की टाइमिंग और ऑडियो ऑफ़सेट के साथ) यहाँ है
[`GET /v1/calls/{call_id}/history`](/api-reference/calls#get-history)।

कॉल-लिस्टिंग और एनालिटिक्स सतहों में, ThunderPhone अब टेस्ट कॉल को वास्तविक ट्रैफ़िक से अलग रिपोर्ट करता है। Browser Talk टेस्ट और सिमुलेशन किसी वास्तविक फ़ोन नंबर का दोबारा उपयोग कर सकते हैं और इनबाउंड जैसे दिख सकते हैं, लेकिन वे प्रोडक्शन कॉल कुल, ग्रेड या इश्यू मेट्रिक्स में शामिल नहीं होते हैं।

## सामान्य समस्याएँ

<AccordionGroup>
  <Accordion title="एजेंट कभी टूल कॉल नहीं करता">
    LLM टूल के डिस्क्रिप्शन के आधार पर निर्णय लेता है। अगर कॉलर का
    प्रश्न डिस्क्रिप्शन से मेल नहीं खाता, तो मॉडल टूल इनवोक नहीं करेगा।
    डिस्क्रिप्शन को अधिक सटीक बनाएँ (सामान्य सिनोनिम और फ्रेज़िंग जोड़ें)
    या एजेंट प्रॉम्प्ट में इसका स्पष्ट उल्लेख करें ("जब कॉलर मौसम के बारे में
    पूछे, तो `get_weather` का उपयोग करें।")।
  </Accordion>

  <Accordion title="टूल बहुत ज़्यादा डेटा लौटाता है">
    6 kB से बड़े रिस्पॉन्स ट्रांसक्रिप्ट प्रीव्यू में ट्रंकेट हो जाते हैं। केवल
    वे फ़ील्ड लौटाएँ जिनकी LLM को आवश्यकता है — अपनी पूरी रो नहीं।
  </Accordion>

  <Accordion title="टाइमआउट">
    टूल एंडपॉइंट में 10 सेकंड का डिफ़ॉल्ट टाइमआउट होता है। अगर आपको अधिक समय चाहिए,
    तो इसे एसिंक्रोनस रूप से हैंडल करें: `{"status": "pending", "request_id": "..."}`
    लौटाएँ और परिणाम को अलग टूल कॉल के जरिए दिखाएँ।
  </Accordion>

  <Accordion title="वर्ज़निंग">
    हर इंटीग्रेशन `PATCH` एक नया रिविज़न बनाता है। किसने क्या बदला, यह देखने के लिए
    [`GET /v1/integrations/{id}/versions`](/api-reference/integrations#version-history)
    जाँचें। अगर आप टूल का स्कीमा तोड़ देते हैं, तो पुराने स्नैपशॉट को वापस PATCH करके
    मैन्युअल रूप से रोल बैक कर सकते हैं।
  </Accordion>
</AccordionGroup>

---

## अगले चरण

<CardGroup cols={2}>
  <Card title="इंटीग्रेशन रेफ़रेंस" icon="plug" href="/api-reference/integrations">
    CRUD, ट्रांसफर, वर्ज़न हिस्ट्री।
  </Card>
  <Card title="फ़ंक्शन टूल्स स्पेक" icon="screwdriver-wrench" href="/hi/tools/overview">
    पूर्ण JSON स्कीमा ग्रामर और साइन किए गए एंडपॉइंट कॉन्ट्रैक्ट।
  </Card>
  <Card title="सिग्नेचर सत्यापित करें" icon="shield-check" href="/hi/guides/verify-webhook-signatures">
    टूल एंडपॉइंट पर वेबहुक-सिग्नेचर पैटर्न लागू करें।
  </Card>
  <Card title="ट्रांसक्रिप्ट + हिस्ट्री API" icon="phone" href="/api-reference/calls">
    टूल कॉल की पूरी राउंड-ट्रिप जाँचें।
  </Card>
</CardGroup>
