Enquiries Channel manager Bookings Your website Booking engine Pricing
v2026-09

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.

GET https://api.doorloom.com/api/integrations/v1/properties/{property}/availability
GET https://api.doorloom.com/api/integrations/v1/properties/{property}/rates
GET https://api.doorloom.com/api/integrations/v1/properties/{property}/restrictions

{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.
Request bash
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.

Response 200 json
{
    "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:

  • availabilitytotal_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.

Something unclear or wrong on this page? Write to [email protected] and tell us which page — we would rather fix the doc than answer the ticket twice.