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

Модель «Мы звоним вам и зачитываем код»: вы передаёте номер, АТС звонит и зачитывает ответившему код подтверждения по цифрам (по нажатию 1 — повтор), затем завершает вызов. Код можете отправить вы сами либо Buluthat сгенерирует его и один раз вернёт в ответе. В базе данных код хранится только в виде хеш хранится как; 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: видно, состоялся ли звонок и зачитан ли код.
  • Для пожилых или слабовидящих пользователей слушать код проще, чем читать текст.
  • Тарификация только за состоявшиеся звонки, по правилам вашего пакета.