Skip to content
Reference

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

CodeMeaningWhat to do
200OKSuccess. Read the response body.
201CreatedResource was created. Body holds the new entity.
204No ContentOperation succeeded; no body. Common after deletes.
400Bad RequestValidation or malformed payload. Inspect details.
401UnauthorizedMissing/invalid/revoked API key. Re-mint or re-send.
403ForbiddenAuthenticated but lacking scope or ownership. See details.requiredScope.
404Not FoundResource doesn't exist or your key can't see it. Treat as not-yours.
409ConflictResource already exists or competing operation in progress. Re-fetch state.
422Unprocessable EntityPlan limit or business-rule violation. Read error for the rule.
429Too Many RequestsRate limited. See Rate Limits for backoff.
500Internal Server ErrorOur fault. Retry with exponential backoff; report if persistent.
502 / 503Bad Gateway / UnavailableTransient 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, honor Retry-After.
  • 5xx → retry with jitter, max 3 attempts, then fail.
Errors — Restore Hub API | Restore Hub