---
title: "একটি টুল ইন্টিগ্রেশন (API) তৈরি করুন"
description: "কথোপকথনের মাঝখানে আপনার এজেন্টকে আপনার API কল করতে দিন — ডেটাবেসে অনুসন্ধান, টিকিট তৈরি, অর্ডার খোঁজা।"
---

একটি **টুল ইন্টিগ্রেশন** হলো একটি পুনঃব্যবহারযোগ্য HTTP এন্ডপয়েন্ট, যা একটি এজেন্ট কলের সময় আহ্বান করতে পারে। আপনি ThunderPhone-কে টুলের একটি JSON-schema বিবরণ এবং একটি এন্ডপয়েন্ট URL দেন; কথোপকথনের ভিত্তিতে এজেন্ট কখন এটি কল করবে তা নির্ধারণ করে, এবং ThunderPhone তার সার্ভার থেকে বহির্গামী HTTP অনুরোধ করে ও প্রতিক্রিয়াটি এজেন্টকে ফেরত দেয়।

<Note>
  এই API ছাড়াই ড্যাশবোর্ড অধিকাংশ টুলের চাহিদা পূরণ করে: **Connections
  → Apps** কয়েকটি OAuth ক্লিকেই Slack, HubSpot, Salesforce, Google Calendar,
  Google Sheets এবং Cal.com সংযুক্ত করে; **Connections →
  APIs** যেকোনো HTTP API-কে এজেন্ট অ্যাকশনে রূপান্তর করে (একটি cURL কমান্ড
  পেস্ট করুন, এবং একটি AI উইজার্ড টুলের খসড়া তৈরি করবে, সঙ্গে অন্তর্নির্মিত Test Request); এবং
  **Connections → MCP** MCP সার্ভার যোগ করে। দেখুন
  [Connections](/bn/guides/concepts)। এই গাইডটি APIs ইন্টারফেসের নিচের
  মূল API নিয়ে।
</Note>

এই গাইডে শুরু থেকে শেষ পর্যন্ত একটি আবহাওয়া-অনুসন্ধান টুল তৈরি করা দেখানো হয়েছে।

## একটি টুলের গঠন

দুটি অংশ:

1. **স্কিমা** — একটি OpenAI-ধাঁচের ফাংশন সংজ্ঞা
   (`{type: "function", function: {name, description, parameters}}`),
   যা LLM-কে জানায় টুলটি কী করে এবং এটি কী আর্গুমেন্ট গ্রহণ করে।
2. **এন্ডপয়েন্ট** — LLM টুলটি ব্যবহার করার সিদ্ধান্ত নিলে ThunderPhone-এর সার্ভার যে
   URL-এ কল করে। অনুরোধটি হলো JSON POST, যেখানে
   LLM-এর নির্বাচিত আর্গুমেন্টগুলো বডি হিসেবে থাকে।

## 1. একটি এডিটর বেছে নিন

<CardGroup cols={2}>
  <Card title="ড্যাশবোর্ড" icon="window-maximize">
    **Connections → 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) সংরক্ষণ করুন।

<Tip>
  টুলের `description` এবং প্রতিটি প্যারামিটারের বর্ণনা তৈরিতে যথেষ্ট মনোযোগ দিন। রানটাইমে টুলটি কল করা হবে কি না এবং কীভাবে করা হবে, তা নির্ধারণে LLM এই স্ট্রিংগুলো ব্যবহার করে। অস্পষ্ট বর্ণনা → অস্পষ্ট টুল কল।
</Tip>

### ঠিকানা প্যারামিটারে `format: "email"` ঘোষণা করুন

যে প্যারামিটার একটি ইমেল ঠিকানা গ্রহণ করে, তার স্কিমায় তা উল্লেখ করা উচিত:

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

`format` শুধু একটি ইঙ্গিতের চেয়েও বেশি কিছু। সমাধানকৃত ইমেল স্কিমার ক্ষেত্রে, আপনার endpoint কল হওয়ার আগে ThunderPhone মানটি trim করে, ডোমেইনকে ছোট হাতের অক্ষরে রূপান্তর করে, স্বতন্ত্র ইংরেজি শব্দ `at`, `dot`, `underscore`, `dash`, এবং `hyphen`-কে তাদের সংশ্লিষ্ট অক্ষরে রূপান্তর করে এবং `@`, `.`, `_`, ও `-`-এর ঠিক আশপাশের whitespace সরিয়ে দেয়। ট্রান্সক্রিপ্টে ইতিমধ্যেই আক্ষরিক `@` থাকুক বা না থাকুক, শব্দগুলোর অর্থ একই থাকে:
`"john dot smith at gmail dot com"` হয়ে যায়
`john.smith@gmail.com`।

