Boltcall enforces rate limits per API key to ensure fair usage across all customers. Limits vary by plan.
Limits by plan
| Plan | Rate limit |
|---|
| Starter | 60 requests / minute |
| Pro | 300 requests / minute |
| Ultimate | 1,000 requests / minute |
Every API response includes the following headers so you can monitor your current usage:
| Header | Description |
|---|
X-RateLimit-Limit | Maximum number of requests allowed per minute |
X-RateLimit-Remaining | Number of requests remaining in the current window |
X-RateLimit-Reset | Unix 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
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);
}
}