> ## Documentation Index
> Fetch the complete documentation index at: https://docs.g-tateth.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Rate Limits

Rate limits help ensure fair usage and system stability. Limits are applied per API key based on your subscription plan.

## Rate Limit Tiers

* **Starter/Standard**: 500 requests/hour
* **Professional/Premium**: 5,000 requests/hour
* **Enterprise**: 50,000 requests/hour

## Rate Limit Headers

Every API response includes rate limit information in the headers:

```
X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 4999
X-RateLimit-Reset: 1704067200
```

* `X-RateLimit-Limit`: Your hourly limit
* `X-RateLimit-Remaining`: Requests remaining in the current window
* `X-RateLimit-Reset`: Unix timestamp when the limit resets

## Rate Limit Errors

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

```json theme={null}
{
  "success": false,
  "error": "Rate limit exceeded",
  "code": "RATE_LIMIT_EXCEEDED",
  "retryAfter": 3600
}
```

The `retryAfter` field indicates how many seconds to wait before retrying.

## Per-Key Rate Limits

You can set custom rate limits for individual API keys when creating them:

```json theme={null}
{
  "name": "High Volume Key",
  "rateLimit": {
    "requests": 10000,
    "window": "1h"
  }
}
```

This allows you to have different rate limits for different use cases.

## Best Practices

1. **Monitor your usage** - Check the `X-RateLimit-Remaining` header
2. **Implement exponential backoff** - When you hit rate limits, wait before retrying
3. **Use webhooks** - Instead of polling, use webhooks for real-time updates
4. **Cache responses** - Cache data that doesn't change frequently
5. **Batch requests** - Combine multiple operations when possible

## Handling Rate Limits

### Exponential Backoff

```javascript theme={null}
async function makeRequestWithRetry(url, options, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await fetch(url, options);
      
      if (response.status === 429) {
        const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
        await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
        continue;
      }
      
      return response;
    } catch (error) {
      if (i === retries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
    }
  }
}
```

### Rate Limit Monitoring

```javascript theme={null}
function checkRateLimit(response) {
  const limit = parseInt(response.headers.get('X-RateLimit-Limit'));
  const remaining = parseInt(response.headers.get('X-RateLimit-Remaining'));
  const reset = parseInt(response.headers.get('X-RateLimit-Reset'));
  
  if (remaining < limit * 0.1) {
    console.warn('Rate limit warning: Only 10% remaining');
  }
  
  return { limit, remaining, reset };
}
```
