Operate
Rate limits
Every budget is enforced before anything is written, answers 429 with Retry-After, and is announced on every answer so you can pace yourself before you are ever refused.
Budgets
60 s sliding, shared by every API machine; counters are exact, not per machine.
| data.scope | Budget | Counts |
|---|---|---|
| ip | 240 / min | every request from one address, checked before the key is read |
| ip-auth | 20 / min | 401 answers to one address; after that the address is refused before any lookup |
| requests | 120 / min | every request on one key |
| writes | 30 / min | PUT requests on one key |
| property | 300 / min | every request on all of a property's keys together (five keys are not five budgets) |
| property-writes | 60 / min | PUT requests on all of a property's keys together |
| cells | 20,000 / min | cells a property's writes name after range expansion, charged before anything is read or written |
| bookings | 20 / min | POST /bookings on one key |
| property-bookings | 40 / min | POST /bookings on all of a property's keys together |
| property-bookings-day | 500 / day | POST /bookings per property per ROLLING 24 HOURS (not per minute); the owner can raise it per property |
| global | 3,000 / min | every request on the Connect API, all keys and addresses |
Per request
maxUpdatesPerRequest1,000 entries inupdates;maxCellsPerRequest5,000 cells (entity × night).maxBodyBytes1,048,576 — 413 when the JSON body exceeds 1048576 bytes; split the updates array.horizonDays365: the last writable night and the last bookable arrival are today + 365 in the property's calendar.maxNightsPerBooking90.
Headers
RateLimit-Policy: "key";q=120;w=60, "key-writes";q=30;w=60
RateLimit: "key";r=117;t=42, "key-writes";r=29;t=42
# on a 429
Retry-After: 17RateLimit-Policy— on every answer, one quoted policy per key scope — "key";q=120;w=60, "key-writes";q=30;w=60RateLimit— on every answer, what is left and when it refills — "key";r=117;t=42, "key-writes";r=29;t=42Retry-After— on every 429, whole seconds to wait; the body's data.scope says which budget refused
How to pace
- Batch: one PUT per resource carrying ranges (dateFrom..dateTo, optional days) — a 365-night calendar for three plans is a handful of updates, not a thousand
- Send on change, not on a timer: unchanged cells are dropped and cost nothing, but they still spend your request budget
- Read RateLimit on every answer and slow down when r approaches 0, instead of waiting for a 429
- Reuse x-idempotency-key on a retry so a timed-out request can never land twice
- Poll GET /batches/{batchId} and GET /sync no more than every 15 s; the push to the channels is asynchronous and bounded by the channel manager's own budget
The channel manager's own budget
Your 202 means the cells are in our record. Pushing them to the channel manager is paced by its budget — ten rate/restriction reads a minute for the whole account and a per-property write budget — so a full calendar takes minutes, never seconds, and is never lost.
We coalesce your cells into the fewest channel-manager calls, drop what did not change, pace every call, stop before the channel manager's last token, and back off on its Retry-After — you never have to think about its limits, only about ours.
Facts on this page (routes, samples, limits, codes) come from the API's public contract read live, Tue, 20 Oct 2026 13:10:41 GMT.