Rate limits
Request limits and payload caps. All of them are per integration, so they are yours alone to manage.
Request limits
Every endpoint sits in exactly one tier below, on top of the overall ceiling. Tiers are independent: exhausting bulk property loads does not slow your booking writes or your reads.
| Field | Type | Description |
|---|---|---|
All API calls
|
per minute | 300 per integration, and 600 per source IP. Whichever binds first. The ceiling every tier below sits under. |
GET /me
|
per minute | 60. |
Property reads
|
per minute | 120 — GET /properties and the availability, rates and restriction snapshots share this budget. |
Event replay
|
per minute | 120 — GET /events. |
Booking reads
|
per minute | 120 — list, by id and by external id share this budget. |
Booking writes
|
per minute | 60 — create, update and cancel share this budget. |
Property writes
|
per minute | 30 — POST /properties and PUT /properties/{id} share this budget. |
Bulk property writes
|
per minute | 6 calls — POST and PUT /properties/bulk, each carrying up to 25 properties, so up to 150 properties a minute. |
POST /sync
|
per day | One per 24 hours. Six calls a day are accepted at the edge, refusals included, so a retry loop still gets cut off. |
Exceeding any of them is 429 RATE_LIMITED, except the sync interval, which has its
own 429 SYNC_TOO_SOON. A refused request still counts against its tier, so a
validation error in a tight loop burns budget too.
Reading a 429
{
"success": false,
"code": "RATE_LIMITED",
"message": "Too many requests. Retry after 34 seconds.",
"errors": {
"retry_after": 34
}
}
The standard headers are set as well, and are the more convenient thing to read:
Retry-After: 34
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 0
Wait Retry-After seconds and retry the same request. Do not retry immediately, and
do not spread the same burst across more connections — the per-integration tier is keyed on your
integration, not your socket.
Payload caps
| Field | Type | Description |
|---|---|---|
Properties per bulk call
|
integer | 25 entries in properties[]. |
Units per property
|
integer | 50 entries in units[] on a property create or update. |
external_id, units[].external_id
|
string | 128 characters of A-Z a-z 0-9 . _ : -. |
name
|
string | 255 characters. |
description
|
string | 2000 characters. |
Units per booking
|
integer | 20 entries in units[]. |
Adults or children per unit
|
integer | 50 each. |
Snapshot window
|
integer | 92 days per call. |
Snapshot horizon
|
integer | 730 days ahead of today. |
GET /events page size
|
integer | 200 per call. |
GET /bookings page size
|
integer | 200 per call. |
property_ids on a sync
|
integer | 500 ids. |
external_booking_id
|
string | 128 characters. |
notes
|
string | 2000 characters. |
reason, refund_note
|
string | 500 characters each. |
Stay length is capped by the platform rather than by this API; a stay beyond the maximum is
refused on check_out with the limit named in the message.
Webhook side
These are the limits Doorloom holds itself to when calling you.
| Field | Type | Description |
|---|---|---|
Response deadline
|
integer | 10 seconds per delivery, configurable per integration between 1 and 30. |
Connect timeout
|
integer | 5 seconds. |
Delivery attempts
|
integer | 12, on the ladder 1m, 5m, 15m, 30m, 1h, then every 2h. |
Signature tolerance
|
integer | 300 seconds either side of t. |
Secret rotation overlap
|
integer | 24 hours during which both secrets verify. |
Event retention
|
integer | 30 days, which is also the replay window. |
Event horizon
|
integer | 365 days ahead by default, per integration. |
Window per event
|
integer | Never more than one calendar month. |
Designing within the limits
- Do not poll what is pushed. If you subscribe to the calendar events you have no reason to call the snapshot endpoints on a schedule, and 300 requests a minute is generous for everything else.
- Batch your reads.
GET /bookingswithupdated_sinceandper_page=200beats fetching bookings one at a time. - Batch your property loads. Onboarding a portfolio is
POST /properties/bulk, not 200 single creates against a 30-a-minute tier. - Treat a sync as an incident tool, not a routine job.
- Back off on 429 rather than retrying tightly. The limiter is a fixed window; hammering it simply keeps you at zero remaining.
If the limits do not fit your volume