Rate Limits
The Doppel API implements rate limiting to ensure fair usage and maintain service stability. Rate limits are applied per API key.
Rate Limit Tiers
| Tier | Requests/Minute | Requests/Hour | Requests/Day |
|---|
| Standard | 60 | 1,000 | 10,000 |
| Premium | 300 | 5,000 | 50,000 |
| Unlimited | No limit | No limit | No limit |
Contact your account manager to upgrade your rate limit tier if needed.
Every API response includes headers showing your current rate limit status:
X-RateLimit-Limit-Minute: 60
X-RateLimit-Remaining-Minute: 45
X-RateLimit-Limit-Hour: 1000
X-RateLimit-Remaining-Hour: 823
X-RateLimit-Limit-Day: 10000
X-RateLimit-Remaining-Day: 9156
Rate Limit Exceeded Response
When you exceed a rate limit, you’ll receive a 429 Too Many Requests response:
{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded"
},
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2024-01-15T10:30:00.000Z"
}
The response will also include a Retry-After header indicating how many seconds to wait:
Handling Rate Limits
Basic Retry Logic
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || 60;
console.log(`Rate limited. Waiting ${retryAfter}s...`);
await new Promise(r => setTimeout(r, retryAfter * 1000));
continue;
}
return response;
}
throw new Error('Max retries exceeded');
}
Exponential Backoff
For more robust handling, implement exponential backoff:
async function fetchWithExponentialBackoff(url, options) {
const maxRetries = 5;
let delay = 1000; // Start with 1 second
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
const waitTime = retryAfter ? retryAfter * 1000 : delay;
console.log(`Rate limited. Waiting ${waitTime}ms...`);
await new Promise(r => setTimeout(r, waitTime));
delay *= 2; // Double the delay for next retry
continue;
}
return response;
}
throw new Error('Max retries exceeded');
}
Best Practices
1. Cache Responses
Cache API responses when possible to reduce the number of requests:
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
async function getClinics(apiKey) {
const cacheKey = 'clinics';
const cached = cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return cached.data;
}
const response = await fetch('https://api.getdoppel.ai/api/v1/clinics', {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
const data = await response.json();
cache.set(cacheKey, { data, timestamp: Date.now() });
return data;
}
2. Batch Requests
Instead of making many small requests, use pagination efficiently:
# Instead of 100 requests with limit=1
curl "https://api.getdoppel.ai/api/v1/interactions?limit=1"
# Make 1 request with limit=100
curl "https://api.getdoppel.ai/api/v1/interactions?limit=100"
3. Monitor Your Usage
Check the rate limit headers in each response to monitor your usage and adjust your request patterns accordingly.
4. Use Webhooks (Coming Soon)
For real-time data, consider using webhooks instead of polling the API repeatedly.