# Rate limits

Four numbers to design against, and the one that matters more than the rest.

Source: https://docs.leadarc.io/rate-limits.html

## Buckets

Per key, per minute. Every endpoint shows its bucket in the reference.

| Bucket | Limit | What lands here |
| --- | --- | --- |
| `read` | 120 / minute | Every GET served from our database |
| `write` | 60 / minute | Every POST, PUT, PATCH and DELETE |
| `upstream` | 10 / minute | Anything calling out to EmailBison or a calendar: campaigns, campaign tags, campaign insights, event type slots, meetings, `expand=campaign` |

## Requests at once

At most **4 requests in flight per key**. Over that is [`429 too_many_concurrent`](errors.html#status-429).

> **This is the limit that matters most.**
>
> The per-minute numbers protect the month. This one protects the next thirty seconds. Keep your worker pool at 4 and you will never hit it.

## Headers

```http
x-ratelimit-limit: 120
x-ratelimit-remaining: 114
x-ratelimit-reset: 1785312060      # unix seconds when the window resets
x-api-browser-access: disabled     # no CORS on this API
retry-after: 23                    # on a 429 only
```

Watch `x-ratelimit-remaining` and slow down before it hits zero.

## What counts

- A request counts even if the handler then fails. The work was still done.
- A request rejected for a missing scope does not count, so you get a clear 403.
- An invalid key never reaches the counter.
- One call can spend from two buckets: `expand=campaign` adds an `upstream` call on top of the `read`.
- Counters live in the database, so the limit is the same whichever server answers.

## If you need more

Limits are not raised per key. In order: page with `limit=200` instead of 50, filter on the server instead of pulling and discarding, cache what does not change every minute, then talk to us.

---

Base URL `https://api.leadarc.io/v1`. Generated from the API source.
