# Rate limits

> The two limits on your API key: a per-second cap that answers HTTP 429, and a per-minute points budget that slows responses down.

Two independent limits apply to your API key. The first caps **bursts** and rejects; the second watches **sustained volume** and slows you down.

| Limit | Measured over | What happens when you exceed it |
| --- | --- | --- |
| Request rate | Each second | HTTP **429**, empty body, `Retry-After` header |
| Points quota | Minutes, per area | The response is **delayed** by up to 5 seconds, never rejected |

## Requests per second

Counted per API key, in one-second windows:

| Requests | Limit |
| --- | --- |
| All endpoints together | **5 per second** |
| `POST /api/v1/domains/search` and `POST /api/v1/domains/bulk-search` | **2 per second**, within the 5 |
| `/api/v1/domains/zones` and everything under it | **20 per second**, a budget of its own that does not use up the 5 |
| `GET /api/v1/domains/info` and `GET /api/v1/products/tlds` | No per-second limit |

A request over the limit gets **HTTP 429** with an empty body and a `Retry-After` header: the whole seconds to wait, at least `1`. Wait that long, then retry. A rejected request costs no quota points.

:::tip[Pace instead of retrying]
Five requests per second is plenty for an integration that works through a queue. If you loop over a list of domains, send them one after another, not all at once, and use `bulk-search` (up to 30 domains per call) instead of one `search` per domain.
:::

## Points quota

On top of the per-second cap, a points budget decides whether your requests are answered at full speed or deliberately slowed down. Nothing is rejected by this limit.

- Each request costs **points**: **1 point** for a lookup — `POST /domains/search`, `GET /domains/info`, `GET /products/info` — and **10 points** for everything else.
- Points are tracked **separately per area** — domains (including name servers, DNSSEC and DNS records), contacts, SSL, hosting, products, orders, balance. Heavy domain searching does not slow your SSL calls.
- Your points **decay continuously, by 20% per minute**.
- Below **200 points** nothing happens at all.
- Above 200, responses are delayed — starting at half a second and rising to a ceiling of **5 seconds**.

In round numbers, per area: from a standing start you can make about **20 write operations or 200 lookups** before any slowdown begins. At a steady pace, about **4 write operations or 45 lookups per minute** stay at full speed indefinitely.

**Every response tells you where you stand**

| Header | Meaning |
| --- | --- |
| `X-Quota-Scope` | Which area this request counted against. |
| `X-Quota-Cost` | What it cost — `1` or `10`. |
| `X-Quota-Used` | Your current total in that area. |
| `X-Quota-Limit` | The threshold where slowing begins (`200`). |
| `X-Quota-Delay` | Seconds of delay applied to this request. `0` means full speed. |
| `X-Quota-Reset` | Seconds until decay brings you back under the threshold. |

:::caution[If `X-Quota-Delay` is not zero, slow down — do not retry harder]
Retrying adds more points and deepens the delay. Watch the header and pace yourself. Two specifics worth knowing:

- `bulk-search` costs **10 points, not 1** — it is a bulk operation, not a lookup. Thirty domains in one `bulk-search` still costs far less than thirty separate `search` calls, so prefer it for lists.
- The TLD catalogue (`/products/tlds`) is **free** — it never costs points. Cache it on your side anyway; it changes rarely.
:::

:::note[Set your client timeout above the delay]
A delayed response is still a successful response. Give your HTTP client a timeout comfortably above 5 seconds plus the time the operation itself takes, or a slowed-down request will look like a failure to your code and tempt it to retry.
:::
