Skip to main content
Boltcall enforces rate limits per API key to ensure fair usage across all customers. Limits vary by plan.

Limits by plan

PlanRate limit
Starter60 requests / minute
Pro300 requests / minute
Ultimate1,000 requests / minute

Rate limit headers

Every API response includes the following headers so you can monitor your current usage:
HeaderDescription
X-RateLimit-LimitMaximum number of requests allowed per minute
X-RateLimit-RemainingNumber of requests remaining in the current window
X-RateLimit-ResetUnix timestamp (seconds) when the limit window resets

429 Too Many Requests

When you exceed the rate limit, the API returns a 429 status with the following body:
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Back off and retry with exponential delay.",
    "status": 429
  }
}
Check the X-RateLimit-Reset header to determine when you can resume sending requests.

Best practices

Implement exponential backoff when retrying after a 429. Start with a 1-second delay and double it on each subsequent retry, up to a maximum of 60 seconds.
  • Cache responses — for read-heavy operations like listing agents or leads, cache results locally for 30–60 seconds rather than polling the API.
  • Use webhooks — instead of polling for state changes (e.g., call completed, lead updated), subscribe to webhook events to receive push notifications.
  • Batch operations — use pagination parameters (limit, page) to retrieve larger datasets in fewer requests.
  • Monitor headers — track X-RateLimit-Remaining proactively and slow down before hitting zero.

Exponential backoff example

Node.js
async function fetchWithBackoff(url, options, maxRetries = 5) {
  let delay = 1000;

  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const response = await fetch(url, options);

    if (response.status !== 429) {
      return response;
    }

    if (attempt === maxRetries) {
      throw new Error('Rate limit exceeded — max retries reached');
    }

    await new Promise((resolve) => setTimeout(resolve, delay));
    delay = Math.min(delay * 2, 60_000);
  }
}