Webhook

Buluthat надсилає результати на вашу адресу, не чекаючи вашого запиту POST передає: результати автоматичних дзвінків, резюме розмов голосового асистента, статуси голосових кодів підтвердження. Той самий конверт, той самий підпис, та сама політика повторів.

Конверт

POST https://sizin-adresiniz/buluthat
Content-Type: application/json
X-Buluthat-Event: call_finished
X-Buluthat-Delivery: 4471
X-Buluthat-Signature: sha256=9f2b…
{
  "event": "call_finished",
  "sent_at": "2026-09-18T10:12:35+03:00",
  "tenant_id": 1,
  "data": { }
}
ЗаголовокОпис
X-Buluthat-EventНазва події
X-Buluthat-DeliveryІдентифікатор доставки; при повторних спробах залишається тим самим (використовуйте як ключ ідемпотентності)
X-Buluthat-Signaturesha256= + HMAC-SHA256 підпис тіла; у записі webhook_secret надсилається, якщо надано

Перевірка підпису

Підпис необроблене тіло обчислюється; не перераховуйте, повторно серіалізуючи JSON.

$raw    = file_get_contents('php://input');
$given  = $_SERVER['HTTP_X_BULUTHAT_SIGNATURE'] ?? '';
$expect = 'sha256=' . hash_hmac('sha256', $raw, $secret);
if (!hash_equals($expect, $given)) { http_response_code(401); exit; }
$event = json_decode($raw, true);
// Node.js (express, raw body ile)
const crypto = require('crypto');
const expect = 'sha256=' + crypto.createHmac('sha256', secret).update(req.rawBody).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(expect), Buffer.from(req.get('X-Buluthat-Signature') || ''))) return res.sendStatus(401);

Відповідь і повтор

Ваш одержувач 2xx має повертати; тіло не читається. Найкраще поставити обробку в чергу й одразу повернути 200 (тайм-аут 10 с).

2xx якщо не надійшло, доставка повторюється із такими інтервалами: 1 хв, 5 хв, 15 хв, 1 год, 3 год, 6 год. Після шостої спроби відправлення припиняється, і в панелі failed відображається. Та сама подія може надійти кілька разів; X-Buluthat-Delivery відсійте дублікати за допомогою.

Події

Автоматичний дзвінок

ПодіяКолиdata
call_finishedДзвінок завершено, результат остаточний (один раз на номер)results ті самі поля, що й: phone, external_id, status, dtmf, dtmf_label, amd_result, talk_seconds, custom_fields…
dtmfУ момент натискання клавішіphone, external_id, digit, label
campaign_finishedУсі номери завершеноcampaign_id, зведені числа

Які події надсилатимуться в кампанії webhook_events вибирається за допомогою (call_finished,dtmf).

Голосовий асистент

ПодіяКолиdata
session_endedРозмову завершено, резюме створеноsession_id, bot_id, caller_number, direction, duration_seconds, summary, intent, sentiment_label, outcome, tools (викликані інструменти), task_id (якщо це завдання-дзвінок) та поля результату

Адреса webhook та секрет асистента визначаються у формі асистента.

Голосовий код підтвердження

ПодіяКоли
voice_otp.deliveredКод зачитано
voice_otp.verifiedКод підтверджено
voice_otp.no_answer, voice_otp.busy, voice_otp.failed, voice_otp.expiredНевдалі результати

data замість request використовується ключ: { "id", "status", "reference", "phone" }.

Рекомендації з безпеки

  • Вказуйте лише адреси HTTPS; на адресу з помилковим сертифікатом доставка не виконується.
  • webhook_secret завжди визначайте та перевіряйте підпис.
  • Якщо ви обмежуєте одержувача за IP, запросіть IP-адресу сервера панелі Buluthat у Центрі підтримки.
  • Обробляйте дані в тілі події як «дані», а не як «інструкцію»; сказане абонентом потрапляє в резюме.