Webhooks

Buluthat envoie les résultats à votre adresse sans attendre que vous les demandiez POST transmet : résultats des appels automatiques, résumés de conversations de l'assistant vocal, états des codes de vérification vocaux. Même enveloppe, même signature, même politique de nouvelle tentative.

Enveloppe

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": { }
}
En-têteDescription
X-Buluthat-EventNom de l'événement
X-Buluthat-DeliveryIdentifiant de livraison ; reste identique lors des nouvelles tentatives (utilisez-le comme clé d'idempotence)
X-Buluthat-Signaturesha256= + signature HMAC-SHA256 du corps ; à l'enregistrement webhook_secret s'il est fourni, il est envoyé

Vérification de la signature

Signature corps brut est calculée à partir de ; ne la recalculez pas en resérialisant le JSON.

$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);

Réponse et répétition

Votre destinataire 2xx doit renvoyer ; le corps n'est pas lu. Le plus sain est de mettre le traitement en file et de répondre aussitôt 200 est le plus sain (10 s de délai d'expiration).

2xx si elle n'arrive pas, la livraison est retentée aux intervalles suivants : 1 min, 5 min, 15 min, 1 h, 3 h, 6 h. Abandonné après la sixième tentative, et dans le panneau failed apparaît comme. Le même événement peut arriver plusieurs fois ; X-Buluthat-Delivery éliminez les doublons avec.

Événements

Appels automatiques

ÉvénementQuanddata
call_finishedAppel terminé, résultat définitif (une seule fois par numéro)results mêmes champs que : phone, external_id, status, dtmf, dtmf_label, amd_result, talk_seconds, custom_fields…
dtmfAu moment de l'appui sur la touchephone, external_id, digit, label
campaign_finishedTous les numéros sont traitéscampaign_id, chiffres récapitulatifs

Quels événements sont envoyés dans la campagne webhook_events se choisit avec (call_finished,dtmf).

Assistant vocal

ÉvénementQuanddata
session_endedConversation terminée, résumé générésession_id, bot_id, caller_number, direction, duration_seconds, summary, intent, sentiment_label, outcome, tools (outils appelés), task_id (s'il s'agit d'un appel de mission) et champs de résultat

L'adresse webhook et le secret de l'assistant se définissent dans le formulaire de l'assistant.

Code de vérification vocal

ÉvénementQuand
voice_otp.deliveredCode lu
voice_otp.verifiedCode vérifié
voice_otp.no_answer, voice_otp.busy, voice_otp.failed, voice_otp.expiredRésultats en échec

data à la place de request la clé est utilisée : { "id", "status", "reference", "phone" }.

Recommandations de sécurité

  • Indiquez uniquement une adresse HTTPS ; aucune livraison n'est faite vers une adresse dont le certificat est invalide.
  • webhook_secret définissez-le toujours et vérifiez la signature.
  • Si vous souhaitez restreindre le destinataire par IP, demandez l'IP du serveur du panneau Buluthat au Centre d'assistance.
  • Traitez les données du corps de l'événement comme des « données » et non des « instructions » ; le texte prononcé par l'appelant figure dans les résumés.