Webhooks
Get told when a booking changes instead of polling for it.
Webhooks go to your organization's webhook URL, which you set on the Settings page. Every booking your organization makes is delivered there, whichever API key made it. With no URL set, nothing is sent. Delivery history is on the Webhooks page of the dashboard.
webhook_url on POST /v1/bookingsis accepted and stored, but deliveries do not use it: they always go to the organization's URL.Events
booking.createdbooking.requires_actionbooking.processingbooking.confirmedbooking.failedbooking.cancelledbooking.modifiedNo event is sent when a booking expires (a booking left in requires_action for more than 20 minutes). Read the booking to see it.
Payload
A POST with a JSON body. data.object is a summary of the booking: id, object, status, provider, and when present error_code, error_message, next_action and last_modification. For everything else, read GET /v1/bookings/{id}.
Verifying the signature
Each delivery carries an Ophelia-Signature header of the form t=<unix seconds>,v1=<hex>. v1 is the HMAC-SHA256 of <t>.<raw body>, keyed with your organization's webhook signing secret, hex-encoded. Compute it over the raw bytes you received, before parsing the JSON, and compare in constant time. Every attempt is signed afresh, so t is the time of that attempt.
Delivery and retries
Deliveries are sent by a background worker that runs every 30 seconds, so an event usually arrives within half a minute. Any 2xx answer within 10 seconds counts as delivered. Anything else (another status, a timeout, a connection error) is retried after 30 seconds, then 2 minutes, then 10 minutes; after the fourth failed attempt the delivery is abandoned.
Delivery is at least once and events can arrive out of order. Deduplicate on the event id, and treat data.object.status as a hint: when order matters, read the booking.