Adrasis™

Rate limits & usage

Operational request measurement for partners and how to handle rate limiting and backoff, including when to partition stalled SEARCH_TIMEOUT batches.

Operational request measurement

The Distribution Partner API measures availability and pricing traffic on a per-request basis for capacity planning and abuse detection. The unit is a request, not the number of properties, allocations, or slots returned.

Request Included in measured compute
POST /properties/availability Yes. One unit per request for 1..200 unique properties and an exact top-1 result per property, with or without max_offers_per_property.
POST /places/availability Yes. One unit per request, whatever the mode. In catalogue order a request prices one page of at most 100 access-visible properties. With sort, filters or near, the first request builds the result set and is still one unit. It accepts at most 10,000 visible properties and prices at most 1,000 after ruling out unavailable properties; property-level filters can narrow the search. Each later page, order change or filter change reads the kept set and is one more unit.
POST /properties/{property_public_id}/offers/search Yes. The room count records only the rooms in best_allocation, as in bulk search. Returning a longer room_offers list does not increase that count.
POST /availability/check Yes. One unit per request (single-tuple gate trace).
GET /properties, GET /properties/{public_id} No. Content reads are not part of measured compute.
POST /prebook, POST /book No. These are part of completing a booking, not pricing lookups.
GET /bookings, GET /bookings/{public_id}, cancellation-quote, cancel No.

Two consequences worth designing around:

  • Batch property comparison. A single POST /properties/availability may carry up to 200 unique property_ids and is still one unit. It returns the exact winner for each property, and with max_offers_per_property the cheapest offers of each. Use the single-property detail route when a caller needs every room product of one property; it returns the best allocation and all room products. Neither route accepts max_offers, limit, or alternative breadth fields.
  • Cache content freely. Property catalogue reads are not measured, so build and refresh your local catalogue from GET /properties (with updated_since delta sync) as often as you need. See Property content.

Rate limiting

Planning Partner API capacity

Before adding sales channels or increasing Partner API traffic, confirm the request policy applicable to each operation with your Adrasis account contact. The policy identifies the covered endpoint or shared operation group, account scope, request quantity and time window. Where a budget is shared by a Partner Account, additional credentials or profiles do not create more allowance.

Current controls

The API does not publish a fixed per-credential request ceiling. Traffic is accounted per credential, and abusive patterns can be throttled at the network edge with 429 Too Many Requests, optionally carrying a Retry-After header (seconds). Handle any 429 as follows, regardless of origin:

Booking webhook management has explicit account-level limits: 30 management writes per minute, plus a separate 10-per-minute budget for manual test and retry commands. These application responses use 429 RATE_LIMITED, the normal JSON error envelope, and Retry-After. Reuse the same Idempotency-Key when retrying a rejected webhook command.

Search admission overload is distinct from credential rate limiting. It returns 503 SEARCH_OVERLOADED with Retry-After; honor that value and reduce concurrent search pressure. A detail deadline, or a bulk deadline before any property completes, returns 503 SEARCH_TIMEOUT with the same retry header; branch on code to distinguish the outcomes. Splitting a timed-out batch does not change result semantics; it changes only how the same ordered property IDs are scheduled across requests.

Handling bulk SEARCH_TIMEOUT

SEARCH_TIMEOUT is the only retryable inline bulk-search code. Keep every other row, then retry exactly the timed-out property IDs in their original relative order after bounded backoff. Keep all other search fields unchanged and, for inline timeout rows, set request_time to the first response's request_time. If a retry does not reduce the timeout set, partition the remaining IDs into smaller ordered batches (for example, halves) before the next attempt. Keep partitioning only within an overall retry/time budget; surface IDs still unresolved when that budget expires.

A top-level 503 has no property rows. Honor Retry-After and branch on error.code: reduce concurrent pressure for SEARCH_OVERLOADED; partition the ordered property set for SEARCH_TIMEOUT because that attempt made no row progress. Preserve the original request_time; if it was omitted, choose one new evaluation instant before the first partitioned retry and reuse it across every partition.

Handling 429

  1. Honor Retry-After. When the response carries a Retry-After header (seconds), wait at least that long before retrying.
  2. Back off exponentially. When no Retry-After is present, retry with exponential backoff, for example 1s, 2s, 4s, 8s, capped at a sensible ceiling (e.g. 30s).
  3. Add jitter. Randomize each delay by ±20% so concurrent workers do not retry in lockstep and re-trigger the limit.
  4. Cap retries. Give up after a small number of attempts (e.g. 5) and surface the failure rather than retrying indefinitely.
  5. Smooth your own traffic. Spread bulk searches over time and reuse batched POST /properties/availability calls rather than issuing many small ones in a burst.

Safe to retry

429 is always safe to retry because the request was rejected before any work was done. The booking finalize (/book) carries a mandatory Idempotency-Key, so retrying it after any transient error replays the original result instead of creating a duplicate. The API timeout is 50 seconds. On a transport timeout or 503 BOOKING_TIMEOUT, retry the exact body with the exact same key. See Idempotency.

For the complete status-code table, see Errors.