# Rate limits

> Recover from transient request-rate limits without confusing them with quota or budget exhaustion.

Canonical guide: <https://api.blackpearl.com/docs/rate-limits>

Raw Markdown: <https://api.blackpearl.com/docs/raw/rate-limits.md>

OpenAPI: <https://api.blackpearl.com/v1/openapi.json>

Rate limits control request pace for one project API key. They are separate from monthly usage quotas, hard cost budgets, credits, and billed capability work.

Every request that successfully authenticates to `/v1` consumes one place in that key's rolling 60-second window. This includes reads, polling, validation failures, idempotent replays, and calls to Usage. Missing, invalid, revoked, and expired credentials do not enter a key's window because no key can be identified.

The deployment default is 120 authenticated requests per 60 seconds per API key. A deployment can configure another limit, so use the policy and live window values returned by the API:

| Response value | Meaning |
|---|---|
| `RateLimit-Limit` | Requests allowed in the current 60-second window. |
| `RateLimit-Remaining` | Requests still available after the current request. |
| `RateLimit-Reset` | Whole seconds until the oldest request leaves the current window. |
| `Retry-After` | On `rate_limit_exceeded` only, the minimum whole seconds to wait before retrying. |

The three `RateLimit-*` headers appear on authenticated success and error responses. `GET /v1/usage` also returns `rate_limit.limit` and `rate_limit.window_seconds` for policy discovery.

The per-minute limit is set by the organization's **usage tier**, which grows automatically with cumulative paid usage and account age. `GET /v1/usage` returns the current tier as `usage_tier` (`key`, `name`, `rank`, `rate_limit_per_minute`, `monthly_cost_cap_usd`). Each tier also carries a monthly spend cap: when it is reached, job creation fails `429 budget_exceeded` with `error.details.scope` of `"usage_tier"` — like budget exhaustion, this is not transient and resets at `error.details.resets_at`.

When request pace is too high, the API returns `429` with `error.code` set to `rate_limit_exceeded`. Wait at least the larger of `Retry-After` and `RateLimit-Reset`, then retry with bounded exponential backoff and jitter. Polling consumes request-rate capacity but does not create or bill another generation run.

`quota_exceeded` and `budget_exceeded` also return `429`, but neither is a transient request-rate failure and neither carries `Retry-After`. Use `error.details.resets_at` and the counters in [Limits, budgets, and usage](https://api.blackpearl.com/docs/usage-quotas) to decide whether to wait for the next UTC month or ask an administrator to change the control. The complete decision table is in [Errors](https://api.blackpearl.com/docs/errors).
