Overview and events
Webhooks are in active development. This is the specification.
A webhook tells you something changed. It does not tell you what the thing now is.
Thin payloads, on purpose
{
"id": "01JGQ7XN2M4T8V6R0KZC3PWA5E",
"type": "reservation.confirmed",
"occurredAt": "2026-08-31T14:02:11.000Z",
"accountCode": "b41c9e07",
"data": {
"reservationCode": "7f3e9c02",
"propertyCode": "a1b2c3d4"
}
}
Reference codes and a timestamp. No guest names, no door codes, no money.
Three reasons. A fat payload is a second copy of data the scope system is carefully guarding, delivered over a channel with weaker guarantees. Deliveries arrive out of order, so a payload describing state is a payload that can be stale on arrival and wrong if you write it down. And a body carrying listing prose reliably trips web application firewalls, which is how a competitor lost 295 deliveries in a week with nothing in their logs to explain it.
Treat an event as an instruction to re-read. The REST call is the record.
Events
| Event | Fires when | Scope required to subscribe |
|---|---|---|
reservation.requested | A booking request is made | reservations:read |
reservation.confirmed | A booking is confirmed | reservations:read |
reservation.cancelled | A booking is cancelled | reservations:read |
reservation.dates_changed | Stay dates move | reservations:read |
reservation.refunded | A refund is issued | reservations:read |
calendar.availability_changed | Blocks change on a listing | calendar:read |
rates.changed | Overrides, promotions or bumps change | rates:read |
listing.created | A listing is added | listings:read |
listing.updated | Listing content changes | listings:read |
listing.market_state_changed | Archived, hidden, or booking toggled | listings:read |
message.received | A guest sends a message | messaging:read |
connection.scopes_changed | The host changes what you may do | none |
connection.revoked | The host disconnects you | none |
endpoint.verified | Sent once when an endpoint is registered | none |
You cannot subscribe to an event class you hold no read scope for. The subscription is a filter; scope is the authority.
The two connection.* events need no scope and cannot be unsubscribed. Learning that a host disconnected you from a webhook rather than from a failed call an hour later is the difference between a clean stop and a queue of errors.
Registering an endpoint
An endpoint is https only. Haven resolves the host and refuses private address ranges, link-local addresses and loopback, and does not follow redirects.
On registration Haven sends a signed endpoint.verified probe. Answer 2xx within ten seconds and the endpoint goes active. Until then nothing is delivered, which means a misconfigured URL fails at setup rather than silently swallowing a month of events.
An endpoint may be scoped to one connection or shared across every host connected to your application. A shared endpoint is managed from your developer console with client credentials, never with a host's access token, so one host's consent can never reach a channel carrying another host's events.
Delivery
Acknowledge fast. Return 2xx as soon as you have durably queued the event, and do your work afterwards. Haven allows ten seconds; a handler that does the work inline will eventually exceed it under load, and the retry will arrive while the first attempt is still running.
Failed deliveries retry on a published schedule with growing gaps, and a permanent 4xx dead-letters immediately rather than retrying against an endpoint that is gone. Sustained failure disables the endpoint and emails your contact address. You can re-enable it yourself; you will not have to ask Haven to do it for you.
Duplicates and ordering
Expect duplicates. At-least-once delivery is what makes retries safe. The id field is a stable delivery identifier: record processed ids and drop repeats.
Expect disorder. A retried event can arrive after a newer one. Never reconstruct state from event sequence. Re-read the resource and use what the API returns.
What does not arrive on connection
When a host first authorizes you, you get endpoint.verified and nothing else. Existing listings, reservations and conversations are not replayed as events. Backfill by walking the REST endpoints once, then rely on webhooks for changes.
This trips up almost every integration against every platform in this category, so it is stated plainly rather than left to be discovered.
Delivery log and replay
Every delivery is recorded with its response code and body snippet, queryable from your developer console and by API, and any delivery can be replayed on demand.
That is unusual: one major competitor cannot list past failures at all, and another requires an email to their support team to re-enable a disabled endpoint. Being able to see what Haven sent and ask for it again is meant to remove a whole category of support conversation.