Rate Limits

API rate limits, headers, and error handling for rate-limited requests.

Rate Limits

All API requests are rate-limited per API key using a sliding window. Limits vary by endpoint category:

CategoryLimitEndpoints
Videos5 req/min/videos/*
Images10 req/min/images/*
Voiceovers10 req/min/voiceovers/*
Ad Library3 req/min/ad-library/scrape
Reads60 req/minAll GET endpoints

Rate Limit Headers

Every response includes rate limit headers:

HeaderDescription
X-RateLimit-LimitMaximum requests per window
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when the window resets

Handling Rate Limits

When rate limited, you'll receive a 429 Too Many Requests response with a Retry-After header:

JSON
{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded. Try again in 30 seconds."
  }
}

Best Practices

  • Check X-RateLimit-Remaining before making requests
  • Use the Retry-After header to wait before retrying
  • Implement exponential backoff for retries
  • Use idempotency keys to safely retry failed requests
  • For bulk operations, space requests evenly within the rate window
async function fetchWithRetry(url: string, options: RequestInit, maxRetries = 3) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const response = await fetch(url, options);

    if (response.status === 429) {
      const retryAfter = parseInt(response.headers.get('Retry-After') || '30');
      await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      continue;
    }

    return response;
  }
  throw new Error('Max retries exceeded');
}