# Rate limits

Requests to this API are counted per Account. Go over the limit and the next request is
answered `429` — immediately, and without consuming Credits. This page is the whole
contract.

## What is counted

**Every request, on every endpoint, in one count per Account.** `POST /v1/predict` and
`POST /v1/validate` share a single count, even though `/v1/validate` consumes no Credits.
The limit bounds how fast you send requests, not how much you spend — a free request still
occupies the service.

Requests are counted **per Account**, not per API Key. Minting or rotating a key does not
give you a fresh count, and a rotated key does not reset it.

## What happens at the limit

The request is refused with **[`429 rate-limited`](/errors/rate-limited)**, whose `type` is
`https://docs.investorliftdata.com/errors/rate-limited`.

- **No Credits are consumed.** The limit is enforced before the call reaches anything that
  charges, so a rate-limited request cannot cost you a Credit — there is nothing to refund
  because nothing was spent.
- **The `Retry-After` header is authoritative — on this `429`.** A `rate-limited` refusal
  carries one, in seconds, and the same value appears as `retry_after` in the response
  body. Wait that long, then send the request again. The other `429`,
  [`spend-cap-exceeded`](/errors/spend-cap-exceeded), is a different limit and carries no
  `Retry-After` at all, so branch on `type` and never on the status alone.
- **Every refusal carries a `trace_id`**, in the body and in the `trace-id` response header.
  Quote it if you contact support at `john@investorliftdata.com`.

Nothing about your Balance, your Account or your Terms acceptance changes because of a
`429`. Retrying after the stated interval is the entire remedy.

## The current limits

These are the current defaults, by Tier:

| Tier | Requests | Window |
|---|---|---|
| No valid API Key | 30 | 1 minute |
| Public | 60 | 1 minute |
| Reseller | 300 | 1 minute |

**An individual Account's Tier may be configured differently from the defaults above, so
treat these numbers as a guide and the `Retry-After` header as the value your client
obeys.** A client that backs off on the header is correct whatever the configured limit is;
a client that hard-codes a number from this table is not.

## Requests without a valid API Key

Requests that arrive with a missing or incorrect API Key are counted too.
They all share one count — a single shared count covering every such request, whoever sent
it. That has a consequence worth stating plainly, because it will surprise you while you
are debugging:

**A burst of requests with a bad or missing key can be answered `429` rather than
[`401 invalid-key`](/errors/invalid-key).** Both are published responses and both mean the
request was refused without charge, but if you are testing credentials and see a `429`, the
answer is to slow down, not to keep retrying a key that is not working. A flood of
unauthenticated requests is not free to serve, so it is not exempt from the limit.

## Handling this in a client

1. Send the request.
2. On `429`, read the `type` member of the body. Only
   [`rate-limited`](/errors/rate-limited) is the limit this page describes;
   [`spend-cap-exceeded`](/errors/spend-cap-exceeded) carries no `Retry-After` and is
   handled on its own page.
3. On `rate-limited`, read the `Retry-After` header — it is a whole number of seconds.
4. Wait that long. Do not retry sooner, and do not retry in a tight loop.
5. Send the request again. An `Idempotency-Key` from the original request is still valid;
   see [Idempotency](/idempotency).

Every error this API can return is listed in the [error reference](/errors), each with
its `type`, its status, and whether Credits were consumed.
