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

# Rate Limiting

> Understand the API rate limits and how to handle them in your integration.

## Overview

The FoxReach API enforces rate limits to ensure fair usage and platform stability. Rate limits are applied **per API key** using a sliding window counter.

## Limits

| Plan    | Limit                                   |
| ------- | --------------------------------------- |
| Default | **100 requests per minute** per API key |

## Rate Limit Headers

Every API response includes rate limit information in the headers:

| Header                  | Description                                   |
| ----------------------- | --------------------------------------------- |
| `X-RateLimit-Limit`     | Maximum requests allowed per minute           |
| `X-RateLimit-Remaining` | Requests remaining in the current window      |
| `X-RateLimit-Reset`     | Unix timestamp when the current window resets |

**Example response headers:**

```
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1706140920
```

## Exceeding the Limit

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

```json theme={null}
{
  "error": "Rate limit exceeded",
  "code": "rate_limit_exceeded",
  "details": {
    "limit": 100,
    "reset": 1706140920
  }
}
```

The response also includes a `Retry-After` header indicating how many seconds to wait:

```
Retry-After: 42
```

## Handling Rate Limits

### Retry with Backoff

The simplest approach is to respect the `Retry-After` header:

<CodeGroup>
  ```python Python theme={null}
  import requests
  import time

  def api_request(url, headers):
      response = requests.get(url, headers=headers)

      if response.status_code == 429:
          retry_after = int(response.headers.get("Retry-After", 60))
          time.sleep(retry_after)
          return api_request(url, headers)

      return response
  ```

  ```javascript Node.js theme={null}
  async function apiRequest(url, headers) {
    const response = await fetch(url, { headers });

    if (response.status === 429) {
      const retryAfter = parseInt(response.headers.get("Retry-After") || "60");
      await new Promise((r) => setTimeout(r, retryAfter * 1000));
      return apiRequest(url, headers);
    }

    return response;
  }
  ```
</CodeGroup>

### Monitor Remaining Requests

Proactively slow down when you're approaching the limit:

<CodeGroup>
  ```python Python theme={null}
  remaining = int(response.headers.get("X-RateLimit-Remaining", 100))

  if remaining < 10:
      time.sleep(1)  # Slow down
  ```

  ```javascript Node.js theme={null}
  const remaining = parseInt(response.headers.get("X-RateLimit-Remaining") || "100");

  if (remaining < 10) {
    await new Promise((r) => setTimeout(r, 1000)); // Slow down
  }
  ```
</CodeGroup>

### Batch Operations

Instead of making many individual requests, use pagination efficiently:

```bash theme={null}
# Fetch 100 leads at once instead of one at a time
curl "https://api.foxreach.io/api/v1/leads?pageSize=100" \
  -H "X-API-Key: otr_your_key"
```

## Best Practices

* **Cache responses** when possible to reduce the number of API calls
* **Use webhooks** instead of polling for real-time updates
* **Batch operations** to minimize the number of requests
* **Implement exponential backoff** for retries after rate limit errors
