Overview
Booking webhooks deliver a signedPOST to an HTTPS endpoint you control every
time a booking transitions in your workspace. Subscriptions are managed by a
workspace administrator from the Copera app’s Bookings settings; each
subscription has a receiver URL, a set of events, and a signing secret.
Events
| Event | Fires when |
|---|---|
booking.created | A booking is created (pending or confirmed). |
booking.confirmed | A booking is confirmed. |
booking.cancelled | A booking is cancelled. |
booking.rescheduled | A booking is rescheduled to a new time. |
booking.declined | A pending booking is declined by the host. |
booking.reassigned | A booking’s host is reassigned (round-robin). |
booking.no_show | A no-show is recorded for the host or booker. |
Request
Each delivery is aPOST with a JSON body:
data block is your workspace’s own booking data, so the booker’s contact
details are included. Internal handles (the booking’s manage token, idempotency
key, ICS internals) are never sent.
Headers
| Header | Value |
|---|---|
X-Copera-Event | The event string (e.g. booking.confirmed). |
X-Copera-Signature | sha256=<hex> — HMAC-SHA256 of the raw request body using your subscription secret. |
X-Copera-Webhook-Version | The payload contract version (currently 1). |
Verifying the signature
Compute the HMAC-SHA256 of the raw request body (before JSON parsing) with your subscription secret and compare it, in constant time, to the hex inX-Copera-Signature:
Delivery and retries
- Respond with a
2xxstatus to acknowledge receipt. - A
4xxresponse is treated as a permanent rejection — we do not retry. - A
5xx, network error, or timeout is retried with exponential backoff (3 attempts total). Receivers should be idempotent — the same event may be delivered more than once. - Receiver URLs must be public HTTPS endpoints; private / internal addresses are rejected.