Appearance
Rate Limiting
The MyWarranties API implements rate limiting to ensure fair usage and protect against abuse.
Rate Limits
By User Role
| Role | Requests | Time Window |
|---|---|---|
| Anonymous | 20 | 1 minute |
| CUSTOMER | 100 | 1 hour |
| SUPPLIER | 200 | 1 hour |
| RESELLER | 200 | 1 hour |
| ADMIN | 500 | 1 hour |
By Endpoint Type
| Endpoint Type | Additional Limit |
|---|---|
| Authentication | 10 per 5 minutes |
| File Uploads | 20 per hour |
| Webhooks | 1000 per hour |
Response Headers
Every API response includes rate limit information:
http
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1709568000| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed in window |
X-RateLimit-Remaining | Requests remaining in current window |
X-RateLimit-Reset | Unix timestamp when limit resets |
Rate Limit Exceeded
When you exceed the rate limit, the API returns:
Status: 429 Too Many Requests
Response:
json
{
"error": "RateLimitError",
"message": "Too many requests. Please try again in 45 seconds.",
"code": "RATE_LIMIT_EXCEEDED",
"details": {
"retry_after": 45,
"limit": 100,
"period": "1 hour"
}
}Headers:
http
HTTP/1.1 429 Too Many Requests
Retry-After: 45
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1709568045Implementation
Rate limiting is based on:
- User ID (for authenticated requests)
- IP Address (for anonymous requests)
- Endpoint (different limits per endpoint type)
Best Practices
Respect Rate Limits
Always check response headers and respect limits:
typescript
async function makeRequest(url: string) {
const response = await fetch(url, {
headers: { 'Authorization': `Bearer ${token}` }
});
// Check rate limit headers
const remaining = parseInt(response.headers.get('X-RateLimit-Remaining'));
const reset = parseInt(response.headers.get('X-RateLimit-Reset'));
if (remaining < 10) {
console.warn(`Only ${remaining} requests remaining`);
}
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get('Retry-After'));
console.log(`Rate limited. Retry in ${retryAfter} seconds`);
await sleep(retryAfter * 1000);
return makeRequest(url); // Retry
}
return response.json();
}Implement Exponential Backoff
typescript
async function fetchWithRetry(
url: string,
maxRetries: number = 3,
baseDelay: number = 1000
) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(url);
if (response.status === 429) {
const retryAfter = parseInt(
response.headers.get('Retry-After') || '60'
);
const delay = retryAfter * 1000;
console.log(`Rate limited. Waiting ${retryAfter}s before retry ${i + 1}/${maxRetries}`);
await sleep(delay);
continue;
}
return response;
} catch (error) {
if (i === maxRetries - 1) throw error;
// Exponential backoff for other errors
const delay = baseDelay * Math.pow(2, i);
await sleep(delay);
}
}
}Batch Requests
Instead of making many individual requests, batch them:
typescript
// Bad: 100 individual requests
for (const productId of productIds) {
await fetch(`/api/products/${productId}`);
}
// Good: 1 batch request
const products = await fetch('/api/products', {
method: 'POST',
body: JSON.stringify({ ids: productIds })
});Cache Responses
Cache API responses to reduce requests:
typescript
const cache = new Map();
async function getCachedProduct(id: number) {
if (cache.has(id)) {
return cache.get(id);
}
const product = await fetch(`/api/products/${id}`).then(r => r.json());
cache.set(id, product);
// Expire after 5 minutes
setTimeout(() => cache.delete(id), 5 * 60 * 1000);
return product;
}Monitoring Rate Limits
Track Usage
typescript
class RateLimitTracker {
private remaining: number = 100;
private limit: number = 100;
private resetAt: number = 0;
updateFromHeaders(headers: Headers) {
this.limit = parseInt(headers.get('X-RateLimit-Limit') || '100');
this.remaining = parseInt(headers.get('X-RateLimit-Remaining') || '0');
this.resetAt = parseInt(headers.get('X-RateLimit-Reset') || '0');
}
getPercentageRemaining(): number {
return (this.remaining / this.limit) * 100;
}
getSecondsUntilReset(): number {
return Math.max(0, this.resetAt - Math.floor(Date.now() / 1000));
}
shouldWait(): boolean {
return this.remaining < 5; // Wait if less than 5 requests remaining
}
}Display to Users
typescript
function RateLimitIndicator({ tracker }: { tracker: RateLimitTracker }) {
const percentage = tracker.getPercentageRemaining();
const color = percentage > 50 ? 'green' : percentage > 20 ? 'yellow' : 'red';
return (
<div>
<div style={{ color }}>
API Quota: {tracker.remaining}/{tracker.limit}
</div>
{tracker.shouldWait() && (
<div>
Rate limit low. Resets in {tracker.getSecondsUntilReset()}s
</div>
)}
</div>
);
}Increasing Limits
Contact support to request higher rate limits:
- Email: support@my-warranties.nl
- Subject: Rate Limit Increase Request
- Include: Use case, expected request volume, account email
Webhook Rate Limits
Webhooks have separate, higher limits:
| Webhook Type | Limit |
|---|---|
| Email Inbound | 1000/hour |
| General | 500/hour |
Webhook rate limits are per source IP, not per user.
Related
- Error Codes - Rate limit errors
- Authentication - Auth endpoints limits
- Pagination - Reduce requests with pagination
