Sesli Doğrulama (OTP)
"Sizi arıyoruz, kodu okuyoruz" modeli: numarayı verirsiniz, santral arar, açan kişiye doğrulama kodunu rakam rakam okur (1'e basınca tekrar), kapatır. Kodu siz gönderebilir ya da Buluthat üretip cevapta bir kez döndürebilir. Kod veritabanında yalnızca hash olarak saklanır; status cevabında görünmez.
Uç: https://api.buluthat.com/api/voice_otp.php — Entegrasyon anahtarı (bt_…, kapsam voice_otp / autocall / voicebot / *). Hesapta voice_otp modülü açık olmalıdır.
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"
}
| Alan | Zorunlu | Açıklama |
|---|---|---|
phone | evet | Aranacak numara |
code | hayır | Kendi kodunuz; boşsa Buluthat üretir |
length | hayır | Üretilecek kod hanesi (4-8, varsayılan 6) |
reference | hayır | Kendi kaydınız; status/list ile bulmak için |
caller_id, trunk_slug | hayır | Arayan numara ve hat |
repeat | hayır | Kod kaç kez okunsun (1-5, varsayılan 2) |
ttl_minutes | hayır | Kod geçerliliği (en fazla 60, varsayılan 5) |
company_name | hayır | Giriş anonsundaki firma adı; boşsa hesap adı |
webhook_url, webhook_secret | hayır | Durum bildirimi |
Cevap:
{ "ok": true, "code": "482913", "data": { "id": 17, "status": "calling", "expires_at": "2026-09-18 10:17:03" } }
code yalnızca Buluthat ürettiğinde döner; siz gönderdiyseniz null.
Hatalar (422): geçersiz numara, aynı numaraya 10 dakikada 3'ten fazla arama (rate_limited), günlük tavan (daily_limit), süren arama (in_progress), hat yok, seslendirme anahtarı yok, santral aramayı kuramadı (mesajda sebep).
POSTverify
{ "action": "verify", "id": 17, "code": "482913" }
id yerine phone (+ reference) da verilebilir; o numaraya açılan son kayıt kullanılır.
- Doğru:
{ "ok": true, "verified": true } - Yanlış:
422veerror:wrong_code(kalan deneme mesajda),expired,too_many_attempts(5),not_delivered(arama açılmadı),not_found
Kod, arama açıldıysa (answered/delivered) doğrulanabilir — kişi kodu duyduktan sonra telefonu kapatsa da olur.
GETstatus
GET https://api.buluthat.com/api/voice_otp.php?action=status&id=17
Durumlar: pending → calling → answered → delivered → verified; başarısızlar no_answer, busy, failed, expired. final: true ise arama bitti. 2-3 saniyede bir sorgulayın ya da webhook kullanın.
GETlist
GET ?action=list&phone=0555…&reference=CARI-451&limit=20
GETcaller_ids · trunks
Arayan numara ve hat seçenekleri (otomatik arama API'siyle aynı).
Webhook
webhook_url verildiyse durum değişimlerinde (delivered, verified, no_answer, busy, failed, expired) POST gider:
{ "event": "voice_otp.delivered", "request": { "id": 17, "status": "delivered", "reference": "CARI-451", "phone": "05551112233" } }
Başlıklar X-Buluthat-Event, X-Buluthat-Delivery, webhook_secret verildiyse X-Buluthat-Signature: sha256=<hmac>. 2xx dışı cevapta 1 dk, 5 dk, 15 dk, 1 sa, 3 sa, 6 sa sonra tekrar denenir.
PHP istemci
Panelden indirilen 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
Neden SMS yerine?
- İYS izni ve SMS başlığı gerektirmez, sabit hatta da çalışır.
- Teslim edilmeyen SMS sorunu yok: arama açıldı mı, kod okundu mu belli.
- Yaşlı ya da görme engelli kullanıcı için kodu dinlemek yazıyı okumaktan kolaydır.
- Ücretlendirme yalnızca açılan aramalar için, paket kurallarınıza göre.
