Skip to main content

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

TierRequests/MinuteRequests/HourRequests/Day
Standard601,00010,000
Premium3005,00050,000
UnlimitedNo limitNo limitNo limit
Contact your account manager to upgrade your rate limit tier if needed.

Rate Limit Headers

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:
Retry-After: 35

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.