Availability, rates and restrictions
Pull current availability, rates or restrictions for a property and a date window, instead of waiting for an event. Same shape, same builders, same payload.
Three endpoints, one request shape.
{property} accepts either a Doorloom property id or your external
alias. Doorloom resolves whichever it recognises.
Query parameters
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
from
|
string | Required | YYYY-MM-DD. First night, inclusive. |
to
|
string | Required | YYYY-MM-DD. Last night, inclusive. Must be on or after from. |
Limits
| Field | Type | Description |
|---|---|---|
Window length
|
integer | At most 92 days per call. Page through anything longer. |
Horizon
|
integer | to may reach at most 730 days ahead of today. |
curl -G "https://api.doorloom.com/api/integrations/v1/properties/VILLA-9/availability" \
-H "Authorization: Bearer $DOORLOOM_API_KEY" \
--data-urlencode "from=2026-10-12" \
--data-urlencode "to=2026-10-15"
Response
The envelope is the same for all three. Note the nesting: data.data is the payload
proper.
{
"success": true,
"message": "OK",
"data": {
"sequence": 1047,
"property": {
"doorloom_id": 902,
"external_id": "VILLA-9"
},
"window": {
"from": "2026-10-12",
"to": "2026-10-15"
},
"data": {
"total_units": 2,
"units": [
"…"
],
"dates": [
{
"date": "2026-10-12",
"available_units": 1,
"total_units": 2,
"is_blocked": false,
"block_scope": null,
"units_cap": null
},
{
"date": "2026-10-13",
"available_units": 0,
"total_units": 2,
"is_blocked": false,
"block_scope": null,
"units_cap": null
},
{
"date": "2026-10-14",
"available_units": 0,
"total_units": 2,
"is_blocked": true,
"block_scope": "everywhere",
"units_cap": null
},
{
"date": "2026-10-15",
"available_units": 1,
"total_units": 2,
"is_blocked": false,
"block_scope": "ota_only",
"units_cap": 1
}
]
}
}
}
| Field | Type | Description |
|---|---|---|
sequence
|
integer | The sequence watermark, read before the payload was built. |
property
|
object | Which property this is, by both ids. |
window
|
object | The range covered, inclusive at both ends. |
data
|
object | The payload — exactly the data block the matching webhook carries. |
One parser for both paths
data.data is byte-identical to the data of the matching event. Whatever
applies an availability.changed payload can apply this, unchanged.The three payloads
Each is documented in full on its event page, because it is the same thing:
availability—total_units,units[], and per-night sellable counts, blocks and caps.rates— currency, GST flags, meal plans, and per-night prices with their source.restrictions— property-wide booking rules, and per-night minimum and maximum stay and stop-sell.
There is no snapshot endpoint for inventory or property; use
GET /properties, which carries
both.
Using the watermark safely
data.sequence is captured before the payload is built. So:
- Any event with a higher sequence is safe to apply on top of this snapshot, whether or not the snapshot already reflects it — the event is full state, so re-applying is a no-op.
- Any event with a lower or equal sequence is already included, and your apply-if-newer rule will discard it.
Concretely: after taking a snapshot, set your cursor for that property and type to
data.sequence, and carry on.
When to use snapshots rather than events
- Cold start. First connection, or a new property appearing in your coverage.
- A cursor older than 30 days. Past the event retention window, replay is not available.
- A drift check. Pull a window occasionally and compare against what you hold.
For an ordinary outage, replay is cheaper and simpler. See Staying in sync for a decision table.
Errors
Errors
| Status | Code | Meaning |
|---|---|---|
| 422 | VALIDATION_FAILED |
The request body failed validation. errors is Laravel's field bag: an object keyed by field path, each holding an array of messages. |
| 404 | NOT_FOUND |
No such booking or property for this integration. Another integration's booking is not found rather than forbidden, so ids cannot be probed across partners. |
| 401 | UNAUTHENTICATED |
No API key, or a key that is not valid. Rotating your API key invalidates the previous one immediately. |
| 429 | RATE_LIMITED |
You exceeded one of the rate limits. The standard Retry-After and X-RateLimit-* headers are set on the response. |
A window longer than 92 days, or reaching beyond 730 days ahead, is a
422 VALIDATION_FAILED against the to field. An unknown or uncovered
property is 404 NOT_FOUND.