Голосове підтвердження (OTP)

Модель «Ми телефонуємо, ми зачитуємо код»: ви передаєте номер, АТС дзвонить і зачитує особі, яка відповіла, код підтвердження цифра за цифрою (повтор — за натисканням 1), після чого завершує дзвінок. Код можете надіслати ви, або Buluthat згенерує його та поверне у відповіді один раз. У базі даних код зберігається лише hash зберігається як; status не відображається у відповіді.

Кінцева точка: https://api.buluthat.com/api/voice_otp.php — Ключ інтеграції (bt_…, область voice_otp / autocall / voicebot / *). В обліковому записі voice_otp має бути відкритий модуль.

POSTsend

{
  "action": "send",
  "phone": "05551112233",
  "code": "482913",
  "length": 6,
  "reference": "CARI-451",
  "caller_id": "02124119610",
  "trunk_slug": "hat-1",
  "repeat": 2,
  "ttl_minutes": 5,
  "company_name": "Byfix",
  "webhook_url": "https://crm.example.com/otp-sonuc.php",
  "webhook_secret": "gizli"
}
ПолеОбов'язковоОпис
phoneтакНомер для набору
codeніВаш власний код; якщо порожньо, Buluthat створює
lengthніКількість цифр коду, що створюється (4-8, за замовчуванням 6)
referenceніВаш власний запис; status/list щоб знайти за допомогою
caller_id, trunk_slugніНомер абонента та лінія
repeatніСкільки разів зачитувати код (1-5, за замовчуванням 2)
ttl_minutesніТермін дії коду (максимум 60, за замовчуванням 5)
company_nameніНазва компанії у вхідному оголошенні; якщо порожньо — назва облікового запису
webhook_url, webhook_secretніСповіщення про статус

Відповідь:

{ "ok": true, "code": "482913", "data": { "id": 17, "status": "calling", "expires_at": "2026-09-18 10:17:03" } }

code повертається лише тоді, коли його створив Buluthat; якщо надіслали ви, null.

Помилки (422): недійсний номер, понад 3 дзвінків на той самий номер за 10 хв (rate_limited), добовий ліміт (daily_limit), активний дзвінок (in_progress), немає лінії, немає ключа озвучення, АТС не змогла встановити дзвінок (причина — у повідомленні).

POSTverify

{ "action": "verify", "id": 17, "code": "482913" }

id замість phone (+ reference) також можна вказати; використовується останній запис, відкритий для цього номера.

  • Правильно: { "ok": true, "verified": true }
  • Неправильно: 422 та error: wrong_code (залишок пробних повідомлень), expired, too_many_attempts (5), not_delivered (дзвінок не відкрито), not_found

Код, якщо дзвінок встановлено (answered/delivered) можна підтвердити — навіть якщо особа поклала слухавку після того, як почула код.

GETstatus

GET https://api.buluthat.com/api/voice_otp.php?action=status&id=17

Статуси: pending → calling → answered → delivered → verified; невдалі no_answer, busy, failed, expired. final: true якщо, дзвінок завершено. Опитуйте раз на 2-3 секунд або використовуйте webhook.

GETlist

GET ?action=list&phone=0555…&reference=CARI-451&limit=20

GETcaller_ids · trunks

Варіанти номера абонента та лінії (як у API автоматичного дзвінка).

Webhook

webhook_url якщо надано, при зміні статусу (delivered, verified, no_answer, busy, failed, expired) надсилається POST:

{ "event": "voice_otp.delivered", "request": { "id": 17, "status": "delivered", "reference": "CARI-451", "phone": "05551112233" } }

Заголовки X-Buluthat-Event, X-Buluthat-Delivery, webhook_secret якщо надано X-Buluthat-Signature: sha256=<hmac>. При відповіді не 2xx повторна спроба через 1 хв, 5 хв, 15 хв, 1 год, 3 год, 6 год.

PHP-клієнт

Завантажено з панелі buluthat-voice-otp-client.php:

require 'buluthat-voice-otp-client.php';
$otp = new BuluthatVoiceOtp('https://api.buluthat.com', 'bt_xxx');

$r = $otp->send('05551112233', ['reference' => 'CARI-451']);   // $r['code'], $r['data']['id']
// ... kullanıcı kodu girer ...
$v = $otp->verify($r['data']['id'], $girilenKod);               // $v['ok'] === true

Чому замість SMS?

  • Не потребує дозволу İYS і SMS-заголовка, працює й на стаціонарний номер.
  • Немає проблеми з недоставленими SMS: видно, чи відповіли на дзвінок і чи зачитано код.
  • Для літніх або слабозорих користувачів слухати код легше, ніж читати текст.
  • Тарифікація лише для дзвінків, на які відповіли, за правилами вашого пакета.