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

# Quotas & rate limits

> How billing periods, monthly caps, and rate limits work.

Two distinct mechanisms throttle traffic:

1. **Monthly quota** — a per-Organization cap aligned to your
   contractual billing period.
2. **Rate limit** — a short-window per-key burst limit.

Both surface as `429` RFC 7807 problems, with different `type` URIs
and recovery semantics.

## Monthly quota

Counted in **billable requests** since the start of your current
billing period. The period boundaries come from your contract —
typically the day of the month you signed up.

When exceeded:

```http theme={null}
HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
Retry-After: 1209600
X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1715040000

{
  "type":     "https://errors.attestly.io/quota-exceeded",
  "title":    "Quota Exceeded",
  "status":   429,
  "detail":   "Monthly quota of 10000 requests exceeded for this billing period.",
  "instance": "/v1/evaluate",
  "quota": {
    "limit": 10000,
    "used":  10000,
    "period_started_at": "2026-04-15T00:00:00Z",
    "period_ends_at":   "2026-05-15T00:00:00Z"
  }
}
```

The `quota` block is an RFC 7807 extension member. Headers:

* `Retry-After` — seconds until `period_ends_at`.
* `X-RateLimit-Limit` — the monthly cap.
* `X-RateLimit-Remaining` — `0` while over quota.
* `X-RateLimit-Reset` — Unix timestamp matching `period_ends_at`.

Recovery: wait until `period_ends_at`, or contact us to bump the cap.

## Rate limit

Per-API-key burst protection. Short-window — typically tens of
requests per second.

```http theme={null}
HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
Retry-After: 1
X-RateLimit-Limit: 50
X-RateLimit-Remaining: 0

{
  "type":     "https://errors.attestly.io/rate-limit-exceeded",
  "title":    "Rate Limit Exceeded",
  "status":   429,
  "detail":   "Rate limit exceeded.",
  "instance": "/v1/evaluate"
}
```

Recovery: back off for `Retry-After` seconds and retry. Use
exponential backoff with jitter on persistent 429s.

## What counts as a billable request

| Counts                   | Does not count                |
| ------------------------ | ----------------------------- |
| `POST /v1/evaluate`      | `GET /v1/sources`             |
| `POST /v1/intersections` | `GET /v1/rulesets` (list/get) |
| `POST /v1/distance`      | `POST /v1/rulesets` (create)  |
| `POST /v1/subjects`      |                               |

Catalog reads and ruleset writes do not consume quota.
