# Rate limits

> Per-key limits in one-minute windows across three buckets, reported in RateLimit-Policy and RateLimit headers, with Retry-After on a 429.

Limits apply per API key, in fixed one-minute windows. Every request a valid key makes counts against the **overall** bucket — a refused one (`403`) too; some also count against a second one.

| Bucket | Default limit | Counts |
|---|---|---|
| `overall` | 60 requests / minute | Every request |
| `search` | 20 requests / minute | `POST /organizations/match`, `POST /organizations/contacts/match`, `POST /organizations/switchboards/match`, `POST /people/match` |
| `spend` | 5 requests / minute | `POST /contacts/reveal` (dry runs included), and `POST /organizations/match`, `POST /people/match` or `POST /organizations/switchboards/match` when it reveals |

`GET /credits` counts only against `overall`. An `organizations/match`, `people/match` or `organizations/switchboards/match` that reveals (`reveal` set, `dryRun` false) counts against `overall`, `search` and `spend`, also when it is refused (`400` without an `Idempotency-Key`), just as a refused `contacts/reveal` counts against `spend`.

A request counts once however many items it carries, so batching 25 items per request is the way to more throughput. These are starting values; if your integration needs more, tell us at [support@funnelfeedr.com](mailto:support@funnelfeedr.com).

## Headers

Every response to a valid key, errors included, reports the buckets that request counted against, following the IETF [RateLimit header fields draft](https://datatracker.ietf.org/doc/draft-ietf-httpapi-ratelimit-headers/):

```http
RateLimit-Policy: "overall";q=60;w=60, "search";q=20;w=60
RateLimit: "overall";r=41;t=17, "search";r=3;t=17
```

- `RateLimit-Policy`: per bucket, the quota `q` per window of `w` seconds.
- `RateLimit`: per bucket, the requests `r` remaining in this window and the seconds `t` until it resets.

Slow down when `r` gets low rather than waiting for a `429`.

## When you hit a limit

```http
HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
Retry-After: 12
RateLimit-Policy: "overall";q=60;w=60, "spend";q=5;w=60
RateLimit: "overall";r=52;t=12, "spend";r=0;t=12
```

```json
{
  "type": "https://funnelfeedr.com/developers/errors/rate_limited",
  "title": "Rate limit exceeded",
  "status": 429,
  "detail": "Rate limit exceeded for 'spend' (5/min). Retry after 12 seconds.",
  "code": "rate_limited",
  "retryable": true,
  "retryAfterSeconds": 12,
  "traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
}
```

Wait `Retry-After` seconds, then retry. A rate-limited request did nothing: nothing was revealed or charged, so retrying it — with the same `Idempotency-Key` for a spend call — is safe.

Windows are aligned to the clock minute, so a burst at the end of one minute and the start of the next can briefly see up to twice the limit. Don't build on that.
