Changelog
What has changed in the Brand Integration API, and what we consider ourselves free to change without telling you first.
Compatibility policy
The API version is stamped on every webhook as version and returned by
GET /me. It is currently
2026-09.
Within a version, changes are additive only. Concretely, these may happen without notice:
- A new field appears in a response or an event payload.
- A new event type appears — you will only receive it if your subscription includes it.
- A new optional request field is accepted.
- A new error
codeappears for a case that previously had a more general one. - An error
messageis reworded. Branch oncode, not prose.
These will not happen inside a version:
- A field is removed, renamed, or changes type.
- An existing field changes meaning.
- A previously optional request field becomes required.
- An endpoint changes path or method.
Parse defensively
A breaking change means a new version. Versions run in parallel, and we would agree a migration window with you before anything is switched off.
Releases
2026-09 — current
The first public release, live since 24 September 2026.
- Signed webhooks for availability, rates, restrictions, inventory, properties and bookings, plus a connectivity ping. Gap-free per-integration sequencing, full-state payloads, strict in-order delivery.
- Property API: create with mandatory idempotency, merge-style update, and bulk create and update of up to 25 properties per call.
- Booking API: create with mandatory idempotency, retrieve by either id, update with optional
If-Matchconcurrency, and idempotent cancel. - Reconciliation: property listing, availability, rate and restriction snapshots sharing the webhook payload shapes, event replay over a 30-day window, and full re-sync.
- HMAC-SHA256 request signing with a 24-hour dual-secret rotation window.
Additions
Additive within 2026-09; nothing that existed before changed shape
or meaning.
| Field | Type | Description |
|---|---|---|
POST /properties
|
added | Create a property under your brand from your own system — name, type, description, address, room counts, occupancy, opening weekday/weekend rates, up to 50 units with your unit ids, and house-rule flags. Requires Idempotency-Key. The 201 is the GET /properties block. See Create a property. |
PUT /properties/{id}
|
added | Merge-style update of a covered property, addressed by Doorloom id or your external id: listing facts, address, base rates, units by inventory_id or alias (an unknown alias creates the unit), and re-mapping or clearing your external_id. No idempotency key, no If-Match. See Update a property. |
POST /properties/bulk, PUT /properties/bulk
|
added | Up to 25 properties per call. The batch is validated as a whole, then each item is written on its own and reported in results[] with a summary. Bulk create requires Idempotency-Key. See Bulk create and update. |
external_id and external_unit_id are yours to set
|
added | Previously only Doorloom staff mapped them. You set them on create, and set, change or clear them on update. Uniqueness is per integration. |
Coverage on create
|
added | A property you create is covered by your integration in the same transaction — coverage reads active in the 201 — listed by GET /properties and bookable immediately, regardless of your auto-enrol setting. |
Initial snapshot on create
|
added | A created property sends property.changed, inventory.changed and the windowed availability.changed, rates.changed and restrictions.changed events across your horizon — the same set POST /sync produces for one property — within seconds. |
property.changed on address and occupancy edits
|
added | An in-place change to a property's address or occupancy — by the host or by you — now emits property.changed. Previously only renames, archiving and coverage changes did. |
PROPERTY_EXTERNAL_ID_EXISTS
|
added | 409 when an external_id you send is already mapped to another of your properties; errors.doorloom_id names it. On a create nothing is created; on an update the mapping is unchanged. |
IDEMPOTENCY_KEY_REQUIRED on property creates
|
added | The same 422 booking create returns, with a message naming the endpoint. Keys are one namespace per integration across every create. |
New VALIDATION_FAILED keys
|
added | units.N.external_id, units.N.inventory_id, units.N.name, units.N.is_active, units.N and properties.N.* — see the error reference. |
Documentation changes
These clarified the documentation without changing behaviour. They are listed because if you built against an earlier draft, these are the places you may have guessed wrong.
| Field | Type | Description |
|---|---|---|
property.changed carries property_type
|
clarified | It was always sent, and was missing from the catalogue. |
units[] carries code, is_default, max_occupancy, deleted
|
clarified | All four were always sent. deleted in particular is how you know to retire an alias. |
Accept and X-Doorloom-Integration delivery headers
|
clarified | Both were always sent and were missing from the header list. |
errors.availability.window.to is check_out minus one day
|
clarified | It is the last night of the stay, not the departure date. |
Money is a JSON number
|
clarified | 13000.00 serialises as 13000. Parse numerically. |
Timestamps are ISO-8601 in Asia/Kolkata
|
clarified | They carry a +05:30 offset and are not UTC-normalised. |
source.channel is not patchable
|
clarified | Only source.reference can be changed after create. |
No acknowledge endpoint, no single-event resend
|
clarified | The after_sequence cursor is the only catch-up mechanism; a redelivery is always a new event. |
Behaviour changes
| Field | Type | Description |
|---|---|---|
POST /sync is limited to one per 24 hours
|
changed | The interval between full re-syncs was 10 minutes and is now 24 hours; the edge cap moved from six an hour to six a day. Nothing about the response shape changed — a too-soon call is still 429 SYNC_TOO_SOON with errors.retry_after, which now simply reports a much larger number. If you were re-syncing to recover from missed events, move to GET /events, which has no interval. |
401 returns the standard envelope
|
changed | An unauthenticated call now answers an envelope whose code is UNAUTHENTICATED, instead of a bare message object. If you branched on the absence of code, branch on the status instead. |
429 returns the standard envelope
|
changed | A rate-limited call now answers an envelope whose code is RATE_LIMITED, carrying errors.retry_after, instead of a bare message object. The Retry-After and X-RateLimit-* headers are unchanged. |
Every endpoint has its own rate-limit tier
|
changed | Reads, event replay, booking reads, booking writes, property writes and bulk property writes each have a dedicated per-minute budget under the unchanged 300-a-minute ceiling. See rate limits. If you were pacing only against the ceiling, the tightest tier that now binds is 120 property reads a minute. |
The API is live in every environment
|
changed | There is no longer a platform-level switch that answers 404 for the whole API. An integration that Doorloom staff disable still gets 403 INTEGRATION_DISABLED; a paused one keeps API access and only stops receiving webhooks. |
The first two were documented as enveloped before they were. They now match the documentation,
which means every failure from this API carries a code you can branch on.
Staying informed
Doorloom contacts integration partners directly about anything that affects them. If the right person for that is not the person who set up your integration, tell [email protected] who it should be.