Rate Limiting
To protect the API from overload, the number of requests is limited per minute. The limit is computed using a sliding window.
Every API key has its own limit — there is no shared/global limit. Limits are applied per endpoint group (bucket); usage in one bucket does not affect the others.
Quotas
| Bucket | Default limit | Scope |
|---|---|---|
default | 60 requests / minute | Orders, products, balance, webhooks, VNC, credentials, lifecycle (suspend/unsuspend/terminate) |
services_read | 150 requests / minute | GET /services, GET /services/{id} |
services_status | 300 requests / minute | GET /services/{id}/status (high-frequency polling) |
services_changes | 120 requests / minute | Change endpoints (power, rebuild, password, upgrade) |
Per-bucket increases for large resellers are configured by Rabisu. You can read your
key's effective limits from the rate_limits field of the GET /auth/me response:
"rate_limits": {
"default": 60,
"services_read": 150,
"services_status": 300,
"services_changes": 120
}
Response Headers
Every response returns the current quota state:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Total quota per minute |
X-RateLimit-Remaining | Remaining requests |
X-RateLimit-Reset | Unix timestamp when the quota resets |
Quota Exceeded (429)
When the quota is exceeded, 429 Too Many Requests is returned, and the
Retry-After header tells you how many seconds to wait:
HTTP/1.1 429 Too Many Requests
Retry-After: 42
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1785000000
{
"success": false,
"error": {
"code": "rate_limited",
"message": "Request limit exceeded. Please try again later."
},
"meta": { "trace_id": "...", "timestamp": "..." }
}
Recommendations
- On
429, wait for theRetry-Afterduration and retry with exponential backoff. - Instead of continuously polling service status, use Webhooks where possible — notifications arrive instantly and consume no quota.
- For bulk operations, spread requests over time; do not send hundreds of requests at once.