অভ্যন্তরীণ অন্য যেকোনো whitespace নীরবে জোড়া দেওয়ার পরিবর্তে প্রত্যাখ্যান করা হয়। কথ্য বিভাজক শব্দগুলো শুধু ইংরেজির জন্য প্রযোজ্য; অ-ইংরেজি বা অচেনা ফাঁকা-স্থানযুক্ত ফর্ম বন্ধ অবস্থায় ব্যর্থ হয়। বৈধ আন্তর্জাতিকীকৃত ডোমেইন এবং SMTPUTF8 local part গ্রহণ করা হয়। Punycode ইনপুট Punycode-ই থাকে এবং Unicode ডোমেইন ইনপুট parser normalization-এর পরেও Unicode-ই থাকে, তাই আপনার API কলারের দেওয়া প্রচলিত উপস্থাপনাটি পায়। চূড়ান্ত মানটি অবৈধ হলে, টুলটি **কল করা হয় না**। এজেন্ট `invalid_email_argument` পায়, যা তাকে কলারের সঙ্গে বানান নিশ্চিত করতে এবং আক্ষরিক ঠিকানাটি পুনরায় পাঠাতে বলে।

বাদ দেওয়া ঐচ্ছিক ইমেল অপরিবর্তিত থাকে। `null`, খালি স্ট্রিং, বা শুধু whitespace-যুক্ত স্ট্রিংও অপরিবর্তিত থাকে যখন প্রপার্টিটি ঐচ্ছিক বা nullable হয়; একই মানগুলো প্রয়োজনীয়, non-nullable ইমেলের ক্ষেত্রে প্রত্যাখ্যান করা হয়।

`#/$defs/email` এবং `#/definitions/email`-এর মতো স্থানীয় schema reference, পাশাপাশি `anyOf`, `oneOf`, এবং `allOf`, cycle ও depth limit সহ পরিদর্শন করা হয়। non-local বা সমাধান-অযোগ্য `$ref` একটি পরিচিত enforcement সীমাবদ্ধতা এবং অপরিবর্তিত অবস্থায় পাঠানো হয়; একইভাবে, যে কলের tool snapshot-এ ব্যবহারযোগ্য schema নেই সেটিও অপরিবর্তিত অবস্থায় পাঠানো হয়। gate প্রয়োগ করতে হলে ইমেল schema স্থানীয় রাখুন।

প্রয়োগকৃত ইমেল format ছাড়া প্যারামিটারগুলো মডেল যেভাবে তৈরি করেছে ঠিক সেভাবেই পাঠানো হয়।

সমর্থিত format হলো `date-time`, `time`, `date`, `duration`, `email`, `hostname`, `ipv4`, `ipv6`, এবং `uuid`; বর্তমানে শুধু `email` স্বাভাবিকীকরণ ও প্রয়োগ করা হয়।

## 3. endpoint স্যান্ডবক্সে পরীক্ষা করুন

ইন্টিগ্রেশনটি কোনো এজেন্টের সঙ্গে লিঙ্ক করার আগে, সংযোগ নিশ্চিত করতে ThunderPhone-এর সার্ভার থেকে একটি signed request পাঠান:

```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 guard-ও শক্তিশালী করে — localhost বা private IP range-এ অনুরোধ করলে `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-..."]
  }'
```

আপনি একটি এজেন্টের সঙ্গে একাধিক ইন্টিগ্রেশন লিঙ্ক করতে পারেন। এজেন্টের prompt নাম ধরে সেগুলোর উল্লেখ করতে পারে — কলার পরিস্থিতি সম্পর্কে জিজ্ঞাসা করলে "`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: <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>
  আপনার webhook এন্ডপয়েন্টের মতো একই `secret` ব্যবহার করে কাঁচা রিকোয়েস্ট বডির ওপর স্বাক্ষর গণনা করা হয়। **এটি যাচাই করুন** — টুল এন্ডপয়েন্টগুলো ইন্টারনেটমুখী এবং webhook-এর মতো একই স্পুফিং-সংক্রান্ত ঝুঁকির মুখোমুখি। দেখুন
  [webhook স্বাক্ষর যাচাই করুন](/bn/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)-এ।

## সাধারণ সমস্যা

<AccordionGroup>
  <Accordion title="এজেন্ট কখনও টুলটি কল করে না">
    LLM টুলের বিবরণের ভিত্তিতে সিদ্ধান্ত নেয়। কলারের প্রশ্ন বিবরণের সঙ্গে না মিললে, মডেল টুলটি আহ্বান করবে না। বিবরণটি আরও নির্দিষ্ট করুন (প্রচলিত সমার্থক শব্দ ও বাক্যরীতি যোগ করুন) অথবা এজেন্টের prompt-এ স্পষ্টভাবে উল্লেখ করুন ("কলার আবহাওয়া সম্পর্কে জিজ্ঞাসা করলে, `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="Function Tools স্পেসিফিকেশন" icon="screwdriver-wrench" href="/bn/tools/overview">
    সম্পূর্ণ JSON schema ব্যাকরণ এবং স্বাক্ষরিত এন্ডপয়েন্ট চুক্তি।
  </Card>
  <Card title="স্বাক্ষর যাচাই করুন" icon="shield-check" href="/bn/guides/verify-webhook-signatures">
    টুল এন্ডপয়েন্টে webhook-স্বাক্ষর প্যাটার্ন প্রয়োগ করুন।
  </Card>
  <Card title="ট্রান্সক্রিপ্ট + ইতিহাস API" icon="phone" href="/api-reference/calls">
    একটি টুল কলের সম্পূর্ণ রাউন্ড-ট্রিপ পরিদর্শন করুন।
  </Card>
</CardGroup>
