> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thunderphone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# फ़ंक्शन टूल्स

> अपने AI एजेंट्स को बातचीत के दौरान बाहरी APIs कॉल करने दें

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

## यह कैसे काम करता है

1. आप एक स्कीमा के साथ टूल परिभाषित करते हैं (टूल कौन से आर्ग्युमेंट स्वीकार करता है)
2. आप एक `endpoint` कॉन्फ़िगरेशन देते हैं (जहाँ ThunderPhone आपके API को कॉल करता है) — या अपने संगठन वेबहुक पर टूल कॉल प्राप्त करने के लिए इसे छोड़ दें
3. कॉल के दौरान, AI बातचीत के आधार पर तय करता है कि टूल का उपयोग कब करना है
4. ThunderPhone टूल आर्ग्युमेंट्स के साथ आपके एंडपॉइंट को कॉल करता है
5. बातचीत जारी रखने के लिए आपका API रिस्पॉन्स AI को वापस दिया जाता है

<Note>
  फ़ंक्शन टूल अपना-API-लाने वाला विकल्प हैं। ThunderPhone ऐसे प्लेटफ़ॉर्म-मैनेज्ड टूल भी
  प्रदान करता है जिन्हें किसी एंडपॉइंट की आवश्यकता नहीं होती:
  [ऐप कनेक्शन](/hi/guides/connect-apps) (HubSpot, Salesforce, Slack,
  Google Calendar, Google Sheets, Cal.com),
  [API कनेक्शन](/hi/guides/api-connections), और
  [MCP सर्वर](/hi/guides/mcp-servers)।
</Note>

***

## टूल स्कीमा

हर टूल इस संरचना का पालन करता है:

```json theme={null}
{
  "type": "function",
  "function": {
    "name": "search_appointments",
    "description": "Find available appointment slots for a given date",
    "parameters": {
      "type": "object",
      "properties": {
        "date": {
          "type": "string",
          "description": "Date in YYYY-MM-DD format"
        },
        "service": {
          "type": "string",
          "description": "Type of service (e.g., 'consultation', 'follow-up')"
        }
      },
      "required": ["date"]
    }
  },
  "endpoint": {
    "url": "https://api.example.com/appointments/search",
    "method": "POST",
    "headers": {
      "X-Api-Key": "your-api-key"
    }
  }
}
```

### फ़ंक्शन परिभाषा

| फ़ील्ड        | प्रकार   | आवश्यक | विवरण                                        |
| ------------- | -------- | ------ | -------------------------------------------- |
| `name`        | स्ट्रिंग | हाँ    | टूल के लिए यूनिक आइडेंटिफ़ायर                |
| `description` | स्ट्रिंग | हाँ    | AI को बताता है कि इस टूल का उपयोग कब करना है |
| `parameters`  | ऑब्जेक्ट | हाँ    | टूल आर्ग्युमेंट्स के लिए JSON स्कीमा         |

### एंडपॉइंट कॉन्फ़िगरेशन

| फ़ील्ड    | प्रकार   | आवश्यक | विवरण                          |
| --------- | -------- | ------ | ------------------------------ |
| `url`     | स्ट्रिंग | हाँ    | आपके API का एंडपॉइंट URL       |
| `method`  | स्ट्रिंग | नहीं   | HTTP मेथड (डिफ़ॉल्ट: `POST`)   |
| `headers` | ऑब्जेक्ट | नहीं   | शामिल करने के लिए कस्टम हेडर्स |

<Note>
  `endpoint` कॉन्फ़िगरेशन AI मॉडल को **नहीं** भेजा जाता—इसका उपयोग केवल ThunderPhone द्वारा टूल कॉल एक्ज़ीक्यूट करने के लिए किया जाता है।
</Note>

***

## दो इनवोकेशन पाथ

आपके सर्वर को कौन सा रिक्वेस्ट मिलता है, यह इस पर निर्भर करता है कि टूल में
`endpoint` है या नहीं:

