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

PlanRequests per Hour
Standard1,000
AdminUnlimited

Rate Limit Headers

Every API response includes headers to help you track your rate limit status:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per window
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix 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/json

Handling 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?

  1. Audit your code for unnecessary API calls
  2. Implement caching for data that doesn't change frequently
  3. Batch operations where possible
  4. Use webhooks (coming soon) instead of polling

Need higher limits?

Contact us at support@canetoad.ai to discuss enterprise plans with higher rate limits.