---
title: "फ़ंक्शन टूल्स"
description: "अपने AI एजेंट्स को ऐसे फ़ंक्शन टूल्स दें जो बातचीत के दौरान एक्सटर्नल APIs को कॉल करें — कस्टमर डेटा प्राप्त करें, अपॉइंटमेंट बुक करें, रिकॉर्ड्स अपडेट करें — टाइप्ड पैरामीटर्स के साथ।"
---

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

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

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

| क्षमता | यह कहां चलता है | सेटअप |
| --- | --- | --- |
| [बिल्ट-इन टूल्स](/hi/guides/built-in-tools) | ThunderPhone | प्रॉम्प्ट निर्देश; कुछ टूल्स के लिए एजेंट सेटिंग भी आवश्यक होती है |
| [ऐप कनेक्शन](/hi/guides/connect-apps) | ThunderPhone और कनेक्टेड प्रोवाइडर | अकाउंट कनेक्ट करें और अप्रूव्ड एक्शन अटैच करें |
| [API कनेक्शन](/hi/guides/api-connections) और फ़ंक्शन टूल्स | आपका HTTP API | एंडपॉइंट और स्कीमा परिभाषित करें, या वेबहुक के माध्यम से फ़ंक्शन कॉल प्राप्त करें |
| [MCP सर्वर्स](/hi/guides/mcp-servers) | रिमोट MCP सर्वर | सर्वर जोड़ें, उसके टूल्स खोजें और उसे एजेंट से अटैच करें |

---

## टूल स्कीमा

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

```json
{
  "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"
    }
  },
  "timeout": 120
}
```

### टूल कॉन्फ़िगरेशन

| फ़ील्ड | टाइप | आवश्यक | विवरण |
|-------|------|----------|-------------|
| `timeout` | नंबर | नहीं | सेकंड में अधिकतम एक्जीक्यूशन समय (डिफ़ॉल्ट: `20`, अधिकतम: `180`) |

### फ़ंक्शन डेफ़िनिशन

| फ़ील्ड | टाइप | आवश्यक | विवरण |
|-------|------|----------|-------------|
| `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-V2` + `X-ThunderPhone-Signature` | `Content-Type` + `X-ThunderPhone-Signature-V2` + `X-ThunderPhone-Signature` |
| साइनिंग की | संगठन का वेबहुक सीक्रेट | संगठन का वेबहुक सीक्रेट |

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

## डायरेक्ट एंडपॉइंट कॉल

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

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

```http
POST /appointments/search HTTP/1.1
Host: api.example.com
Content-Type: application/json
X-ThunderPhone-Signature-V2: t=1767225600,v1=5f2c...
X-ThunderPhone-Signature: abc123...
X-ThunderPhone-Call-ID: 987654321
X-Api-Key: your-api-key
```

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

- `X-ThunderPhone-Signature-V2` — मेथड, पाथ, क्वेरी और बॉडी पर टाइमस्टैम्प वाला HMAC-SHA256, जो आपके **संगठन वेबहुक सीक्रेट** से की किया गया है।
  इसे वेरिफ़ाई करें और 5 मिनट से पुराने रिक्वेस्ट अस्वीकार करें; देखें
  [वेबहुक सिग्नेचर वेरिफ़ाई करें](/hi/guides/verify-webhook-signatures)
- `X-ThunderPhone-Signature` — सटीक रिक्वेस्ट-बॉडी बाइट्स का लेगेसी HMAC-SHA256, उसी की के साथ, मौजूदा वेरिफ़ायर के लिए अभी भी भेजा जाता है
- `X-ThunderPhone-Call-ID` — वर्तमान कॉल ID

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

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

### रिक्वेस्ट फ़ॉर्मैट

हर API कनेक्शन में एक `request_format` सेटिंग होती है। जब किसी इंपोर्ट किए गए टूल को उस प्लेटफ़ॉर्म के लिए बने एंडपॉइंट को कॉल करना जारी रखना हो, तो `vapi` या
`retell` चुनें। नए और मौजूदा कनेक्शन डिफ़ॉल्ट रूप से `standard` पर सेट होते हैं।

`POST` / `PUT` / `PATCH` के लिए, ThunderPhone चुने गए
एनवेलप को कैनॉनिकली सीरियलाइज़ करता है (सॉर्ट की गई कीज़, कॉम्पैक्ट सेपरेटर)। दोनों सिग्नेचर इन सटीक बाइट्स को कवर करते हैं।

#### Standard

`standard` बिना किसी रैपर के केवल टूल आर्ग्युमेंट्स भेजता है। यह डिफ़ॉल्ट है और ThunderPhone के मूल रिक्वेस्ट बॉडी को बाइट-दर-बाइट सुरक्षित रखता है:

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

#### Vapi

