The event envelope
Every event, whatever its type, arrives inside the same wrapper. Only data differs.
{
"id": "01J6Y0Q8ZK3N4V6M7P8R9S0T1U",
"type": "availability.changed",
"version": "2026-09",
"sequence": 1042,
"occurred_at": "2026-10-01T15:04:11+05:30",
"integration": {
"id": 12,
"slug": "acme-pms"
},
"property": {
"doorloom_id": 902,
"external_id": "VILLA-9",
"master_property_id": 902
},
"window": {
"from": "2026-10-12",
"to": "2026-10-15"
},
"data": [
"…"
]
}
Fields
| Field | Type | Description |
|---|---|---|
id
|
string | A ULID, unique forever. Useful as a log key and for deduplicating at the transport level. It is not ordered in any way you should rely on — that is what sequence is for. |
type
|
string | One of the seven types in the event catalogue. |
version
|
string | The API version this payload is shaped by. Currently 2026-09. Within a version, changes are additive only. |
sequence
|
integer | Gap-free, strictly increasing per integration. The basis of the apply-if-newer rule. |
occurred_at
|
string | ISO-8601 with offset, in Asia/Kolkata. When the event was built, which is when its data was true. |
integration.id
|
integer | Your integration id. |
integration.slug
|
string | Your integration slug, e.g. acme-pms. Also sent as the X-Doorloom-Integration header. |
property
|
object|null | The property this event is about. Null for ping. |
property.doorloom_id
|
integer | Doorloom's permanent property id. |
property.external_id
|
string|null | Your alias for it, if one is mapped. |
property.master_property_id
|
integer | The head of this property's cluster. Equal to doorloom_id when the property is not part of one, or is the head. |
window
|
object|null | The date range this payload covers. Null for events that are not date-scoped. |
window.from
|
string | Y-m-d. Inclusive. |
window.to
|
string | Y-m-d. Inclusive — this night is in data.dates. |
data
|
object | The type-specific payload. Documented per event type. |
Which events carry a window
Three types are date-scoped and always carry a window:
availability.changed, rates.changed and
restrictions.changed. Their data.dates[] has exactly one entry per
night in the window, inclusive of both ends.
A window never spans more than one calendar month. A change across a longer range arrives as several events, each with its own sequence, each covering part of the range.
inventory.changed, property.changed and
booking.changed describe a thing rather than a period, and carry
window: null. ping carries property: null as well.
window.to is inclusive, check_out is not
2026-10-12 to 2026-10-13 covers two nights, and both
appear in dates[]. A booking with check_in: "2026-10-12" and
check_out: "2026-10-14" also covers two nights — the 12th and the 13th — because the
guest leaves on the morning of the 14th.Clusters
Doorloom lets a host group properties into a cluster: a main property and its sub-properties,
which block each other's availability. master_property_id tells you where a listing
sits in that structure.
If you do not model clusters, ignore both cluster fields. The mutual blocking is already reflected in the availability events for each property, so you never have to compute it.