

## How it works [#how-it-works]

In addition to your monthly [quota](/docs/getting-started/quotas), a request-rate limit
applies to each API key. The default ceiling is **100 requests per 60-second window**,
enforced in a sliding window per key.

When you exceed it you receive `429 Too Many Requests`:

```json title="rate limit body"
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Limit: 100 requests per 60 seconds"
  }
}
```

There is no `Retry-After` header — use the `X-RateLimit-*` headers below.

## Response headers [#response-headers]

Responses carry three headers:

| Header                  | Value                                                   |
| ----------------------- | ------------------------------------------------------- |
| `X-RateLimit-Limit`     | The ceiling for the throttle that stamped this response |
| `X-RateLimit-Remaining` | How much of it is left                                  |
| `X-RateLimit-Reset`     | When it resets                                          |

<Callout type="info" title="two throttles, same header names">
  Both the request-rate limiter **and** the monthly quota meter write these headers, with
  different meanings. On a `RATE_LIMIT_EXCEEDED` response they describe the request window
  (`Reset` is seconds). On quota-related responses (success, `403 TIER_REQUIRES_PAID`,
  `429 QUOTA_EXCEEDED`) they describe your monthly units (`Reset` is the period-end
  timestamp, RFC3339). Branch on the `error.code`, not the header shape.
</Callout>

Use `X-RateLimit-Remaining` to implement client-side back-pressure before hitting the limit.

## Higher limits on paid plans [#higher-limits-on-paid-plans]

<Callout type="warn" title="tbd · per-tier ceilings">
  Per-tier request-rate ceilings (Free vs Pro vs Scale, etc.) are defined but not yet
  enforced — the current deployment applies a single configured ceiling globally.

  For now: hitting limits on a paid plan? Email
  [`support@statshawk.ai`](mailto:support@statshawk.ai) and we'll bump you manually.
</Callout>
