Outbound webhooks and signatures
A webhook sends your system a POST request every time something happens — no need to poll the API every minute. Available on Business and above.
Setup
- API → Webhooks → New subscription: an HTTPS URL, the events you care about, and a secret (
whsec_…, generated automatically; it can be rotated). - Click "Test" — a
pingevent is sent. Your server must answer 2xx within 8 seconds. Heavy work — after you returned 200.
Events
| Event | When |
|---|---|
lead.created | A new lead was saved (from WhatsApp, the phone or the API). |
message.received | An incoming WhatsApp message from a customer. |
appointment.booked · appointment.canceled | An appointment was booked (voice, WhatsApp, booking page or API) / canceled. |
call.ended | A call ended and was analysed — summary, duration, outcome and recording link. |
contact.optout | A customer opted out — update your own system too. |
payment.reported | A customer reported a payment. |
The request body: JSON with id, event, created_at and data. Headers: X-WABOT-Event, X-WABOT-Delivery (a unique id — use it to drop duplicates), X-WABOT-Timestamp and X-WABOT-Signature.
Verifying the signature
X-WABOT-Signature: sha256=<hex> — HMAC-SHA256 of the raw request body with your secret. Check it before you trust the content:
<?php
$secret = 'whsec_...'; // from the API page
$raw = file_get_contents('php://input');
$given = (string)($_SERVER['HTTP_X_WABOT_SIGNATURE'] ?? '');
$calc = 'sha256=' . hash_hmac('sha256', $raw, $secret);
if (!hash_equals($calc, $given)) { http_response_code(401); exit; }
http_response_code(200); // answer first, work later
$evt = json_decode($raw, true);
// $evt['event'], $evt['data'], $evt['id']
Retries
A non-2xx response or a timeout ⇒ up to 5 retries: after 1 minute, 5 minutes, 30 minutes, 2 hours and 12 hours. After 20 consecutive failed deliveries the subscription is disabled and you get a notification; re-enable it with one click once fixed. The log on the page (and GET events) shows every delivery with its response code, and a failed delivery can be re-sent.