Webhooks
Receive real-time notifications when events happen in your Boltly account. Webhooks are delivered as HTTP POST requests to your endpoint.
Event types
Subscribe to any combination of these events when creating a webhook endpoint.
message.received A new inbound message from a contact message.sent An outbound message was accepted by WhatsApp message.delivered Message was delivered to the contact's device message.read Contact opened and read the message message.failed Message delivery failed Creating a webhook
Register an endpoint via the dashboard at Settings → Developer Access → Webhooks, or use the API:
curl -X POST https://api.boltly.online/v1/developer-access/webhooks \
-H "X-API-Key: sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/boltly",
"events": ["message.received", "message.delivered"],
"description": "Production webhook"
}'
The response includes a signing_secret starting with whsec_. Store this to verify incoming payloads.
Payload format
Every webhook delivery sends a JSON payload with this structure:
{
"id": "evt_a1b2c3d4-...",
"type": "message.received",
"organization_id": "org_...",
"created_at": "2026-04-03T12:00:00Z",
"data": {
"message_id": "msg_...",
"conversation_id": "conv_...",
"from": "+1234567890",
"type": "text",
"text": { "body": "Hi, I'd like to book an appointment" }
}
} Verifying signatures
Every webhook request includes an X-Webhook-Signature header. Verify it to ensure the request came from Boltly.
Verification steps
- 1. Read the raw request body (do not parse JSON first)
- 2. Compute
HMAC-SHA256(body, signing_secret) - 3. Hex-encode the result
- 4. Compare with the
X-Webhook-Signatureheader (constant-time comparison)
import crypto from "crypto";
function verifyWebhook(body, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(body)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
} Delivery & retries
Webhooks are delivered asynchronously via a queue worker. Your endpoint must respond with a 2xx status within 30 seconds. Failed deliveries are retried automatically.