PUT /v1/webhooks/endpoint. Get verification right and
every delivery you act on is provably ours; get it wrong and anyone who finds your
endpoint URL can feed your system fake bookings — see
Webhook signatures before you rely on anything this page
delivers.
Registering your endpoint
Send the URL and the events you want:- Every event is available to every key. See
The event catalogue. Asking for one
that is not on the list answers
400 validation_failedand names the event, so the fix is never a guess. httpsonly, on port 443 or 8443, on a publicly resolvable DNS name. We check the address the name actually resolves to at the moment we connect — not just at registration — and we never follow redirects. A refused URL gets one genericvalidation_failed; we do not report which check failed.- One endpoint per workspace. Registering again replaces the URL and the event list.
A
PUTon an endpoint that is alreadyactivetakes it back topending_verificationfirst, and the challenge decides whether it comes back. So do not re-register while your handler is down or mid-deploy: a re-registration that fails its challenge leaves you subscribed to nothing until you send another one that passes.eventsmust name at least one event: an empty array is refused, because every registration re-arms the challenge and an empty one would leave your endpointpending_verificationand subscribed to nothing.DELETE /v1/webhooks/endpointis the operation that means stop, and it keeps your secret and your history — see Managing your endpoint yourself. - The signing secret is returned once, in the response to your first registration, and never again — we cannot read it back. Store it in a secret manager immediately. Re-registering (a corrected path, a new event list) does not mint a new secret, so your existing verification keeps working.
The challenge round-trip
Nothing real is delivered until your endpoint proves it is yours. During the registration call we POST a signedendpoint.challenge delivery to your URL, and your
handler must answer 2xx with a JSON body echoing the same string back:
active. Anything else leaves it
pending_verification and nothing is ever sent to it — call the registration endpoint
again to retry. The challenge is signed exactly like a real delivery, so your
verification code is exercised before your first real payload rather than after it.
Respond within five seconds; the challenge happens inside your own registration
request. And expect it on every registration call, including one that does not change
the URL.
Acknowledge within the deadline
Every delivery gives you ten seconds to answer, and any2xx acknowledges it. Past
that we retry on a fixed ladder — what to do about retries, ordering and a delivery that
never lands is the rest of the story: Webhook delivery.
Where the rest lives
- Verifying a delivery is genuinely ours — the header scheme, the exact bytes to sign, two offline test vectors, and verifiers in Node, Python and Go: Webhook signatures.
- Everything about a delivery’s lifecycle — retries, ordering, what a booking payload carries, the full event catalogue, running your endpoint’s own lifecycle, the delivery log, redriving a delivery, and sending yourself a test event: Webhook delivery.
- What each event actually carries, field by field with a live example: its own
reference page under API Reference → Booking notifications (and → Reviews,
Listings, Pricing, Calendar for the rest), or browse the closed set as
WebhookEventType. - The seven
booking.*events as one state machine — which fires when, what never fires, and how to apply them in order: Booking notifications lifecycle.