Webhook Events
Reference for all webhook event types, their payloads, and delivery behavior.
Event Types
| Event | Description |
|---|---|
booking.created | A new booking was created |
booking.confirmed | Booking payment confirmed |
booking.cancelled | Booking was cancelled |
booking.completed | Booking has ended |
payment.received | Payment was received |
payment.refunded | Payment was refunded |
door.unlocked | Door was unlocked (scan or manual) |
door.locked | Door was locked |
door.fault | Door reported a fault |
device.online | Device came online |
device.offline | Device went offline (missed heartbeat) |
Payload Format
All webhook payloads follow the same structure:
Example payload: booking.confirmedjson
{
"id": "evt_uuid",
"type": "booking.confirmed",
"created_at": "2026-02-16T12:00:00Z",
"tenant_id": "tenant-uuid",
"data": {
"booking": {
"id": "booking-uuid",
"guestName": "Jan de Vries",
"guestEmail": "jan@example.com",
"objectId": "object-uuid",
"startTime": "2026-02-17T10:00:00Z",
"endTime": "2026-02-17T11:00:00Z",
"status": "CONFIRMED",
"totalPrice": 2500
}
}
}Signature Verification
Each webhook request includes a X-BOOQR-Signature header containing an HMAC-SHA256 signature. Verify this to ensure the request came from BOOQR.
Node.js signature verificationjavascript
import crypto from "crypto";
function verifyWebhookSignature(payload, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your webhook handler:
const isValid = verifyWebhookSignature(
JSON.stringify(req.body),
req.headers["x-booqr-signature"],
process.env.WEBHOOK_SECRET
);Retry Policy
Failed deliveries (non-2xx response or timeout) are retried with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
| 5th retry | 24 hours |
After 5 failed attempts, the webhook is marked as failing and disabled after 3 consecutive failures.
Best Practices
- Always verify the webhook signature
- Return
200 OKas quickly as possible — process the event asynchronously - Handle duplicate events idempotently (use the event
id) - Use HTTPS endpoints only
- Monitor your webhook delivery status in the admin dashboard