Rate limits
What the API returns when you exceed a limit and how to retry.
When you exceed a limit, the API returns 429 Too Many Requests with a
Retry-After header: the number of seconds to wait before retrying, at least 1.
HTTP/1.1 429 Too Many Requests
Retry-After: 12
Content-Type: application/json
{ "status": 429, "title": "Too many requests" }What is limited
- All requests, per credential or per IP address.
- Storefront purchase writes: checkout, payments, payment receipts, coupons, reviews, cancellations, and returns have a lower limit than reads.
- Authentication:
POST /and sending sign-in codes.connect/ token - Admin bulk operations: imports, exports, and batch updates run one at a
time per store. If you send another before the previous one responds, you get
429.
Retry
Wait for the time in Retry-After and send the request again. Cap the number
of attempts.
async function withRetryAfter(request: () => Promise<Response>, maxAttempts = 4) {
for (let attempt = 1; ; attempt += 1) {
const response = await request();
if (response.status !== 429 || attempt === maxAttempts) return response;
const seconds = Number(response.headers.get("retry-after") ?? "1");
await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
}
}Retrying a 429 is safe: the rejected request did not run. If several
processes share credentials, use a shared queue so they don't all retry at
once.
An accepted import returns 202 with the id of an operation that runs in the
background. Track it with GET /; uploading the file again
creates another import.
Use fewer requests
- Request large pages:
limit=200on cursor lists. - Cache data that rarely changes, such as categories, brands, or zones.
- Use webhooks instead of polling.
Last updated: