Webhooks

Webhook Guide

Receive real-time HTTP notifications when events happen in your studio.

How it works

When you register a webhook endpoint in Admin → Settings → Developer → Webhooks, BOOKING BIBLE will POST a JSON payload to your URL whenever a subscribed event occurs.

Every request includes an X-Webhook-Signature header — an HMAC-SHA256 hash of the request body, signed with your endpoint's secret. Verify this on every request to make sure the event is really from us.

Event types

EventDescription
Bookings
booking.createdA new booking was created
booking.cancelledA booking was cancelled
booking.checked_inA member checked in to a class
booking.no_showA member was marked as no-show
booking.waitlist_promotedA member was promoted from the waitlist
Classes
class.createdA new class instance was generated
class.updatedA class instance was updated
class.cancelledA class instance was cancelled
Members
member.createdA new member signed up
member.updatedA member profile was updated
member.deletedA member was removed
Passes
pass.activatedA pass was activated
pass.expiredA pass expired
pass.pausedA pass was paused
pass.cancelledA pass/subscription was cancelled
Payments
payment.succeededA payment was completed
payment.failedA payment failed
payment.refundedA payment was refunded
Instructors
instructor.substitutedAn instructor was substituted for a class

Payload format

Every webhook request POSTs a JSON envelope with a unique event id, type, timestamp, organization id, and an event-specific data object.

POST /your-webhook-url
{
  "id": "evt_a1b2c3d4",
  "type": "booking.created",
  "created_at": "2026-04-12T07:15:00Z",
  "organization_id": "org_xxxx",
  "data": {
    "booking_id": "bk_xxxx",
    "user_id": "usr_xxxx",
    "class_instance_id": "ci_xxxx",
    "class_name": "Hot Yoga",
    "start_time": "2026-04-12T08:00:00Z",
    "status": "confirmed",
    "attendance_type": "physical"
  }
}

Request headers

HeaderValue
Content-Typeapplication/json
X-Webhook-Signaturesha256=xxxxxxxx...
X-Webhook-Eventbooking.created
X-Webhook-Idevt_a1b2c3d4
X-Webhook-Timestamp2026-04-12T07:15:00Z
User-AgentBookingBible-Webhooks/1.0

Verifying signatures

Compute an HMAC-SHA256 of the raw request body using your endpoint's secret, then compare the result with the X-Webhook-Signature header. Always use a constant-time comparison function — never === or ==.

const crypto = require('crypto');

function verifyWebhook(body, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(body, 'utf8')
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// Express middleware
app.post('/webhooks/bookingbible', (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  if (!verifyWebhook(req.rawBody, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  const event = req.body;
  console.log(`Received ${event.type}:`, event.data);
  res.status(200).send('OK');
});

Retry policy

If your endpoint returns a non-2xx status or times out (10s), we retry with exponential backoff:

AttemptDelay
1immediate
2after 1 minute
3after 5 minutes
4after 30 minutes
5after 2 hours
6after 12 hours

After 10 consecutive failures, the endpoint is automatically disabled. You can re-enable it from the admin panel.

Best practices

  • Respond with a 2xx within 5 seconds. Process events asynchronously.
  • Use X-Webhook-Id to deduplicate — we may send the same event twice.
  • Store the raw payload before processing for debugging.
  • Verify the signature on every request — never skip this.
  • Monitor your endpoint in Admin → Settings → Developer → Webhooks for delivery logs and failures.

Ready to subscribe?

Add a webhook endpoint from the admin panel and start receiving events in minutes.