- Home
- API reference
- About
- Rate limits
Rate limits
How many requests an API key may make per minute, how to read the limit from the headers, and how to handle and avoid a 429.
Rate limits cap the number of Merchant API requests per key. If you exceed the limit in a minute, the API returns 429 with a Retry-After header.
Current limits
Section titled “Current limits”Every operation of the Merchant API shares one limit per key:
| Environment | Requests per minute, per key |
|---|---|
| Sandbox | 600 |
| Live | 3000 |
- Each key has its own count, so one busy service does not use up the budget of another.
- The count is for each clock minute, and the budget is whole again when the next minute begins.
Retry-Afteris the time that is left of the minute. - Rate limits may change. Changes are announced in the Changelog.
If you think you will need more, contact support.
Read your limit
Section titled “Read your limit”Every response says where you stand:
X-RateLimit-Limit: 600X-RateLimit-Remaining: 597| Header | Meaning |
|---|---|
X-RateLimit-Limit |
How many requests the key may make per minute |
X-RateLimit-Remaining |
How many are left in the current minute |
Retry-After |
On a 429 only: the seconds to wait |
Handle a 429
Section titled “Handle a 429”Over the limit, the API answers 429 with the common error shape and a Retry-After header with the number of seconds to wait:
HTTP/1.1 429 Too Many RequestsRetry-After: 12{ "error": { "type": "rate_limit_error", "code": "rate_limited", "detail": "Too many requests. Please try again later.", "documentation_url": "https://docs.baiyar.com/resources/errors/rate_limited/" }, "meta": { "request_id": "req_…" }}Wait for that many seconds before you send anything else with the key. Spread the retries out instead of sending them all at once, and keep the same Idempotency-Key on a retry of a request that has one.
Retry with a wait
Section titled “Retry with a wait”async function call(url, options, attempts = 5) { for (let attempt = 1; ; attempt++) { const response = await fetch(url, options); if (response.status !== 429 || attempt === attempts) return response; const wait = Number(response.headers.get("retry-after") ?? 1); // a little jitter, so that several workers do not come back together await new Promise((resolve) => setTimeout(resolve, (wait + Math.random()) * 1000)); }}import randomimport time
import requests
def call(method, url, attempts=5, **kwargs): for attempt in range(1, attempts + 1): response = requests.request(method, url, **kwargs) if response.status_code != 429 or attempt == attempts: return response wait = float(response.headers.get("Retry-After", 1)) # a little jitter, so that several workers do not come back together time.sleep(wait + random.random())Wrong keys count too
Section titled “Wrong keys count too”Repeated requests with a wrong key from one address are slowed down as well: after 60 in a minute, that address gets a 429 too, whether or not the key exists.
Avoid hitting the limit
Section titled “Avoid hitting the limit”- Do not poll a payment until it is paid. Register a webhook endpoint and let Baiyar tell you.
- Page through a list once, with the largest
limityou can use, and keep what you read. See Pagination. - Retry a failed request with a growing delay and a limit on the number of tries.
- Use a separate key for each service.
Related pages
Section titled “Related pages”- Authentication
- Idempotency
- Errors: the error
rate_limited