Overview
All API endpoints are rate-limited to protect service stability. Limits are applied per authenticated user (or per IP address for unauthenticated requests). Limits reset on a rolling window basis.
When a rate limit is exceeded the server responds with HTTP 429 Too Many Requests.
Check the
Retry-After header for the number of seconds to wait before retrying.
Limits by Endpoint Category
| Category | Applies To | Limit | Window |
|---|---|---|---|
| Default | All authenticated API endpoints not listed below | 100 requests | 1 minute |
| Auth endpoints |
/api/auth/login, /api/auth/register,
/api/auth/refresh, /api/mfa/*
|
10 requests | 15 minutes |
| Mutation endpoints |
POST / PUT / PATCH / DELETE on resource endpoints
(/api/inventory, /api/listings, /api/offers, etc.)
|
30 requests | 1 minute |
| Expensive operations |
/api/ai/*, /api/reports/*,
/api/inventory/import, /api/batch-photo/*
|
10 requests | 1 minute |
Rate Limit Headers
Every API response includes the following headers so clients can track their current usage.
| Header | Description | Example |
|---|---|---|
X-RateLimit-Limit |
Maximum requests allowed in the current window for this endpoint category | 100 |
X-RateLimit-Remaining |
Requests remaining in the current window | 73 |
X-RateLimit-Reset |
Unix timestamp (seconds) at which the window resets | 1741900800 |
Retry-After |
Seconds to wait before retrying. Present only on 429 responses. | 47 |
Handling 429 Responses
When your client receives a 429 response:
- Read the
Retry-Afterheader — it tells you exactly how long to wait. - Do not immediately retry — this will only extend your blocked window.
- Implement exponential backoff for automated clients.
- Log the event; repeated 429s suggest the integration needs throttling.
Example 429 response body:
{
"error": "Too Many Requests",
"message": "Rate limit exceeded. Try again in 47 seconds.",
"retryAfter": 47
}
Example retry logic (JavaScript):
async function apiRequest(method, path, body, retries = 3) {
const res = await fetch('/api' + path, {
method,
headers: { 'Content-Type': 'application/json' },
body: body ? JSON.stringify(body) : undefined
});
if (res.status === 429 && retries > 0) {
const wait = parseInt(res.headers.get('Retry-After') || '60', 10) * 1000;
await new Promise(resolve => setTimeout(resolve, wait));
return apiRequest(method, path, body, retries - 1);
}
return res.json();
}
Automated bots and marketplace automations (Playwright) are subject to the same limits.
Respect the platform-specific delays documented in your automation configuration.
Unauthenticated Requests
Requests made without a valid Authorization JWT header are rate-limited by IP address.
Only public endpoints (health check, status, OAuth callbacks) are accessible without authentication.
All other endpoints return 401 Unauthorized.