Rate limits
Default quotas, per integration per workspace:
| Bucket | Limit |
|---|---|
| Requests per minute | 300 |
| Requests per day | 20 000 |
| Write requests per minute | 60 |
Writes have their own, tighter budget because each one can fan out to a channel push. A runaway read loop costs us queries; a runaway write loop reaches the OTAs.
Higher tiers exist. If a legitimate integration pattern does not fit, talk to us rather than working around it — usually the answer is a filter you are not using yet, and occasionally it is a tier change.
Headers
Every response carries the current state, not just the ones that fail:
Code
X-RateLimit-Reset is a Unix timestamp. The values reflect whichever bucket is
tightest right now, which is the one you will hit next.
When you exceed it
Code
Code
Honour Retry-After. Retrying sooner just consumes budget you do not have.
Staying inside the quota
The limits are set on the assumption that you use the API as designed. Three habits account for almost all of the difference:
- Delta sync, not full sync.
updated_afterturns a nightly re-read of every reservation into a handful of requests. - Batch your writes.
PUT /v1/calendarapplies a whole season across many properties in one call. Ninety separate per-day requests do the same work for ninety times the quota, and cost far more to propagate to the channels. - Subscribe to webhooks. Most polling exists to notice changes. Being told instead removes it.
Back off properly
Code
Add jitter if you run several workers, or they will all wake up together and spend the new window in the first second.

