Rate Limiting | Orwel Docs
Docs

Rate Limiting

Understand rate limits and how to handle them

Overview

To ensure fair usage and system stability, Orwel implements rate limiting on all API requests. Rate limits are applied per API key.

Rate Limits

Production Keys

1,000 requests per minute

Suitable for production workloads and high-traffic applications

Development Keys

100 requests per minute

Perfect for testing and development environments

Rate Limit Headers

Every API response includes rate limit information in the headers:

http
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1642252800
X-RateLimit-Limitinteger

Maximum number of requests allowed in the current window

X-RateLimit-Remaininginteger

Number of requests remaining in the current window

X-RateLimit-Resetinteger

Unix timestamp when the rate limit resets

Rate Limit Exceeded

When you exceed the rate limit, you'll receive a 429 Too Many Requests response:

json
{
  "error": "rate_limit_exceeded",
  "message": "Too many requests. Please try again later.",
  "retry_after": 60
}

The response also includes a Retry-After header indicating how many seconds to wait before retrying.

Best Practices

Monitor Rate Limit Headers

Always check the X-RateLimit-Remaining header to know how many requests you have left. Implement logic to slow down requests as you approach the limit.

javascript
const response = await fetch('https://api.orwel.io/api/v1/leads');
const remaining = response.headers.get('X-RateLimit-Remaining');

if (remaining < 10) {
  console.warn('Approaching rate limit!');
}
Implement Exponential Backoff

When you receive a 429 response, wait before retrying. Use exponential backoff to gradually increase wait times.

javascript
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 retryAfter = response.headers.get('Retry-After');
    const delay = retryAfter ? parseInt(retryAfter) * 1000 : Math.pow(2, i) * 1000;
    
    await new Promise(resolve => setTimeout(resolve, delay));
  }
  
  throw new Error('Max retries exceeded');
}
Batch Requests

Instead of making many individual requests, batch your operations when possible. For example, use pagination to fetch multiple items in a single request.

javascript
// ❌ Bad: Multiple requests
for (let i = 0; i < 100; i++) {
  await fetch(`/api/v1/leads/${ids[i]}`);
}

// ✅ Good: Single paginated request
const response = await fetch('/api/v1/leads?limit=100');
Cache Responses

Cache API responses when appropriate to reduce the number of requests. Use ETags or implement your own caching strategy.

javascript
const cache = new Map();

async function fetchWithCache(url) {
  if (cache.has(url)) {
    return cache.get(url);
  }
  
  const response = await fetch(url);
  const data = await response.json();
  cache.set(url, data);
  
  return data;
}

Monitoring Usage

Track your API usage in the Orwel dashboard:

  1. Navigate to Settings, then API Keys
  2. View usage metrics for each key
  3. Monitor rate limit violations
  4. Set up alerts for high usage

Increasing Limits

If you need higher rate limits for your production workload:

  1. Contact Support

    Email support@orwel.io with your use case (see Support)

  2. Provide Details

    Include your workspace ID and expected request volume

  3. Review

    Our team will review your request within 24 hours

Enterprise plans include higher rate limits by default. Contact us to learn more.

Example Implementation

Here's a complete example with rate limit handling:

javascript
class OrwelClient {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.baseUrl = 'https://api.orwel.io/api/v1';
  }
  
  async request(endpoint, options = {}) {
    const url = `${this.baseUrl}${endpoint}`;
    const headers = {
      'Authorization': `Bearer ${this.apiKey}`,
      'Content-Type': 'application/json',
      ...options.headers
    };
    
    const response = await fetch(url, { ...options, headers });
    
    // Check rate limit
    const remaining = parseInt(response.headers.get('X-RateLimit-Remaining'));
    if (remaining < 10) {
      console.warn(`Rate limit warning: ${remaining} requests remaining`);
    }
    
    // Handle rate limit exceeded
    if (response.status === 429) {
      const retryAfter = parseInt(response.headers.get('Retry-After'));
      throw new Error(`Rate limit exceeded. Retry after ${retryAfter} seconds`);
    }
    
    return response.json();
  }
  
  async getLeads(params = {}) {
    const queryString = new URLSearchParams(params).toString();
    return this.request(`/leads?${queryString}`);
  }
}

// Usage
const client = new OrwelClient('your_api_key');

try {
  const leads = await client.getLeads({ limit: 50 });
  console.log(leads);
} catch (error) {
  console.error(error.message);
}