EDistribution API

Rate limits#

Every authenticated request is rate limited, and every response tells you where you stand — not just the ones that get rejected.

The budget#

Requests per minute600
Burst100

It is a token bucket: the bucket holds at most burst tokens and refills continuously at per-minute ÷ 60 per second. Each request spends one.

In practice you can fire 100 requests back to back, then sustain 10 per second while it refills.

Your account can be configured with its own limits. Read X-RateLimit-Limit rather than assuming 600 it is on every response, so there is no reason to hardcode.

Scope: per credential#

The bucket is keyed on the API credential — not on your account, and not on your IP.

That is a useful property rather than an incidental one. Issue a separate key per deployment — production, staging, the nightly catalogue sync — and each gets its own full budget. A runaway batch job then cannot starve your live booking path. See multiple keys.

The bucket is shared across all endpoints, and nothing is exempt — including GET /v1/ping. Do not use /v1/ping as a high-frequency health check.

The headers#

Three headers on every authenticated response, throttled or not.

X-RateLimit-Reset is a Unix timestamp, not a duration — the instant the bucket is full again.

When you are throttled you also get Retry-After, in seconds, reflecting your account's real refill rate. Honour it rather than using a fixed delay: a client that retries on a hardcoded 1 second will simply be rejected again.

Response headers
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 412
X-RateLimit-Reset: 1785312000
429
{
  "status": 429,
  "error": "Too Many Requests",
  "message": "Rate limit exceeded",
  "path": "/v1/listings",
  "timestamp": "2026-07-29T13:05:56.198280408Z"
}

Staying under it#

The endpoints are bulk-shaped for this exact reason. A loop is almost always the wrong answer:

Instead ofDo
One GET /v1/listings/{id} per listingOne GET /v1/listings?listingIds=… — up to 100
One availability call per nightOne call with from/to — up to 365 days
Polling GET /v1/bookings/{id} after bookingPass a callbackUrl and be told once
Re-syncing the whole catalogue nightlyupdatedSince — only what changed

A full catalogue sync costs a handful of requests. The same sync written as a loop over ids costs one per listing and will be throttled.

The billing-run throttle#

POST /v1/invoices has its own, much tighter limit — roughly a couple of runs per minute, on a bucket keyed on the account rather than the credential. Issuing more keys does not buy more runs.

A run takes an exclusive lock on your billing, which is why it is bounded. A rejected run is 429 with a Retry-After and a message naming the wait:

A billing run for this agent group was requested too recently. Retry in 27s. A run is expensive and takes an exclusive lock on the group's billing, so it is deliberately bounded; the scheduled run covers the ordinary case.

You rarely need this endpoint. Billing runs on your cycle automatically. It exists for closing a period early, not for routine use. See running billing on demand.

Next#

Errors covers the retry policy 429 fits into.