Rate Limiting
API calls are subject to rate limiting to ensure service stability and fair usage for all customers.
Current Limits
Rate limits are applied per API token:
| Endpoint Type | Requests | Time Window |
|---|---|---|
| GET requests | 1000 | 5 minutes |
| POST requests | 100 | 5 minutes |
| All requests | 5000 | 1 hour |
Note
These are default limits. Enterprise customers may have custom limits. Contact support for more information.
Rate Limit Headers
Every API response includes headers showing your current rate limit status:
http
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 950
X-RateLimit-Reset: 1623761345| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed |
X-RateLimit-Remaining | Requests remaining in current window |
X-RateLimit-Reset | Unix timestamp when limit resets |
Handling Rate Limits
When you exceed the rate limit, you'll receive a 429 response:
http
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1623761345
{
"error": "Rate limit exceeded. Please retry after 60 seconds.",
"code": "RATE_LIMIT_EXCEEDED"
}Best Practices
1. Implement Exponential Backoff
javascript
async function requestWithBackoff(url, options, maxRetries = 5) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options);
if (response.status !== 429) {
return response;
}
const retryAfter = response.headers.get('Retry-After') || 60;
const delay = Math.min(retryAfter * 1000, Math.pow(2, i) * 1000);
console.log(`Rate limited. Waiting ${delay}ms before retry...`);
await new Promise(resolve => setTimeout(resolve, delay));
}
throw new Error('Max retries exceeded');
}2. Cache Responses
Reduce API calls by caching responses when appropriate:
javascript
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
async function getCachedProduct(productId) {
const cacheKey = `product-${productId}`;
const cached = cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return cached.data;
}
const response = await fetch(`/api/products/${productId}`, {
headers: { 'Authorization': 'Bearer YOUR_TOKEN' }
});
const data = await response.json();
cache.set(cacheKey, {
data,
timestamp: Date.now()
});
return data;
}3. Batch Requests
Instead of making multiple individual requests, batch them when possible:
javascript
// Instead of this:
for (const productId of productIds) {
await getProduct(productId);
}
// Do this:
const products = await getAllProducts();
const needed = products.filter(p => productIds.includes(p._id));4. Monitor Rate Limit Status
javascript
function checkRateLimit(response) {
const remaining = response.headers.get('X-RateLimit-Remaining');
const limit = response.headers.get('X-RateLimit-Limit');
const reset = response.headers.get('X-RateLimit-Reset');
const percentUsed = ((limit - remaining) / limit) * 100;
if (percentUsed > 80) {
console.warn(`Rate limit warning: ${percentUsed.toFixed(1)}% used`);
const resetDate = new Date(reset * 1000);
console.log(`Resets at: ${resetDate.toLocaleTimeString()}`);
}
return {
limit: parseInt(limit),
remaining: parseInt(remaining),
reset: parseInt(reset),
percentUsed
};
}Optimization Tips
- Use Webhooks: Instead of polling for changes, use webhooks for real-time updates
- Filter Results: Request only the data you need using query parameters
- Implement Smart Caching: Cache product data that doesn't change frequently
- Spread Requests: Distribute API calls evenly over time instead of bursts
Rate Limit Errors
If you consistently hit rate limits:
- Review your implementation for inefficiencies
- Consider caching strategies
- Use webhooks instead of polling
- Contact support for limit increases (enterprise customers)
Next Steps
- Implement Webhooks to reduce polling
- Learn about Error Handling
- Read Best Practices