|                        | `endpoint` **वाला** टूल                                                         | `endpoint` **के बिना** टूल                                                                   |
| ---------------------- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| रिक्वेस्ट कहाँ जाता है | सीधे `endpoint.url` पर                                                          | आपके संगठन के [लेगेसी वेबहुक URL](/api-reference/organizations#legacy-single-url-webhook) पर |
| बॉडी                   | **केवल टूल आर्ग्युमेंट्स**                                                      | `telephony.tool` / `web.tool` एनवेलप                                                         |
| हेडर्स                 | आपके `endpoint.headers` + `X-ThunderPhone-Call-ID` + `X-ThunderPhone-Signature` | `Content-Type` + `X-ThunderPhone-Signature`                                                  |
| साइनिंग की             | संगठन वेबहुक सीक्रेट                                                            | संगठन वेबहुक सीक्रेट                                                                         |

दोनों पाथ **ब्लॉकिंग** हैं — AI रिज़ल्ट के लिए वाक्य के बीच में प्रतीक्षा कर रहा
होता है — और इनका टाइमआउट **20 s** है। हैंडलर्स को तेज़ रखें। मिश्रण भी ठीक है:
जिस कॉल के संगठन में वेबहुक URL है, उसमें `endpoint` वाले टूल सीधे
कॉल होते हैं और बाकी वेबहुक पर फ़ॉलबैक करते हैं।

## प्रत्यक्ष एंडपॉइंट कॉल

जब AI ऐसे टूल को इनवोक करता है जिसमें `endpoint` होता है, ThunderPhone
आपके URL पर एक रिक्वेस्ट भेजता है:

### रिक्वेस्ट हेडर्स

```http theme={null}
POST /appointments/search HTTP/1.1
Host: api.example.com
Content-Type: application/json
X-ThunderPhone-Signature: abc123...
X-ThunderPhone-Call-ID: 987654321
X-Api-Key: your-api-key
```

आपके `endpoint.headers` के कस्टम हेडर्स हमेशा यथावत शामिल किए जाते हैं,
साथ ही ThunderPhone-नेमस्पेस वाले दो हेडर्स भी शामिल होते हैं:

* `X-ThunderPhone-Signature` — सटीक रिक्वेस्ट-बॉडी बाइट्स का HMAC-SHA256,
  जिसे आपके **org webhook secret** से की किया गया है
* `X-ThunderPhone-Call-ID` — वर्तमान कॉल ID

`Content-Type: application/json` सेट किया जाता है, जब तक कि आपके `endpoint.headers`
इसे ओवरराइड न करें — कस्टम `Content-Type` को प्राथमिकता मिलती है।

<Warning>
  सिग्नेचर को org-स्तरीय webhook secret से की किया जाता है, जो
  [`GET /v1/webhook`](/api-reference/organizations#legacy-single-url-webhook) से मिलता है।
  अगर आपके org ने कभी legacy webhook कॉन्फ़िगर नहीं किया है, तो कोई
  secret नहीं होता और टूल कॉल में **केवल** `X-ThunderPhone-Call-ID` होता है —
  मिसिंग सिग्नेचर पर हार्ड-फेल होने वाला हैंडलर उन्हें अस्वीकार कर देगा।
  secret पाने के लिए legacy webhook कॉन्फ़िगर करें, या अपना shared secret
  `endpoint.headers` में रखें।
</Warning>

### रिक्वेस्ट बॉडी

`POST` / `PUT` / `PATCH` के लिए, बॉडी में **केवल** टूल
आर्ग्युमेंट्स होते हैं (कोई रैपर नहीं), जिन्हें कैनॉनिकली सीरियलाइज़ किया जाता है (सॉर्ट की गई keys, कॉम्पैक्ट
सेपरेटर्स):

```json theme={null}
{"date":"2025-01-02","service":"consultation"}
```

`GET` / `DELETE` के लिए, आर्ग्युमेंट्स **क्वेरी पैरामीटर्स** के रूप में भेजे जाते हैं
और बॉडी खाली होती है — तब सिग्नेचर खाली
बाइट स्ट्रिंग पर कंप्यूट किया जाता है। देखें
[webhook सिग्नेचर सत्यापित करें](/hi/guides/verify-webhook-signatures)।

### रिस्पॉन्स

टूल रिजल्ट के साथ JSON रिस्पॉन्स लौटाएँ:

```json theme={null}
{
  "available_slots": ["9:00 AM", "2:00 PM", "4:30 PM"],
  "timezone": "America/Los_Angeles"
}
```

रिस्पॉन्स को फ़ॉर्मैट करके बातचीत जारी रखने के लिए AI को दिया जाता है।
गैर-JSON रिस्पॉन्स को `{"data": "<text>"}` के रूप में रैप किया जाता है;
टाइमआउट और कनेक्शन फेल्योर AI को एरर्स के रूप में रिपोर्ट किए जाते हैं, ताकि
एजेंट माफ़ी माँगकर आगे बढ़ सके, रुक न जाए।

## Webhook-मोड डिस्पैच

बिना `endpoint` वाले टूल आपके org के legacy
webhook URL पर साइन किए गए `telephony.tool` (फ़ोन कॉल) या `web.tool`
(वेब कॉल) रिक्वेस्ट के रूप में डिस्पैच किए जाते हैं। निष्पादन के बाद webhook एंडपॉइंट्स पर
भेजी जाने वाली [ऑडिट नोटिफ़िकेशंस](/hi/webhooks/events) के विपरीत, यह रिक्वेस्ट **ही**
निष्पादन है — आपका HTTP रिस्पॉन्स ही टूल रिजल्ट होता है।

```json theme={null}
{
  "type": "telephony.tool",
  "data": {
    "call_id": 987654321,
    "tool_name": "search_appointments",
    "arguments": { "date": "2026-04-21" },
    "from_number": "+14155550199",
    "to_number": "+15551234567"
  }
}
```

`web.tool` में `from_number` /
`to_number` के बजाय `origin_domain` होता है। टूल रिजल्ट को JSON के रूप में रिस्पॉन्ड करें — प्रत्यक्ष एंडपॉइंट कॉल जैसा ही
रिस्पॉन्स कॉन्ट्रैक्ट। हर अन्य webhook की तरह, रिक्वेस्ट को raw बॉडी पर org
webhook secret से साइन किया जाता है।

<Note>
  सब्सक्राइब किए गए [webhook endpoints](/hi/webhooks/endpoints) को अतिरिक्त रूप से
  हर टूल के निष्पादित होने के **बाद** एक non-blocking `telephony.tool` / `web.tool` **नोटिफ़िकेशन**
  मिलता है (उसे चलाने वाला कोई भी पथ हो), जिसमें
  टूल का रिस्पॉन्स शामिल होता है — ऑडिट ट्रेल्स के लिए उपयोगी। देखें
  [events catalog](/hi/webhooks/events)।
</Note>

***

## सिग्नेचर वेरिफिकेशन

डायरेक्ट टूल कॉल को वेबहुक की तरह ही साइन किया जाता है:

* सटीक रिक्वेस्ट-बॉडी बाइट्स पर HMAC-SHA256 (कैनोनिकल JSON —
  सॉर्ट की गई keys, बिना अतिरिक्त whitespace के)
* आपके संगठन के वेबहुक सीक्रेट से keyed
* `GET` / `DELETE` टूल खाली byte string पर साइन करते हैं

<CodeGroup>
  ```python Python theme={null}
  import hmac
  import hashlib

  def verify_tool_call(body: bytes, signature: str, secret: str) -> bool:
      expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
      return hmac.compare_digest(expected, signature)

  @app.post("/appointments/search")
  async def search_appointments(request: Request):
      body = await request.body()
      signature = request.headers.get("X-ThunderPhone-Signature", "")

      if not verify_tool_call(body, signature, WEBHOOK_SECRET):
          raise HTTPException(status_code=401)

      data = json.loads(body)
      date = data["date"]

      # Look up availability
      slots = await get_available_slots(date)

      return {"available_slots": slots}
  ```

  ```javascript Node.js theme={null}
  app.post('/appointments/search', express.raw({type: 'application/json'}), (req, res) => {
    const signature = req.headers['x-thunderphone-signature'] || '';
    const expected = crypto
      .createHmac('sha256', WEBHOOK_SECRET)
      .update(req.body)
      .digest('hex');

    if (!signature ||
        signature.length !== expected.length ||
        !crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
      return res.status(401).send('Invalid signature');
    }

    const { date, service } = JSON.parse(req.body);

    // Look up availability
    const slots = getAvailableSlots(date, service);

    res.json({ available_slots: slots });
  });
  ```
</CodeGroup>

खाली-बॉडी केस और बिना-सीक्रेट वाली सावधानी सहित पूरी रेसिपी [वेबहुक सिग्नेचर वेरिफाई करें](/hi/guides/verify-webhook-signatures) में उपलब्ध हैं।

***

## उदाहरण: पूर्ण बुकिंग फ्लो

यह पूर्ण अपॉइंटमेंट बुकिंग सिस्टम के लिए टूल का एक सेट है:

```json theme={null}
{
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "search_appointments",
        "description": "Find available appointment slots",
        "parameters": {
          "type": "object",
          "properties": {
            "date": { "type": "string", "description": "YYYY-MM-DD" },
            "service": { "type": "string" }
          },
          "required": ["date"]
        }
      },
      "endpoint": {
        "url": "https://api.example.com/appointments/search",
        "method": "POST",
        "headers": { "X-Api-Key": "key" }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "book_appointment",
        "description": "Book an appointment at a specific time",
        "parameters": {
          "type": "object",
          "properties": {
            "date": { "type": "string", "description": "YYYY-MM-DD" },
            "time": { "type": "string", "description": "HH:MM format" },
            "customer_name": { "type": "string" },
            "customer_phone": { "type": "string" }
          },
          "required": ["date", "time", "customer_name"]
        }
      },
      "endpoint": {
        "url": "https://api.example.com/appointments/book",
        "method": "POST",
        "headers": { "X-Api-Key": "key" }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "cancel_appointment",
        "description": "Cancel an existing appointment",
        "parameters": {
          "type": "object",
          "properties": {
            "confirmation_number": { "type": "string" }
          },
          "required": ["confirmation_number"]
        }
      },
      "endpoint": {
        "url": "https://api.example.com/appointments/cancel",
        "method": "POST",
        "headers": { "X-Api-Key": "key" }
      }
    }
  ]
}
```

***

## सर्वोत्तम प्रथाएँ

<AccordionGroup>
  <Accordion title="स्पष्ट विवरण लिखें">
    `description` फ़ील्ड AI को यह समझने में मदद करती है कि टूल का उपयोग **कब** करना है। यह क्या करता है और इसका उपयोग कब उचित है, इसके बारे में स्पष्ट रहें।
  </Accordion>

  <Accordion title="त्रुटियों को सहजता से संभालें">
    ऐसे त्रुटि संदेश लौटाएँ जिन्हें AI समझ सके: सामान्य 500 त्रुटियों के बजाय `{"error": "No slots available for that date"}`।
  </Accordion>

  <Accordion title="रिस्पॉन्स संक्षिप्त रखें">
    बातचीत जारी रखने के लिए AI को केवल वही लौटाएँ जिसकी उसे आवश्यकता है। बड़े पेलोड रिस्पॉन्स समय को धीमा करते हैं।
  </Accordion>

  <Accordion title="आवश्यक फ़ील्ड का समझदारी से उपयोग करें">
    फ़ील्ड को `required` केवल तभी चिह्नित करें जब वे वास्तव में आवश्यक हों। टूल कॉल करने से पहले AI उपयोगकर्ता से आवश्यक जानकारी पूछेगा।
  </Accordion>
</AccordionGroup>

***

## संबंधित

<CardGroup cols={2}>
  <Card title="ऐप कनेक्शन" icon="plug" href="/hi/guides/connect-apps">
    HubSpot, Salesforce, Slack, Google
    Calendar, Google Sheets और Cal.com के लिए प्लेटफ़ॉर्म-प्रबंधित टूल — किसी एंडपॉइंट की आवश्यकता नहीं।
  </Card>

  <Card title="MCP सर्वर" icon="server" href="/hi/guides/mcp-servers">
    MCP सर्वर अटैच करें और एजेंट को उसके टूल कॉल करने दें।
  </Card>

  <Card title="API कनेक्शन" icon="code" href="/hi/guides/api-connections">
    पुन: उपयोग योग्य REST इंटीग्रेशन जिन्हें आप एजेंट्स से अटैच कर सकते हैं।
  </Card>

  <Card title="वेबहुक सिग्नेचर सत्यापित करें" icon="shield-check" href="/hi/guides/verify-webhook-signatures">
    वेबहुक और टूल कॉल के लिए एक वेरिफिकेशन हेल्पर।
  </Card>
</CardGroup>
