Skip to content

Subscribe to Events via Webhook

A webhook subscription forwards platform events to a URL you control. Use it to connect Bookable to Slack, a data warehouse, an access control system, or any downstream pipeline that needs to react in real time. See Event for the full envelope and the list of event names.

Create the Subscription

POST /event/webhook

json
{
  "url": "https://hooks.example.com/bookable",
  "event_name": "booking_created",
  "owner_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

url and owner_id are required. Set event_name to the name of a single event to receive only that event. Set event_name: null to subscribe to every event the owner can see.

Response:

json
{
  "data": {
    "id": "55555555-6666-7777-8888-999999999999",
    "url": "https://hooks.example.com/bookable",
    "event_name": "booking_created",
    "active": true,
    "secret": "wh_sec_2f1d3a8b6c4e0f9a7d2b1c8e5f3a9b6d2c7e1f4a8b3d6c9e0f5a7b1d8e2c4f6",
    "owner_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "created_by": "e992bfc1-0336-42c5-bd0a-4f4804a9fd24",
    "created_at": "2026-05-15T10:00:00.000Z",
    "updated_at": "2026-05-15T10:00:00.000Z"
  },
  "request_id": "c1d2e3f4-a5b6-7890-cdef-123456789012",
  "count": 1
}

WARNING

secret is returned once, in this response only. Read endpoints do not disclose it. Capture it now into the receiver's config. If the secret is lost, delete the subscription and create a new one.

What the Receiver Gets

Each delivery is an HTTP POST to the configured URL with the standard event envelope:

json
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "event_name": "booking_created",
  "timestamp": "2026-05-15T08:00:12Z",
  "context": {
    "booking": { "id": "f9955a9a-bb9e-450b-8e91-09a43f0e6cd6" },
    "bookable": { "id": "c3d4e5f6-a7b8-9012-cdef-345678901234" },
    "user": { "id": "e992bfc1-0336-42c5-bd0a-4f4804a9fd24" }
  }
}

Verifying the Signature

Every delivery includes an X-Samna-Signature header in the form:

X-Samna-Signature: t=1747299612,v1=3d9f1a2b4c5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a

t is the Unix timestamp of the delivery. v1 is the HMAC SHA-256 hex digest of <timestamp>.<body> using the subscription secret as the key. Reject deliveries where t is more than 5 minutes from now to defend against replay.

Inspecting and Removing

GET /event/webhook lists every subscription the caller can see. GET /event/webhook/{id} returns one subscription without the secret. DELETE /event/webhook/{id} removes the subscription; deliveries stop on the next event.

One Subscription for Many Events

A single subscription with event_name: null receives every event for the owner. Filter on the receiver side by event_name in the envelope. This is the simplest setup when one downstream handles many types.

To route by destination, create one subscription per event_name value, each pointing at a different URL.