Rate limits
The partner API allows 300 requests per minute per app. The limit is counted per app — not per credential, per merchant or per source address — so an app serving fifty merchants shares one budget across all of them.
Headers
Section titled “Headers”Every partner response carries the current state of your budget.
| Header | Example | Meaning |
|---|---|---|
X-RateLimit-Limit | 300 | Requests allowed in the window |
X-RateLimit-Remaining | 287 | Requests left in the current window |
X-RateLimit-Reset | 1785312000 | Unix timestamp (seconds) when the window rolls over |
The window is fixed, not sliding: the counter resets on the minute boundary, and unused budget does not carry over.
When you exceed it
Section titled “When you exceed it”{ "status": "error", "statusCode": 429, "timestamp": "2026-07-29T09:41:00.052Z", "path": "/v1/items", "message": "Rate limit exceeded. Try again in 14 seconds.", "code": "partner.rate_limited", "correlationId": "5f0e2a71-7c34-4c50-9a2e-b3d1f8c60e29"}Wait for the reset rather than retrying immediately — a retry inside the same window is guaranteed to fail and burns budget you will want when the window turns over.
async function callPartner(request) { for (let attempt = 0; attempt < 3; attempt++) { const response = await fetch(request); if (response.status !== 429) return response;
const reset = Number(response.headers.get('X-RateLimit-Reset') ?? 0) * 1000; const waitMs = Math.max(reset - Date.now(), 1000) + Math.random() * 250; await new Promise((resolve) => setTimeout(resolve, waitMs)); } throw new Error('rate limited after 3 attempts');}Token endpoint
Section titled “Token endpoint”POST https://api-v2.lithospos.com/v1/token is throttled separately at 30 requests per
minute per source address. This is a ceiling for credential-stuffing protection, not a working
budget: a healthy integration mints roughly one token per merchant every fifteen minutes.
Staying under the limit
Section titled “Staying under the limit”- Cache tokens. Reuse a token for its full 900 seconds. See authentication.
- Page in bulk. List endpoints accept
limitup to 100. Pulling 100 rows per call instead of the default 10 cuts a full catalogue sync by an order of magnitude. - Read reports, not rows. For totals,
/v1/reports/*aggregates server-side. Summing individual sales client-side is slower and far more expensive. - Do not poll tightly. Order state changes at human speed. Poll a store’s open orders every 10–15 seconds, not every second.
- Spread bulk work. Catalogue imports and nightly syncs should run at a steady rate with a small delay between calls rather than in one burst.