音声確認(OTP)
「こちらからお電話してコードを読み上げる」方式:番号を渡すと、交換機が発信し、応答した方に確認コードを1桁ずつ読み上げ(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):無効な番号、同一番号への10分間に3回を超える発信(rate_limited)、1日の上限(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が届かない問題はありません:発信に応答したか、コードが読み上げられたかが分かります。
- 高齢の方や視覚に障害のある方には、コードを聞く方が文字を読むより簡単です。
- 課金は、接続された発信のみが対象で、パッケージのルールに従います。
