Webhooks
Buluthat stuurt de resultaten naar uw adres zonder dat u erom hoeft te vragen POST verstuurt: resultaten van automatisch bellen, gespreksamenvattingen van de spraakassistent, statussen van spraakverificatiecodes. Dezelfde envelop, dezelfde handtekening, hetzelfde herhaalbeleid.
Envelop
POST https://sizin-adresiniz/buluthat
Content-Type: application/json
X-Buluthat-Event: call_finished
X-Buluthat-Delivery: 4471
X-Buluthat-Signature: sha256=9f2b…
{
"event": "call_finished",
"sent_at": "2026-09-18T10:12:35+03:00",
"tenant_id": 1,
"data": { }
}
| Afzendernaam | Omschrijving |
|---|---|
X-Buluthat-Event | Naam van de gebeurtenis |
X-Buluthat-Delivery | Aflevering-ID; blijft bij nieuwe pogingen gelijk (gebruik als idempotency-sleutel) |
X-Buluthat-Signature | sha256= + HMAC-SHA256-handtekening van de body; bij registratie webhook_secret wordt verzonden indien opgegeven |
Handtekeningverificatie
Handtekening ruwe body wordt berekend uit; serialiseer de JSON niet opnieuw om te berekenen.
$raw = file_get_contents('php://input');
$given = $_SERVER['HTTP_X_BULUTHAT_SIGNATURE'] ?? '';
$expect = 'sha256=' . hash_hmac('sha256', $raw, $secret);
if (!hash_equals($expect, $given)) { http_response_code(401); exit; }
$event = json_decode($raw, true);
// Node.js (express, raw body ile)
const crypto = require('crypto');
const expect = 'sha256=' + crypto.createHmac('sha256', secret).update(req.rawBody).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(expect), Buffer.from(req.get('X-Buluthat-Signature') || ''))) return res.sendStatus(401);
Antwoord en herhaling
Uw beller 2xx moet teruggeven; de body wordt niet gelezen. Het is het best om de verwerking in een wachtrij te zetten en direct 200 is het best (10 sec time-out).
2xx komt de aflevering niet aan, dan wordt met deze tussenpozen opnieuw geprobeerd: 1 min, 5 min, 15 min, 1 u, 3 u, 6 u. Na de zesde poging wordt het opgegeven en in het paneel failed wordt weergegeven als. Dezelfde gebeurtenis kan meerdere keren aankomen; X-Buluthat-Delivery filter duplicaten eruit met.
Gebeurtenissen
Automatisch bellen
| Gebeurtenis | Wanneer | data |
|---|---|---|
call_finished | Gesprek beëindigd, resultaat definitief (eenmaal per nummer) | results dezelfde velden als: phone, external_id, status, dtmf, dtmf_label, amd_result, talk_seconds, custom_fields… |
dtmf | Op het moment van de toetsdruk | phone, external_id, digit, label |
campaign_finished | Alle nummers zijn afgerond | campaign_id, samenvattende aantallen |
Welke gebeurtenissen in de campagne worden verzonden webhook_events wordt gekozen met (call_finished,dtmf).
Spraakassistent
| Gebeurtenis | Wanneer | data |
|---|---|---|
session_ended | Gesprek beëindigd, samenvatting gegenereerd | session_id, bot_id, caller_number, direction, duration_seconds, summary, intent, sentiment_label, outcome, tools (aangeroepen tools), task_id (indien een taakoproep) en resultaatvelden |
Het webhook-adres en het geheim van de assistent worden in het assistentformulier gedefinieerd.
Spraakverificatiecode
| Gebeurtenis | Wanneer |
|---|---|
voice_otp.delivered | Code voorgelezen |
voice_otp.verified | Code geverifieerd |
voice_otp.no_answer, voice_otp.busy, voice_otp.failed, voice_otp.expired | Mislukte resultaten |
data in plaats van request sleutel wordt gebruikt: { "id", "status", "reference", "phone" }.
Beveiligingsadviezen
- Geef alleen HTTPS-adressen op; naar een adres met een certificaatfout wordt niet afgeleverd.
webhook_secretdefinieer altijd en controleer de handtekening.- Wilt u de ontvanger beperken tot een IP, vraag dan via het Helpcentrum het IP van de Buluthat-paneelserver aan.
- Verwerk de gegevens in de gebeurtenisbody als "data", niet als "instructie"; de tekst die de beller zei komt in samenvattingen voor.
