Lists
GET /locations, /owners, /properties, /amenities and /webhooks answer a page:
limitis 1 to 500, 100 by default; above 500 is refused.- To read the next page, send
next_cursorback ascursor. It is opaque and bound to the query that produced it. It isnullon the last page. /locations,/ownersand/propertiesfilter bystatus, for examplestatus=active,inactive, and/propertiesalso bylocation_idandowner_id.- A single resource is
GET /locations/{location_id},/owners/{owner_id},/properties/{property_id}. - A read carries an
ETag(every one exceptGET /availability); send it back asIf-None-Matchand an unchanged answer is304 Not Modified, everywhere but the webhook delivery logs (/webhooks/{webhook_id}/deliveries).
location_id and owner_id, so read locations and owners before the properties that point to them.
The first copy, then only the changes
1
Read everything once
List each resource without
updated_since, following next_cursor to the end. Keep every resource with its version, and remember the largest updated_at you received.2
Ask for what changed since then
List again with
updated_since set to that largest updated_at. The bound is inclusive, so you need no overlap: what changed at that very second comes back again, and its version tells you whether you already have it.3
Apply by version
Apply a resource only when its
version is higher than the one you hold, and ignore a lower one. A version grows with every change visible to your channel, but it is not a counter: do not expect consecutive values.4
Start over when the window has passed
An
updated_since older than the retention window, 35 days, is answered 410 with sync-window-expired. Resync from scratch: read everything once, as in the first step.One lifecycle for every resource
Locations, owners, properties, amenities and webhook endpoints share onestatus, with the same meaning everywhere:
A
withdrawn or deleted resource is a tombstone, on every resource, and nothing else is sent:
updated_since; without it, only active and inactive resources exist. A single resource read by its id answers with its tombstone. Handle all four values on every resource, including one that resource does not reach today.
Availability and prices
Availability is read per property and per night, in the property’s own dates.GET /properties/{property_id}/availability?from=2026-12-20&to=2026-12-27answers a property’s nights in a window:tois exclusive, the window is at most 365 nights and within the published horizon. Afrombefore the property’s today is served from today, and the response says which window it served. A window beyond the horizon is answered400withwindow-beyond-horizonand the property’shorizon_end. A withdrawn or deleted property answers404.GET /availability?updated_since=…&from=…&to=…answers the nights that changed, grouped by active or inactive property. A page ends atlimitproperties or 5,000 nights, whichever comes first, so a property’s nights may continue on the next page under the sameproperty_id: apply them by date. A page costsmax(1, ceil(nights / 1000))units of your rate limit.
units_available (0 is sold out), min_stay and max_stay for an arrival that night, closed_to_arrival, closed_to_departure, and a rate per rate plan. A rate’s price is for base_occupancy guests, as the guest pays it (VAT included, markup applied), and is null when the rate is closed; extra_guest_price is the price of one more adult, 0 when free, null when the price covers everyone.
The event log
GET /events is your log, in commit order, of what changed, retained for 35 days. Store the last_event_id of each page and send it back as since; next_cursor is null once you are caught up. Without since the log starts at its oldest retained event. Only the event types your key’s scopes cover appear: availability.updated needs read:ari.
A since behind the retained log is answered 410 with event-cursor-expired and the latest_event_id: resync with updated_since, then continue the log from latest_event_id.
An event names a resource and its version, or, for availability.updated, a property and a range of nights (from, to exclusive) with no version: re-read that range. The event types are location.created, location.updated, location.deleted, owner.created, owner.updated, owner.deleted, property.created, property.updated, property.deleted, property.distributed, property.withdrawn and availability.updated, and more may be added.