Verificação por Voz (OTP)
Modelo "Ligamos-lhe e lemos o código": indica o número, a central liga e lê o código de verificação dígito a dígito a quem atender (prima 1 para repetir) e desliga. Pode enviar o código ou deixar que a Buluthat o gere e o devolva uma única vez na resposta. O código fica na base de dados apenas hash é guardado como; status não aparece na resposta.
Endpoint: https://api.buluthat.com/api/voice_otp.php — Chave de integração (bt_…, âmbito voice_otp / autocall / voicebot / *). Na conta voice_otp o módulo tem de estar ativo.
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"
}
| Campo | Obrigatório | Descrição |
|---|---|---|
phone | sim | Número a chamar |
code | não | O seu próprio código; se vazio, a Buluthat gera-o |
length | não | Número de dígitos do código a gerar (4-8, por defeito 6) |
reference | não | O seu próprio registo; status/list para encontrar com |
caller_id, trunk_slug | não | Número de origem e linha |
repeat | não | Quantas vezes se lê o código (1-5, por defeito 2) |
ttl_minutes | não | Validade do código (no máximo 60, por defeito 5) |
company_name | não | Nome da empresa no anúncio de abertura; se vazio, o nome da conta |
webhook_url, webhook_secret | não | Notificação de estado |
Resposta:
{ "ok": true, "code": "482913", "data": { "id": 17, "status": "calling", "expires_at": "2026-09-18 10:17:03" } }
code só é devolvido quando a Buluthat o gera; se o enviou você null.
Erros (422): número inválido, mais de 3 chamadas para o mesmo número em 10 minutos (rate_limited), limite diário (daily_limit), chamada em curso (in_progress), sem linha, sem chave de síntese de voz, a central não conseguiu estabelecer a chamada (o motivo consta na mensagem).
POSTverify
{ "action": "verify", "id": 17, "code": "482913" }
id em vez de phone (+ reference) também pode ser indicado; é usado o último registo aberto para esse número.
- Correto:
{ "ok": true, "verified": true } - Errado:
422eerror:wrong_code(restantes mensagens de teste),expired,too_many_attempts(5),not_delivered(a chamada não foi iniciada),not_found
Código, se a chamada foi atendida (answered/delivered) pode ser validado — mesmo que a pessoa desligue depois de ouvir o código.
GETstatus
GET https://api.buluthat.com/api/voice_otp.php?action=status&id=17
Estados: pending → calling → answered → delivered → verified; as falhadas no_answer, busy, failed, expired. final: true se for, a chamada terminou. Consulte a cada 2-3 segundos ou utilize webhook.
GETlist
GET ?action=list&phone=0555…&reference=CARI-451&limit=20
GETcaller_ids · trunks
Opções de número de origem e linha (iguais às da API de chamadas automáticas).
Webhook
webhook_url se for indicado, nas mudanças de estado (delivered, verified, no_answer, busy, failed, expired) é enviado um POST:
{ "event": "voice_otp.delivered", "request": { "id": 17, "status": "delivered", "reference": "CARI-451", "phone": "05551112233" } }
Cabeçalhos X-Buluthat-Event, X-Buluthat-Delivery, webhook_secret se for indicado X-Buluthat-Signature: sha256=<hmac>. Numa resposta fora de 2xx volta a tentar após 1 min, 5 min, 15 min, 1 h, 3 h, 6 h.
Cliente PHP
Descarregado do painel 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
Porquê em vez de SMS?
- Não exige consentimento İYS nem cabeçalho de SMS e funciona também em linha fixa.
- Sem problema de SMS não entregue: sabe-se se a chamada foi atendida e se o código foi lido.
- Para utilizadores idosos ou com deficiência visual, ouvir o código é mais fácil do que lê-lo.
- A tarifação aplica-se apenas às chamadas atendidas, segundo as regras do seu pacote.
