Platform
Rate limits
Anonymous callers get 60 counts an hour and 600 a day. Every response reports your remaining quota in the IETF RateLimit headers, and a 429 says how long to wait.
Limits depend on who you are, and every response tells you where you stand. Anonymous callers get 60 counts an hour and 600 a day per IP.
Free and paid accounts get more, per organisation. The limits protect the counts budget, because a count runs a real query and an order spends credits.
Limits by tier
| Tier | Counts | Other limits | Status |
|---|---|---|---|
| anonymous | 60 an hour and 600 a day per IP and fingerprint | Challenge after 20; at most 6 filters an audience; no single company counts, free text title search or radius under 5 miles; counts under 100 and breakdown cells rounded to the nearest 5 | confirmed |
| free | 60 a minute and 1,000 a day per organisation | Counts under 100 and breakdown cells rounded to the nearest 5 | to confirm |
| paid | Published per plan | Exact counts | confirmed |
The anonymous counts figures are confirmed. The free account figures are to confirm, and paid limits are published per plan.
Every request, whatever it does, is also limited. These request limits are the current build's own and are to confirm.
| Tier | Counts | Any request |
|---|---|---|
| Anonymous, per IP | 60 an hour, 600 a day | 120 a minute |
| Free account, per organisation | 60 a minute, 1,000 a day | 300 a minute |
| Paid, per organisation | 600 a minute | 1,200 a minute |
The headers
Every response carries the IETF RateLimit and RateLimit-Policy fields, errors included. A 429 and a 503 also carry Retry-After.
| Header | Example | Meaning |
|---|---|---|
RateLimit-Policy | "counts-hourly";q=60;w=3600, "counts-daily";q=600;w=86400, "requests";q=120;w=60 | One item for each window that applies to you: its name, the quota q and the window w in seconds |
RateLimit | "counts-hourly";r=59;t=3522, "counts-daily";r=599;t=50322, "requests";r=119;t=42 | One item for each of those windows: the quota remaining r and the seconds until it resets t |
Retry-After | 42 | Seconds to wait before retrying, on 429 and 503 |
Each list holds one item for every window the request is counted against, separated by commas, so read the item by its name. The names are counts-hourly, counts-daily, counts-per-minute and requests. A call that is not counted against the counts budget carries only the requests item.
A 429 returns the rate-limited problem, with retry_after_seconds repeating the header.
What uses the counts budget
An operation spends from the counts budget when it asks the engine about data: counting, previewing and quoting, and every call that looks up a record, whether or not it finds one. That includes suppression checks, enrichment, objections, suppression uploads and CRM overlap checks.
| Call | Extra charge |
|---|---|
Preview with shuffle true | One more unit, and it is logged |
POST /v1/suppressions/check | One more unit for each further 100 ids |
POST /v1/contacts/enrich with no match | A key may make 100 a day. A match costs a credit, which is its own brake |
POST /v1/objections with scope emailmovers | One unit, and at most 200 a day for an organisation |
The catalogue lookups are on purpose outside the counts budget: filter values, title expansion and location resolution. They answer from the catalogue, and a type-ahead calls them on every keystroke. They are still limited by the request limit.
Anonymous controls
Besides the rate limits, an anonymous caller is limited to 6 filters in one audience. The premium filter, contact.premium in [true], is not counted, since the app and a compiled brief add it themselves. Single-company counts, free text title search and a radius under 5 miles need a free account, and the answer is account-required.
Counts under 100 and every breakdown cell are rounded to the nearest 5. See Counts and breakdowns.
Behind a proxy, the client address is read from the right of X-Forwarded-For, never from the left, which the client controls.
Retrying well
- On 429, wait for
Retry-After, then retry. Do not retry sooner. - On 503 or 500, wait for
Retry-Afterif present, otherwise back off with jitter, and retry with the sameIdempotency-Key. - Read
RateLimitbefore a burst, and spread requests across the window. - Cache what you can. A count by id answers
304toIf-None-Matchwithout running the engine, and the catalogue, plans and datasets carry anETag.
Next steps
- See the status codes of every operation in the REST reference.
- Read Errors for
rate-limitedandservice-unavailable.