Rate limits
Every route has its own ceiling, expressed in requests per minute per IP address. Reads are generous, writes less so, and sensitive operations — the ones that hand out a secret — are deliberately tight.
Ceilings in force
| Call type | Ceiling | Examples |
|---|---|---|
| Reading a list or a record | 120 / min | GET /v1/entities, GET /v1/campaigns |
| Ordinary write | 10 to 30 / min | POST /v1/entities, PUT /v1/entities/{id} |
| Sending a message | 60 / min | POST /v1/notifications/emails |
| Sensitive operation | 5 / min | creating or rotating an API key |
On top of that sits a global ceiling of 1,000 requests per minute per IP, across all endpoints, which bounds the total however your calls are spread.
The counter is per IP address: two servers calling the API do not penalise each other. Several of your own processes behind the same network exit, on the other hand, share one counter.
Going over
Past the ceiling, the API answers 429 Too Many Requests:
{ "error": "Too many requests, slow down" }
The bucket refills continuously rather than in one go at a fixed time: after a 429, a few seconds of waiting is enough to earn credit back. Exponential backoff — wait 1 s, then 2, then 4 — is the right answer; looping straight away only sustains the refusal.
The API does not return X-RateLimit-* headers. Remaining quota cannot be read, so handle
the 429 when it arrives instead of trying to anticipate it.
Good practice
- Prefer a paginated list over unit calls in a loop: one
GETof 100 records costs one request, a hundredGETs cost a hundred. - Listen to webhooks rather than polling the API to spot a change.
- Spread bulk work (imports, syncs) instead of firing it all at once.