Rate limits
Per-workspace request limits, and how to read them.
Rate limits are per workspace - every API key in a workspace shares them, so creating more keys never raises them. They’re enforced across all of our servers.
What’s limited
| Limit | Applies to | Default |
|---|---|---|
| Workspace-wide | Every /v1 request |
600 per minute |
| Placing calls | POST /v1/calls |
60 per minute |
| Campaign writes | POST /v1/campaigns/:id/contacts, POST /v1/campaigns/:id/run |
60 per minute |
Each limit is a 60-second fixed window. A call-placing request counts toward both the workspace-wide limit and the placing-calls limit.
Reading your limits
Every response to a limited request carries:
| Header | Meaning |
|---|---|
X-RateLimit-Limit |
The limit for this window |
X-RateLimit-Remaining |
Requests left in this window |
X-RateLimit-Reset |
When the window resets (Unix seconds) |
When you hit the limit
HTTP/1.1 429 Too Many Requests
Retry-After: 12
{ "error": "rate limit exceeded - retry in 12s", "code": "rate_limited" }
Back off for the number of seconds in the Retry-After header, then retry.
Repeated requests with an invalid key from one address are also refused with 429 for a minute - check the key rather than retrying.
Concurrency caps (also 429)
Separately, placing a call can return 429 when a concurrent-call cap is reached - either your workspace’s cap or the platform’s:
{ "error": "concurrent-call limit reached for this workspace - retry shortly" }
These aren’t the request-rate limits; they mean too many calls are in flight right now. Retry shortly, or pace your POST /v1/calls calls.
Best practices
- Batch contacts into a single
POST /v1/campaigns/:id/contacts(up to 50,000 rows) instead of many small calls - it replaces the whole list in one request. - Prefer campaigns over a tight loop of
POST /v1/callsfor volume - the dialer paces itself and respects your compliance window. - Watch
X-RateLimit-Remaining, respectRetry-After, and don’t hammer on429. - Send an
Idempotency-KeywithPOST /v1/callsso a retry after a timeout never places a second call.
Next: Scopes →