Rate Limiting

Understand and work with API rate limits.

The API uses a point-based rate limiting system to ensure fair usage. Rate limits are enforced per account (not per API key).

Rate Limit: 5000 points per hour per account

The limit uses a sliding 1-hour window and applies across all API keys for an account.

Single Resource GET

Retrieving a single resource by ID

1 point

Write Operations

POST, PUT, PATCH, DELETE

3 points

List/Search Requests

Retrieving multiple resources or searching

3 points

Rate Limit Headers

All API responses include headers with current rate limit information:

HTTP/1.1 200 OK
X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 4994
X-RateLimit-Reset: 1704070800
X-RateLimit-Limit - Total points allowed per hour
X-RateLimit-Remaining - Points remaining in current window
X-RateLimit-Reset - Unix timestamp when the rate limit resets

Rate Limit Exceeded

When you exceed the rate limit, the API returns a 429 Too Many Requests response:

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1704070800
Retry-After: 3600

Response body:

{
  "error": "rate_limit_exceeded",
  "message": "Too many requests. Please retry later.",
  "retry_after": 3600
}
The Retry-After header indicates how many seconds to wait before retrying.

Best Practices

Handle Rate Limits Gracefully

Always check for 429 responses and implement exponential backoff when retrying requests.

Monitor Your Usage

Track the X-RateLimit-Remaining header to avoid hitting limits.

Optimize List Requests

Use pagination with reasonable page sizes. Fetching 50 items costs 26 points, while fetching 100 items costs 51 points.

Cache When Possible

Cache responses on your end to reduce API calls, especially for data that doesn't change frequently.

Example: Handling Rate Limits

Here's an example of handling rate limits with exponential backoff:

async function apiRequest(url, options = {}) {
  const maxRetries = 3;
  let retryCount = 0;
  
  while (retryCount < maxRetries) {
    const response = await fetch(url, {
      ...options,
      headers: {
        'Authorization': `Bearer ${API_KEY}`,
        ...options.headers
      }
    });
    
    // Check rate limit headers
    const remaining = response.headers.get('X-RateLimit-Remaining');
    const reset = response.headers.get('X-RateLimit-Reset');
    
    console.log(`Rate limit remaining: ${remaining}`);
    
    if (response.status === 429) {
      const retryAfter = response.headers.get('Retry-After');
      const waitTime = retryAfter ? parseInt(retryAfter) * 1000 : Math.pow(2, retryCount) * 1000;
      
      console.log(`Rate limited. Waiting ${waitTime}ms before retry...`);
      await new Promise(resolve => setTimeout(resolve, waitTime));
      
      retryCount++;
      continue;
    }
    
    return response;
  }
  
  throw new Error('Max retries exceeded');
}