Rate limits
Per-key and per-IP minute buckets on every endpoint, the 429 response shape, and how a host should back off. SSO has a much higher budget.
Every call is checked against two minute-aligned buckets: one per key and one per IP. The per-key bucket is evaluated first. Exceeding either returns 429 rate_limited.
Limits per endpoint
| Endpoint | Per-key / min | Per-IP / min |
|---|---|---|
platform-create | 60 | 120 |
platform-plan | 60 | 120 |
platform-topup | 60 | 120 |
platform-suspend | 60 | 120 |
platform-unsuspend | 60 | 120 |
platform-terminate | 60 | 120 |
platform-usage | 60 | 120 |
platform-sso | 600 | 1200 |
SSO carries a much higher budget because it is the hot path — it runs on every customer click into the dashboard, while the lifecycle endpoints run on billing events.
The 429 response
{
"error": "rate_limited",
"reason": "per_key",
"retry_after_seconds": 11,
"current_count": 61
}reason is per_key or per_ip, identifying which bucket tripped. The same retry value is also sent on the Retry-After header.
Recommended host behavior
- Respect
Retry-After— wait at least that long before retrying. - Use exponential backoff on repeated 429s rather than a fixed interval.
- Cache
usageresponses for at least 60 seconds instead of polling. - Never cache and replay SSO tokens — mint a fresh one per click.
The limiter fails open
If the rate limiter itself has a transient outage, requests are allowed through rather than blocked. Do not rely on the limiter as a correctness guarantee — keep your own send rates within the limits above.
Idempotency
How each endpoint behaves on retry — which carry an idempotency key, which are idempotent by state, and how to treat a terminated tenant.
Error reference
Every error the Platform API can return, consolidated. Conventional HTTP codes — 5xx are retryable, 4xx are terminal except 429 and the 409 state codes.