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

# Rate Limits

> Per-minute throughput limits, measured in credits.

Rate limits are measured in **credits per minute**, not requests per minute.

This matters. An Enterprise Bundle call does 35× the work of a single-topic lookup, so it consumes 35× the rate limit budget. A plan with a 300 credits/minute limit allows any of:

* 300 single-topic calls per minute, or
* 20 Standard Bundle calls per minute, or
* 8 Enterprise Bundle calls per minute, or
* any mix summing to 300 credits

| Plan         | Credits per minute |
| ------------ | ------------------ |
| Starter      | 300                |
| Professional | 1,200              |
| Enterprise   | Custom             |

<Note>
  Rate limits and monthly quota are **separate**. You can have plenty of monthly
  credits remaining and still be rate limited if you burst too fast in a single
  minute.
</Note>

## Headers

Every response includes your current rate limit state:

| Header                  | Meaning                                    |
| ----------------------- | ------------------------------------------ |
| `X-RateLimit-Limit`     | Your plan's credits-per-minute ceiling     |
| `X-RateLimit-Remaining` | Credits left in the current minute         |
| `X-RateLimit-Reset`     | Unix timestamp (ms) when the window resets |

## When you hit the limit

You get `429 RATE_LIMIT_EXCEEDED`, and the request is **not charged**.

```json theme={null}
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Credit-per-minute limit exceeded. This request costs 35 credits but only 12 remain in the current window.",
    "docs_url": "https://docs.areahub.com/errors/RATE_LIMIT_EXCEEDED"
  }
}
```

## Handling limits gracefully

<Warning>
  Don't retry immediately on `429`. You'll just burn through the next window
  too.
</Warning>

Read `X-RateLimit-Reset`, wait until that timestamp, then retry. If you're processing a large batch of locations, pace your requests rather than firing them all at once — a steady 250 credits/minute finishes faster than bursting to 300 and getting throttled.

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

  def fetch_with_backoff(lat, lng, api_key):
      while True:
          r = requests.get(
              "https://api.areahub.com/v1/bundle/enterprise",
              params={"lat": lat, "lng": lng},
              headers={"X-API-Key": YOUR_API_KEY},
          )
          if r.status_code != 429:
              return r

          reset_ms = int(r.headers["X-RateLimit-Reset"])
          wait = max(0, (reset_ms / 1000) - time.time()) + 0.5
          time.sleep(wait)
  ```

  ```javascript Node.js theme={null}
  async function fetchWithBackoff(lat, lng, apiKey) {
    while (true) {
      const res = await fetch(
        `https://api.areahub.com/v1/bundle/enterprise?lat=${lat}&lng=${lng}`,
        { headers: { "X-API-Key": YOUR_API_KEY } },
      );
      if (res.status !== 429) return res;

      const resetMs = Number(res.headers.get("X-RateLimit-Reset"));
      const wait = Math.max(0, resetMs - Date.now()) + 500;
      await new Promise((r) => setTimeout(r, wait));
    }
  }
  ```
</CodeGroup>
