Rate Limits

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-account limit

Applies to all v3 endpoints combined, keyed on your Hostex account
— not on the individual access token. Every token issued under the same
account shares one quota, whether you created it yourself in the dashboard
or it was granted through OAuth. Issuing a second token does not give
you a second allowance.

WindowMax requests
1 minute1,200
10 minutes6,000
1 hour20,000
24 hours100,000

These four are checked in parallel — you hit 429 as soon as any one
is breached.

Per-token cap (opt-in)

On top of the account quota, an individual token can be capped tighter,
per minute and/or per hour. No token has such a cap unless Hostex sets one
— it exists so a single misbehaving integration can be reined in without
throttling every other integration on the same account.

The cap only ever tightens: the account and endpoint limits still apply on
top of it. When a per-token cap is what stopped the request, the response
carries X-RateLimit-Scope: token. If you believe one of your tokens has
been capped, contact support — the value is not readable through the API.

Layer 2 — Per-account + per-endpoint limit

Applies to one endpoint at a time, keyed on (account, route template) —
same account scope as Layer 1.

The key is the route template, not the literal URL: every
POST /v3/conversations/{id} call shares one bucket regardless of which
thread id you pass. Fanning a burst across many ids does not spread it
across many buckets.

Endpoint pattern1 min10 min1 h24 h
POST /v3/availabilities120———
POST /v3/listings/* (prices / inventories / restrictions / calendar)120———
GET /v3/listings/airbnb/price_and_rules (reads Airbnb in real time)120———
POST /v3/reservations60———
All other endpoints6003,00010,00050,000

A dash means that window is not enforced for that pattern (the
account-level limit still applies).

Layer 3 — Per-thread throttle on POST /conversations/{id}

Sending a message to a guest is throttled per thread (independent of both the
account and per-token quotas), because OTAs aggressively rate-limit channel-side message
APIs and Hostex must shield the channel account from suspensions:

WindowMax messages per thread
5 seconds5
60 seconds10
30 minutes30
2 hours60
24 hours120

All five are checked in parallel. Plan templates and HostGPT auto-replies
accordingly.

Layer 4 — Failed-request quota

Separate from the request-count limits above, repeated client errors on
the same endpoint consume their own quota, keyed on (account, route template):

WindowMax failed requests
1 hour500
24 hours2,000

Only 400 (bad request) and 404 (not found) count. These are the two
outcomes that will never succeed if you send the same request again —
so retrying them costs you and Hostex capacity while making no progress.

Deliberately not counted: 401, 403, 420 and 429. In particular a
429 never feeds this quota, so being throttled cannot extend your own
block.

When this quota is what stopped the request, the response carries
X-RateLimit-Scope: endpoint_error and:

{"error_code":429,"error_msg":"Too many failed requests to this endpoint. These requests cannot succeed as sent; fix the request instead of retrying.","request_id":"RT..."}

The quota resets on the fixed window boundary like every other limit, and
successful calls to the same endpoint are unaffected until it is exhausted.
The fix is to correct the request, not to wait and retry — see
Errors for how to tell the two 404 cases apart.


Response on rate-limit hit

HTTP/1.1 200 OK
Retry-After: 60
X-RateLimit-Scope: user            # "user" = account-wide; also "endpoint", "token", "endpoint_error"
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..."}

X-RateLimit-Scope names the one limit with the latest reset time. If
several are breached at once, only that one is reported; clearing it may
immediately reveal the next.

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

  1. 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.
  2. Cache dictionary endpoints aggressively. GET /custom_channels,
    GET /income_items, GET /expense_items, GET /income_methods,
    GET /expense_methods, GET /tags, GET /groups change rarely —
    refresh once an hour at most, not on every reservation create.
  3. Batch where possible. POST /listings/prices accepts a list — one
    call per listing-day-range, not per day.
  4. Add jitter on retry. When you get 429, exponential backoff
    starting at the Retry-After value, plus ±25% random jitter, prevents
    thundering-herd against the next window.
  5. Don't tail webhooks with polling. Subscribe to
    Webhooks instead of polling
    GET /reservations every minute — the events arrive in < 5 s.
  6. Use id filters when querying after a write. Re-querying a single
    record via GET /reservations?id=… is far lighter than re-pulling the
    whole list to find the one you just changed.

What is not a rate-limit

ErrorLooks like 429 but isn't
420 Subscription expired / Basic editionAccount-level issue. Do not retry — the host must take action in the portal.
429 Too many attempts. from /oauth/authorizationsOAuth brute-force guard, not the user-level rate limit. Stop attempting for 10 minutes after >10 failed exchanges.