Using the API
Rate limits
Every API key has a fixed request budget per minute. Budgets are generous for
well-behaved integrations: with ETags, updated_since, and full pages,
a recurring sync rarely spends more than a few requests.
The budgets
| Budget | Limit | Applies to |
|---|---|---|
| Per key | 120 requests / minute | Each pk_live_ key independently |
| Per account | 240 requests / minute | All of an account's keys combined |
Both budgets are enforced in fixed one-minute windows. The values above are defaults; read the response headers for the active per-key budget. Splitting traffic across keys still shares the account budget. Conditional GETs and refused over-budget requests also count toward the window.
Read your remaining budget
Responses that reach the API rate limiter carry its current state (earlier authentication or scope denials may not):
| Header | Meaning |
|---|---|
X-RateLimit-Limit | The per-key budget for the current window |
X-RateLimit-Remaining | Per-key requests left; zero when either the key or account budget refuses the request |
X-RateLimit-Reset | When the window resets (unix seconds) |
Retry-After | On 429 only: seconds to wait before retrying |
When you hit the limit
Over-budget requests fail with 429 and the
standard error envelope, code rate_limited:
HTTP/1.1 429 Too Many Requests
Retry-After: 12
{"error": {"code": "rate_limited", "message": "...", "request_id": "req_..."}}
- On
429: waitRetry-Afterseconds, then retry the same request. - On
5xx: retry with exponential backoff and jitter. - On
409 publish_lock_conflict, wait for the conflicting publish; on423 pim_locked, wait for reconciliation. Other4xxresponses need a corrected request.
Keep syncs nearly free
- Full pages. Ask for
limit=250(the maximum) instead of walking many small pages. - Conditional reads. Send the last
ETagback asIf-None-Match; a304has no response body and tells you nothing changed, but still consumes a request from the rate-limit budget. - Incremental polling. Pass
updated_sinceso unchanged entities never appear in the page at all.
One GET /api/v1/products?limit=250&updated_since=... per resource you mirror is usually the whole poll — see the sync guide for the full pattern.