Limits, quotas, and retention
Requests per minute
Rate limits use a sliding 60-second window and are counted in three independent scopes:
| Scope | Production default | Sandbox |
|---|---|---|
| Origin (IP address), before authentication | 600 per minute | 600 per minute |
| Account | 1,000 per minute | 500 per minute |
| Credential | 300 per minute | 150 per minute |
Successful responses do not include rate limit headers. When a request exceeds a limit, the API returns 429 with a Retry-After header, and the response body reports the state of each scope:
{
"error": {
"code": "rate_limit_exceeded",
"message": "Too many requests.",
"retry_after_seconds": 12,
"blocked_by": ["key"],
"limits": [
{ "scope": "instance", "limit": 1000, "window_seconds": 60, "remaining": 640, "retry_after_seconds": 0 },
{ "scope": "key", "limit": 300, "window_seconds": 60, "remaining": 0, "retry_after_seconds": 12 }
]
}
}In limits, the instance scope is the account limit and the key scope is the credential limit. blocked_by lists the scopes that rejected the request.
A 429 response executes nothing and does not count against the window. Wait retry_after_seconds before you retry, and spread your load over time instead of retrying in bursts. If the rate limiter is unavailable, the API returns 503 rate_limiter_unavailable: it fails closed and never admits a request without counting it.
Higher quotas are arranged with Cademí and apply to the account. A credential can have its own limit, which is always less than or equal to the account limit. GET /account/usage reports consumption per window (1h, 24h, 7d, 30d), per outcome, and per credential, along with the limits in effect.
Request size
| Limit | Value |
|---|---|
| JSON request body | 1 MiB (413 payload_too_large) |
| JSON nesting depth | 16 levels (400 json_too_deep) |
| Items in an array | 1,000 (422 too_many_items) |
| Plain text | 64 KiB per field |
| Rich text | 512 KiB per field |
| Operation batch | Depends on the operation type, up to 1,000 items (422 too_many_items) |
| Open operations per account | 100 in queued or running, counted per environment (operation_backlog_exceeded) |
| File | 5 GiB, always through an upload session |
| IDs in a policy selector | 1,000 |
| Event streams | 5 per credential, 20 per account (429 too_many_streams) |
Retention
What the API stores, and for how long:
| Data | Retention |
|---|---|
Events (GET /events) | 30 days |
| Webhook deliveries and attempts | 30 days |
| Operations and items | 30 days from creation (expires_at) |
Audit trail (/requests, /audit-entries) | 30 days |
| Idempotency receipt | 48 hours |
| Previous policy revisions | 365 days |
| Declarative configuration plans | Until the plan expires |
After the retention period, the record no longer exists: a GET for a pruned event returns 404, and a cursor that points to it returns 410 cursor_expired. If your integration needs a longer history, consume events through webhooks or GET /events and store them on your side.