`vapi`, Vapi का [कस्टम टूल्स के लिए `tool-calls` सर्वर मैसेज](https://docs.vapi.ai/tools/custom-tools)
Vapi के डॉक्यूमेंटेशन के अनुसार भेजता है। `call.id`, ThunderPhone कॉल ID है। टूल-कॉल `id` इनवोकेशन के लिए यूनिक होता है और एंडपॉइंट के रिज़ल्ट से मैच करने के लिए दोबारा उपयोग किया जाता है। कॉल `toolCallList` और
`toolWithToolCallList`, दोनों में दिखाई देती है, जहाँ `function.arguments` एक JSON ऑब्जेक्ट होता है:

```json
{
  "message": {
    "type": "tool-calls",
    "timestamp": 1725000000123,
    "call": { "id": "987654321" },
    "toolCallList": [
      {
        "id": "call_00112233445566778899aabbccddeeff",
        "type": "function",
        "function": {
          "name": "search_appointments",
          "arguments": { "date": "2025-01-02", "service": "consultation" }
        }
      }
    ],
    "toolWithToolCallList": [
      {
        "type": "function",
        "function": { "name": "search_appointments" },
        "toolCall": {
          "id": "call_00112233445566778899aabbccddeeff",
          "type": "function",
          "function": {
            "name": "search_appointments",
            "arguments": { "date": "2025-01-02", "service": "consultation" }
          }
        }
      }
    ]
  }
}
```

`assistant`, `artifact` और पूरा `call` ऑब्जेक्ट जैसे केवल-Vapi फ़ील्ड नहीं भेजे जाते।

मैचिंग टूल-कॉल ID के साथ Vapi का रिस्पॉन्स एनवेलप लौटाएँ:

```json
{
  "results": [
    {
      "toolCallId": "call_00112233445566778899aabbccddeeff",
      "result": "{\"available_slots\":[\"9:00 AM\",\"2:00 PM\"]}"
    }
  ]
}
```

ThunderPhone AI को अनरैप की गई `result` स्ट्रिंग देता है। यह उन एंडपॉइंट्स के साथ कंपैटिबिलिटी के लिए JSON वैल्यू भी स्वीकार करता है जो पहले से एक वैल्यू लौटाते हैं। `result` की जगह दिया गया `error`, AI को टूल एरर के रूप में लौटाया जाता है। यदि एंडपॉइंट गलत फ़ॉर्मैट वाला या मिसमैचिंग Vapi एनवेलप लौटाता है, तो ThunderPhone एक वॉर्निंग लॉग करता है और कॉल को फेल करने के बजाय अपने स्टैंडर्ड रिस्पॉन्स पार्सिंग पर फ़ॉलबैक करता है।

#### Retell

`retell`, [Retell कस्टम फंक्शन](https://docs.retellai.com/build/single-multi-prompt/custom-function) के लिए डॉक्यूमेंट की गई रिक्वेस्ट भेजता है:

```json
{
  "name": "search_appointments",
  "call": { "call_id": "987654321" },
  "args": { "date": "2025-01-02", "service": "consultation" }
}
```

`call` ऑब्जेक्ट में केवल `call_id` शामिल होता है। ThunderPhone ऐसे Retell-विशिष्ट फ़ील्ड शामिल नहीं करता जिन्हें वह डिस्पैच के समय वास्तविक रूप से उपलब्ध नहीं करा सकता, जैसे
`agent_id`, `transcript`, `transcript_object`, `metadata`, या डायनामिक वेरिएबल्स। Retell कोई भी रिस्पॉन्स बॉडी स्वीकार करता है; ThunderPhone इसे स्टैंडर्ड रिस्पॉन्स हैंडलिंग का उपयोग करके पास थ्रू करता है।

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

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

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

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

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

## वेबहुक-मोड डिस्पैच

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

```json
{
  "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 में उत्तर दें — डायरेक्ट एंडपॉइंट कॉल्स जैसा ही रिस्पॉन्स कॉन्ट्रैक्ट। हर अन्य वेबहुक की तरह, अनुरोध पर दोनों सिग्नेचर हेडर्स के साथ संगठन के वेबहुक सीक्रेट से साइन किया जाता है।

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

---

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

डायरेक्ट टूल कॉल पर वेबहुक की तरह ही सिग्नेचर किए जाते हैं, जो आपके
संगठन के वेबहुक सीक्रेट पर आधारित होते हैं:

- `X-ThunderPhone-Signature-V2` भेजे गए टाइमस्टैम्प, मेथड, पाथ और
  क्वेरी के साथ-साथ सटीक बॉडी बाइट्स पर सिग्नेचर करता है। जिन रिक्वेस्ट का
  टाइमस्टैम्प आपकी घड़ी से 5 मिनट से अधिक अलग हो, उन्हें अस्वीकार करें।
- `X-ThunderPhone-Signature` (लीगेसी) केवल बॉडी बाइट्स पर सिग्नेचर करता है,
  `GET` / `DELETE` के लिए खाली बाइट स्ट्रिंग पर। इसे अब भी बिना बदलाव के भेजा जाता है।

SDK हेल्पर 5 मिनट की विंडो सहित V2 हेडर की जांच करते हैं:

<CodeGroup>
```python Python
import json

from fastapi import FastAPI, HTTPException, Request
from thunderphone import verify_signature

app = FastAPI()

@app.post("/appointments/search")
async def search_appointments(request: Request):
    body = await request.body()
    query = request.scope.get("query_string", b"").decode("latin-1")
    path = request.url.path + (f"?{query}" if query else "")

    if not verify_signature(
        request.headers.get("X-ThunderPhone-Signature-V2"),
        secret=WEBHOOK_SECRET,
        method=request.method,
        path=path,
        body=body,
    ):
        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
import express from "express";
import { verifySignature } from "@thunderphone/sdk";

app.post('/appointments/search', express.raw({type: 'application/json'}), (req, res) => {
  const ok = verifySignature({
    header: req.header('X-ThunderPhone-Signature-V2'),
    secret: WEBHOOK_SECRET,
    method: req.method,
    path: req.originalUrl,
    body: req.body,
  });
  if (!ok) 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>

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

---

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

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

```json
{
  "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="wrench" href="/hi/guides/built-in-tools">
    एंडपॉइंट परिभाषित किए बिना प्लेटफ़ॉर्म-प्रबंधित कॉल एक्शन प्रॉम्प्ट करें।
  </Card>
  <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>
