Rate Limiting
Understand and work with API rate limits.
The API uses a point-based rate limiting system to ensure fair usage. Rate limits are enforced per account (not per API key).
Rate Limit: 5000 points per hour per account
The limit uses a sliding 1-hour window and applies across all API keys for an account.
Single Resource GET
Retrieving a single resource by ID
1 point
Write Operations
POST, PUT, PATCH, DELETE
3 points
List/Search Requests
Retrieving multiple resources or searching
3 points
Rate Limit Headers
All API responses include headers with current rate limit information:
HTTP/1.1 200 OK
X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 4994
X-RateLimit-Reset: 1704070800
X-RateLimit-Limit
- Total points allowed per hourX-RateLimit-Remaining
- Points remaining in current windowX-RateLimit-Reset
- Unix timestamp when the rate limit resetsRate Limit Exceeded
When you exceed the rate limit, the API returns a 429 Too Many Requests
response:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1704070800
Retry-After: 3600
Response body:
{
"error": "rate_limit_exceeded",
"message": "Too many requests. Please retry later.",
"retry_after": 3600
}
Retry-After
header indicates how many seconds to wait before retrying.Best Practices
Handle Rate Limits Gracefully
Always check for 429 responses and implement exponential backoff when retrying requests.
Monitor Your Usage
Track the X-RateLimit-Remaining
header to avoid hitting limits.
Optimize List Requests
Use pagination with reasonable page sizes. Fetching 50 items costs 26 points, while fetching 100 items costs 51 points.
Cache When Possible
Cache responses on your end to reduce API calls, especially for data that doesn't change frequently.
Example: Handling Rate Limits
Here's an example of handling rate limits with exponential backoff:
async function apiRequest(url, options = {}) {
const maxRetries = 3;
let retryCount = 0;
while (retryCount < maxRetries) {
const response = await fetch(url, {
...options,
headers: {
'Authorization': `Bearer ${API_KEY}`,
...options.headers
}
});
// Check rate limit headers
const remaining = response.headers.get('X-RateLimit-Remaining');
const reset = response.headers.get('X-RateLimit-Reset');
console.log(`Rate limit remaining: ${remaining}`);
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
const waitTime = retryAfter ? parseInt(retryAfter) * 1000 : Math.pow(2, retryCount) * 1000;
console.log(`Rate limited. Waiting ${waitTime}ms before retry...`);
await new Promise(resolve => setTimeout(resolve, waitTime));
retryCount++;
continue;
}
return response;
}
throw new Error('Max retries exceeded');
}