---
title: "Створення інтеграції інструменту (API)"
description: "Дозвольте своєму агенту викликати ваші API під час розмови — шукати в базі даних, створювати заявку, знаходити замовлення."
---

**Інтеграція інструмента** — це багаторазово використовувана HTTP-кінцева точка, яку агент може викликати під час дзвінка. Ви надаєте ThunderPhone опис інструмента у форматі JSON-схеми разом з URL кінцевої точки; агент вирішує, коли її викликати, на основі розмови, а ThunderPhone надсилає вихідний HTTP-запит зі своїх серверів і повертає відповідь агенту.

<Note>
  Панель керування покриває більшість потреб в інструментах без цього API: **З’єднання
  → Застосунки** підключає Slack, HubSpot, Salesforce, Google Calendar,
  Google Sheets і Cal.com за кілька кліків OAuth; **З’єднання →
  API** перетворює будь-який HTTP API на дію агента (вставте команду cURL,
  і майстер ШІ створить чернетку інструмента з вбудованою функцією «Тестовий запит»); а
  **З’єднання → MCP** додає сервери MCP. Дивіться
  [З’єднання](/uk/guides/concepts). Цей посібник описує базовий
  API, що лежить в основі інтерфейсу 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">
    Відкрийте **З’єднання → API**, створіть або відредагуйте API-з’єднання,
    перемкніть редактор параметрів на **JSON** і додайте там формат.
  </Card>
  <Card title="API інтеграцій" icon="plug">
    Створіть специфікацію за допомогою `POST /v1/integrations` або оновіть її за допомогою
    `PATCH /v1/integrations/{id}`.
  </Card>
</CardGroup>

Обидва способи створюють збережену інтеграцію. Після збереження
прикріпіть цю інтеграцію до агента. 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`, порожній рядок або
рядок, що містить лише пробіли, також не змінюються, коли властивість необов’язкова
або допускає значення null; ті самі значення відхиляються для обов’язкової адреси електронної пошти, що не допускає null.

Локальні посилання на схему, як-от `#/$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 надсилає підписаний POST на
ваш `endpoint_url`:

```
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`, що й ваша кінцева точка вебхука. **Перевіряйте його** — кінцеві точки інструментів
  доступні з інтернету та мають ті самі ризики підміни, що й
  вебхуки. Див.
  [Перевірка підписів вебхуків](/uk/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 кБ скорочуються в попередньому перегляді транскрипту. Повертайте
    лише поля, потрібні 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="/uk/tools/overview">
    Повна граматика схеми JSON і контракт підписаної кінцевої точки.
  </Card>
  <Card title="Перевірка підписів" icon="shield-check" href="/uk/guides/verify-webhook-signatures">
    Застосуйте шаблон підпису вебхука до кінцевих точок інструментів.
  </Card>
  <Card title="API транскрипту й історії" icon="phone" href="/api-reference/calls">
    Перегляньте повний цикл виклику інструменту.
  </Card>
</CardGroup>
