Rate Limiting
Understanding API rate limits and how to handle them
Rate Limiting
To ensure fair usage and system stability, the CaneToad API implements rate limiting on all endpoints.
Current Limits
| Plan | Requests per Hour |
|---|---|
| Standard | 1,000 |
| Admin | Unlimited |
Rate Limit Headers
Every API response includes headers to help you track your rate limit status:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed per window |
X-RateLimit-Remaining | Requests remaining in current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
Example Response Headers
HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 950
X-RateLimit-Reset: 1706789460
Content-Type: application/jsonHandling Rate Limits
When you exceed the rate limit, the API returns a 429 Too Many Requests response:
{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded",
"details": {
"reset_at": 1706789460
}
}
}Best Practices
Monitor Rate Limit Headers
Check the X-RateLimit-Remaining header before making requests:
const response = await fetch('https://api.canetoad.ai/api/v1/companies');
const remaining = response.headers.get('X-RateLimit-Remaining');
if (parseInt(remaining) < 10) {
console.warn('Rate limit almost exhausted!');
}Implement Exponential Backoff
When rate limited, wait before retrying with exponential backoff:
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options);
if (response.status !== 429) {
return response;
}
const resetAt = response.headers.get('X-RateLimit-Reset');
const waitTime = Math.min(
(resetAt * 1000 - Date.now()) || (Math.pow(2, i) * 1000),
60000
);
await new Promise(resolve => setTimeout(resolve, waitTime));
}
throw new Error('Rate limit exceeded after max retries');
}Cache Responses
Reduce API calls by caching responses where appropriate:
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
async function getCachedData(url) {
const cached = cache.get(url);
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return cached.data;
}
const response = await fetch(url);
const data = await response.json();
cache.set(url, { data, timestamp: Date.now() });
return data;
}Use Pagination Efficiently
Request only the data you need using pagination parameters:
# Request smaller pages
curl "https://api.canetoad.ai/api/v1/companies?per_page=25&page=1"Rate Limit Calculator
Use this formula to calculate your optimal request rate:
Max requests per second = Limit / Window seconds
= 1000 / 3600
= ~0.28 requests/second (or ~17 per minute)For bulk data imports, consider using CSV/TSV format with larger per_page values (up to 100) to reduce the number of requests needed.
Bursting
The rate limit uses a sliding window algorithm, which means:
- You can make burst requests as long as you haven't exceeded the limit
- The window slides continuously, not fixed to clock minutes
- Unused capacity doesn't roll over to the next window
Troubleshooting
Consistently hitting rate limits?
- Audit your code for unnecessary API calls
- Implement caching for data that doesn't change frequently
- Batch operations where possible
- Use webhooks (coming soon) instead of polling
Need higher limits?
Contact us at support@canetoad.ai to discuss enterprise plans with higher rate limits.