REST API
Errors
The API uses conventional HTTP status codes and returns a consistent JSON body for every error, with a human-readable message and a stable machine-readable code.
On this page3 sections
Error format#
HTTP
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": "VM not found",
"code": "NOT_FOUND"
}Requests rejected by schema validation additionally include a details array describing each failed field:
HTTP
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "Validation error",
"code": "VALIDATION_ERROR",
"details": [
{
"path": ["name"],
"message": "Required"
}
]
}Error codes#
| HTTP status | Code | Meaning |
|---|---|---|
| 400 | VALIDATION_ERROR |
The request body or parameters are invalid. Check details if present. |
| 401 | AUTHENTICATION_ERROR |
Missing, invalid, expired or revoked API key. |
| 403 | AUTHORIZATION_ERROR |
Authenticated, but not permitted to perform this action. |
| 404 | NOT_FOUND |
The resource doesn’t exist or belongs to a different account. |
| 409 | CONFLICT |
The request conflicts with current state (e.g. duplicate name). |
| 429 | RATE_LIMIT |
Too many requests. Back off and retry after Retry-After seconds. |
| 500 | INTERNAL_ERROR |
Something went wrong on our side. Safe to retry with backoff. |
Individual endpoints may return more specific codes (e.g. SCRIPT_NOT_FOUND). Always branch on the HTTP status first and treat code as a refinement.
Rate limits#
The API allows 600 requests per minute per IP, measured over a sliding window. Every response carries the IETF standard rate-limit headers (draft-ietf-httpapi-ratelimit-headers) so clients can self-throttle in real time. The legacy X-RateLimit-* pair is also sent for older clients.
| Header | Meaning |
|---|---|
RateLimit-Limit |
Maximum requests allowed in the window |
RateLimit-Remaining |
Requests remaining in the current window |
RateLimit-Reset |
Seconds until the quota resets |
RateLimit-Policy |
The quota policy: 600;w=60 means 600 requests per 60-second window |
Retry-After |
Seconds to wait before retrying (on 429 responses only) |
X-RateLimit-Limit / X-RateLimit-Remaining |
Legacy pair, kept for older clients. Prefer the RateLimit-* headers. |
HTTP
HTTP/1.1 429 Too Many Requests
Retry-After: 12
RateLimit-Limit: 600
RateLimit-Remaining: 0
RateLimit-Reset: 12
RateLimit-Policy: 600;w=60
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 0
{
"error": "Too many requests. Try again in 12s.",
"code": "RATE_LIMIT"
}Something unclear or out of date? Tell us