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

# Rate limits

> How Croma rate limits work: per-organization buckets shared across keys, plan quotas, the headers that report your usage and how 429 responses behave.

## Credits

Every organization holds a plan that includes a monthly number of **credits**,
and every request spends credits according to what it costs to serve:

| Request                                                                                              | Credits |
| ---------------------------------------------------------------------------------------------------- | ------- |
| [Live request](/live-lookups): a country or global endpoint that queries the source when you call it | 10      |
| [Dataset request](/datasets): an endpoint answered from Croma's own tables (its guide says so)       | 1       |

| Plan     | Price | Credits / month |
| -------- | ----- | --------------- |
| Free     | \$0   | 5,000           |
| Hobby    | \$20  | 20,000          |
| Standard | \$99  | 100,000         |

[Batch requests](/batch) spend credits **per item**: a 10-item batch of live
requests spends 100. Cached hits (`X-Cache: HIT`) spend the same as a miss.
Failed requests spend nothing, and job status polls never spend credits.

Credits reset on the plan's monthly date and are managed from the
[console](https://platform.usecroma.com/billing). Contracts carry their own
monthly number.

## Per-organization buckets

Rate limits are enforced **per organization**, not per key. Every key issued to
the same org shares one allowance, so adding keys doesn't multiply it.

A few endpoints carry an hourly ceiling on top of the plan allowance, and job
polling draws from a bucket of its own:

| Bucket             | Limit        | Endpoints                                                                               |
| ------------------ | ------------ | --------------------------------------------------------------------------------------- |
| Extract & Generate | 60 / hour    | [Extract](/guides/global/extract), [Generate](/guides/global/generate).                 |
| Web Search         | 10 / hour    | [Web Search](/guides/global/web-search).                                                |
| Research           | 10 / hour    | [Research](/guides/global/research).                                                    |
| Job polling        | 600 / minute | [`GET /jobs/:id`](/async-jobs). Its own bucket, so polling never spends your allowance. |

The hourly ceilings are additional, not separate: a Research call spends one of
its 10 hourly slots **and** 10 credits from your plan.

Each endpoint's page notes its limit.

## Quota in response headers

Rate-limit state comes back as HTTP headers on every response (not in the
body):

| Header                  | Meaning                                                                                                                                                                                                                                                     |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `X-RateLimit-Limit`     | The window's size: your plan's credits on data endpoints, the hourly ceiling where one applies.                                                                                                                                                             |
| `X-RateLimit-Remaining` | Credits (or requests, in an hourly window) left before you're throttled.                                                                                                                                                                                    |
| `X-RateLimit-Reset`     | ISO timestamp when the window resets.                                                                                                                                                                                                                       |
| `RateLimit-Policy`      | The window's policy as an IETF `RateLimit-Policy` field, e.g. `"credits";q=5000;w=2592000`. Endpoints with an hourly ceiling list both policies. Present on every response, including `401` and `429`, so a client can read the limits before it has a key. |

## Retries and idempotency

Every Croma operation is a lookup: repeating a request with the same body
returns the same result and never creates or changes a record, so retrying
after a timeout or a dropped connection is always safe. Send an optional
`Idempotency-Key` header (any string up to 255 characters, a UUID works) and
the API echoes it back in the `Idempotency-Key` response header, so you can
tie a retry to its first attempt in your logs. Each attempt that reaches the
API counts against the quota above; a `429` tells you to wait for
`Retry-After` seconds rather than retry immediately.
\| `X-Request-Id` | Unique id for the request (`req_…`); include it in support reports. |
\| `X-Cache` | `HIT` or `MISS` on cacheable endpoints. Cached hits still count against your quota. |

## When the credits are spent

A request your remaining credits cannot cover returns `402` with a `billing_error`
envelope. Upgrade from the console, or wait for the reset in
`X-RateLimit-Reset`:

```json theme={"dark"}
{
  "error": {
    "type": "billing_error",
    "code": "plan_limit_reached",
    "message": "Your plan has no credits left for this period. Upgrade at https://platform.usecroma.com/billing or wait until 2026-10-01T00:00:00.000Z."
  }
}
```

## When you exceed an hourly ceiling

Requests over an hourly ceiling return `429` with a `rate_limit_error`
envelope and a `Retry-After` header (seconds):

```json theme={"dark"}
{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limited",
    "message": "Rate limit exceeded. Try again in 42 seconds."
  }
}
```

```
Retry-After: 42
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 2026-05-23T18:00:00.000Z
```

Back off until `Retry-After` elapses (or `X-RateLimit-Reset`), then retry.

<Note>
  The limiter **fails open**: if the rate-limit backend is briefly unavailable,
  requests are allowed through and no `X-RateLimit-*` headers are emitted.
  Don't depend on the headers always being present.
</Note>

<Card title="Next: Errors" icon="triangle-exclamation" href="/errors">
  The error envelope and every error code.
</Card>
