Rate Limits
Hostex applies rate limiting at three layers to keep the service stable
for everyone. Exceeding a limit returns HTTP 200 with error_code: 429
in the body and a Retry-After header (in seconds).
Layer 1 — Per-token (user) limit
Applies to all v3 endpoints combined, keyed on your access token.
| Window | Max requests |
|---|---|
| 1 minute | 1,200 |
| 5 minutes | 12,000 |
| 1 hour | 20,000 |
| 24 hours | 100,000 |
These four are checked in parallel — you hit 429 as soon as any one
is breached.
Layer 2 — Per-token + per-endpoint limit
Applies to one endpoint at a time, keyed on (access token, request path).
| Endpoint pattern | 1 min | 5 min | 1 h | 24 h |
|---|---|---|---|---|
POST /v3/availabilities | 120 | — | — | — |
POST /v3/listings/* (prices / inventories / restrictions / calendar) | 120 | — | — | — |
POST /v3/reservations | 60 | — | — | — |
| All other endpoints | 600 | 6,000 | 10,000 | 50,000 |
A dash means that window is not enforced for that pattern (the user-level
limit still applies).
Layer 3 — Per-thread throttle on POST /conversations/{id}
POST /conversations/{id}Sending a message to a guest is throttled per thread (independent of your
access token), because OTAs aggressively rate-limit channel-side message
APIs and Hostex must shield the channel account from suspensions:
| Window | Max messages per thread |
|---|---|
| 5 seconds | 5 |
| 60 seconds | 10 |
| 30 minutes | 30 |
| 2 hours | 60 |
| 24 hours | 120 |
All five are checked in parallel. Plan templates and HostGPT auto-replies
accordingly.
Response on rate-limit hit
HTTP/1.1 200 OK
Retry-After: 60
X-RateLimit-Scope: user # or "endpoint"
X-RateLimit-Window: 1m
X-RateLimit-Reason: user rate limit exceeded: 1200 requests per 1m
{"error_code":429,"error_msg":"Too Many Attempts.","request_id":"RT..."}
For Layer 3 (message throttle) the body explicitly tells you when to retry:
{"error_code":429,"error_msg":"Too many requests. Try again in 60 seconds.","request_id":"RT..."}
How to stay under the limit
- Always send a meaningful
User-Agent— e.g.MyCleaningApp/1.2.3 ([email protected]). It helps Hostex bypass IP-level bot defences
and lets the on-call team contact you about behaviour issues. - Cache dictionary endpoints aggressively.
GET /custom_channels,
GET /income_items,GET /expense_items,GET /income_methods,
GET /expense_methods,GET /tags,GET /groupschange rarely —
refresh once an hour at most, not on every reservation create. - Batch where possible.
POST /listings/pricesaccepts a list — one
call per listing-day-range, not per day. - Add jitter on retry. When you get
429, exponential backoff
starting at theRetry-Aftervalue, plus ±25% random jitter, prevents
thundering-herd against the next window. - Don't tail webhooks with polling. Subscribe to
Webhooks instead of polling
GET /reservationsevery minute — the events arrive in < 5 s. - Use
idfilters when querying after a write. Re-querying a single
record viaGET /reservations?id=…is far lighter than re-pulling the
whole list to find the one you just changed.
What is not a rate-limit
| Error | Looks like 429 but isn't |
|---|---|
420 Subscription expired / Basic edition | Account-level issue. Do not retry — the host must take action in the portal. |
429 Too many attempts. from /oauth/authorizations | OAuth brute-force guard, not the user-level rate limit. Stop attempting for 10 minutes after >10 failed exchanges. |
