Errors
- Written for
- + Written for
- Deprecated
- + Deprecated
- Applies to
- + Applies to
Errors
Restore Hub uses standard HTTP status codes and a single, predictable error envelope. Every error response is JSON; even rate-limit and infrastructure errors stay in the same shape.
Response shape
{
"error": "Human-readable summary of what went wrong.",
"details": {
// Optional. Field-level details when relevant
// (e.g. zod validation issues, the missing scope, etc.)
}
}The error string is always present. details is provided for:
Validation errors (Zod issues, malformed JSON)
Scope failures (the required scope is named)
Rate-limit responses (when retry-after info applies)
Some plan-limit responses (current usage, max allowed)
HTTP status codes
Code | Meaning | What to do |
|---|---|---|
| OK | Success. Read the response body. |
| Created | Resource was created. Body holds the new entity. |
| No Content | Operation succeeded; no body. Common after deletes. |
| Bad Request | Validation or malformed payload. Inspect |
| Unauthorized | Missing/invalid/revoked API key. Re-mint or re-send. |
| Forbidden | Authenticated but lacking scope or ownership. See |
| Not Found | Resource doesn't exist or your key can't see it. Treat as not-yours. |
| Conflict | Resource already exists or competing operation in progress. Re-fetch state. |
| Unprocessable Entity | Plan limit or business-rule violation. Read |
| Too Many Requests | Rate limited. See Rate Limits for backoff. |
| Internal Server Error | Our fault. Retry with exponential backoff; report if persistent. |
| Bad Gateway / Unavailable | Transient infra issue. Same retry strategy as 500. |
Authentication errors
401 Unauthorized
{ "error": "Missing or invalid API key." }Causes: no Authorization header, wrong format, key revoked, or key from a deleted account.
403 Forbidden — missing scope
{
"error": "Missing required scope: backups:restore",
"requiredScope": "backups:restore",
"yourScopes": ["servers:read", "backups:read"]
}Mint a new key with the right scope (or edit the existing one). See all scopes.
403 Forbidden — not your resource
{ "error": "You do not own this server." }You authenticated correctly, but the resource you targeted isn't yours. Could also indicate a team-membership issue. Verify the resource ID belongs to your account.
Validation errors
{
"error": "Invalid request body.",
"details": {
"issues": [
{ "path": ["name"], "message": "Required" },
{ "path": ["category"], "message": "Invalid enum value. Expected 'gaming' | 'community' | ..." }
]
}
}Zod-style issue list. Each issue has a path (where the bad value lives) and a human message.
Rate-limit errors
{
"error": "Rate limit exceeded.",
"retryAfterSeconds": 12
}Plus a standard Retry-After header. Full strategy on Rate Limits.
Recommended handling for agents & scripts
401→ re-prompt the user / fail fast. Don't retry blindly.403→ surface the missing scope to the user. Don't try to circumvent.404→ treat the resource as not-yours. Don't crawl.409→ re-fetch and reconcile state.422→ respect the plan rule. Tell the user to upgrade if they want this.429→ exponential backoff, honorRetry-After.5xx→ retry with jitter, max 3 attempts, then fail.