Rate limits
Each API key may send 600 requests per rolling minute. The limit protects the service for everyone and is generous for syncs that use bulk endpoints.
Headers
Every response tells you where you stand:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed per rolling 60 seconds for this key |
X-RateLimit-Remaining | Requests left right now |
X-RateLimit-Reset | Unix time (seconds) when the next request slot frees up |
Retry-After | On 429 only: seconds to wait before retrying |
Requests over the limit answer 429 with code rate_limited and are not counted. The MCP server shares the key's budget.
Retrying
Node.js
javascript
async function request(url, init, attempt = 0) {
const res = await fetch(url, init);
if (res.status === 429 && attempt < 5) {
const wait = Number(res.headers.get("retry-after") ?? 1);
await new Promise((r) => setTimeout(r, wait * 1000));
return request(url, init, attempt + 1);
}
if (res.status >= 500 && attempt < 5) {
await new Promise((r) => setTimeout(r, 2 ** attempt * 500));
return request(url, init, attempt + 1);
}
return res;
}Staying well under the limit
- Write in batches:
POST /products/bulktakes up to 500 products per request. - Read in pages of 250 and only what changed:
updated_sinceinstead of full re-reads. - Use
If-None-Matchwhen polling single products — 304 answers are fast (they still count as requests). - Use webhooks instead of polling for changes.
- For whole-catalog files use exports or pull feeds rather than paging through the API.
One budget per key
Limits apply per API key, not per workspace. Give each integration its own key so one busy system cannot starve another.