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

# Rate Limiting

> Understand API rate limits and how to handle them.

# Rate Limiting

The API enforces a rate limit of **300 requests per minute** per API key. Rate limit information is included in every response via HTTP headers.

## Rate Limit Headers

Every API response includes the following headers:

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

## Handling Rate Limits

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

```json theme={null}
{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded. Max 300 requests per minute."
  }
}
```

## Best Practices

<CardGroup cols={2}>
  <Card title="Monitor headers" icon="chart-line">
    Check `X-RateLimit-Remaining` in responses to track your usage before hitting the limit.
  </Card>

  <Card title="Implement backoff" icon="clock-rotate-left">
    When you receive a 429, wait until the `X-RateLimit-Reset` timestamp before retrying.
  </Card>

  <Card title="Batch operations" icon="layer-group">
    Use the bulk add leads endpoint to add multiple leads in a single request instead of one-by-one.
  </Card>

  <Card title="Cache responses" icon="database">
    Cache GET responses locally when data does not change frequently.
  </Card>
</CardGroup>

## Retry Strategy Example

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function apiCallWithRetry(url, options, maxRetries = 3) {
    for (let attempt = 0; attempt < maxRetries; attempt++) {
      const response = await fetch(url, options);

      if (response.status === 429) {
        const resetAt = response.headers.get("X-RateLimit-Reset");
        const waitMs = resetAt
          ? (parseInt(resetAt) * 1000) - Date.now()
          : 60000;
        await new Promise(resolve => setTimeout(resolve, Math.max(waitMs, 1000)));
        continue;
      }

      return response;
    }
    throw new Error("Max retries exceeded");
  }
  ```

  ```python Python theme={null}
  import time
  import requests

  def api_call_with_retry(url, headers, max_retries=3):
      for attempt in range(max_retries):
          response = requests.get(url, headers=headers)

          if response.status_code == 429:
              reset_at = int(response.headers.get("X-RateLimit-Reset", 0))
              wait_seconds = max(reset_at - time.time(), 1)
              time.sleep(wait_seconds)
              continue

          return response
      raise Exception("Max retries exceeded")
  ```
</CodeGroup>

## Webhooks vs Polling

If you are polling the API repeatedly to detect new calls, updated lead statuses, or completed campaigns, consider using **webhooks** instead. Webhooks push events to your server the moment they happen — no quota consumed, no delay.

Register a webhook endpoint once and receive real-time `POST` payloads for every event you care about:

```bash theme={null}
# Register a webhook
curl -X POST \
  https://kdjmltmhxvvmiuehafgl.supabase.co/functions/v1/api-gateway/v1/webhooks \
  -H "Authorization: Bearer rchd_live_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.com/reached-webhook",
    "events": ["call.completed", "lead.updated", "campaign.completed"],
    "secret": "your_signing_secret"
  }'
```

Each delivery includes an `X-Reached-Signature` header (HMAC-SHA256) so you can verify the payload is genuine.

| Approach | Requests consumed | Latency |
| - | - | - |
| Polling every 10 s | \~6 req/min per resource | Up to 10 s |
| Polling every 1 s | \~60 req/min per resource | Up to 1 s |
| **Webhooks** | **0 req/min** | **Real-time** |

Use the REST API for on-demand reads and writes; use webhooks for everything event-driven.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.