Skip to content

Authentication

All /api/* requests authenticate with an HTTP token in the Authorization header. Both the Token and Bearer schemes are accepted:

Authorization: Token {{ SuperSpace API Token }}
Authorization: Bearer {{ SuperSpace API Token }}

There are three credential types, all presented the same way. The server resolves which kind it is (session / API key first, then OAuth):

Credential Identity Admin‑capable? OAuth scopes apply? Notes
User API key A user (accesses the accounts that user belongs to) If the key is flagged admin No (bypasses scope checks) Optional IP access list.
System API key An account (system-managed only) If flagged admin No Account comes from the key's bearer — does not require X-Auth-Account; IP must be on the system access list.
OAuth 2.1 access token A user, bound to one (account, brand) Never Yes — fail-closed Issued via the OAuth 2.1 authorization server.

Trial accounts cannot use the API

Authentication rejects any credential resolving to a trial account, for both session/API-key and OAuth tokens.


IP Restriction

You may restrict access by IP to a particular API Key in the SuperSpace API Key Manager. Note that when you attempt to connect from a non-authorized IP, you will receive the same response as if you supplied an invalid API Key.

By default there is no IP restriction in place.


Setting Account Scope

Some API endpoints require an Account Scope. To specify which account you would like to be working under, include the header X-Auth-Account set to your Account ID:

X-Auth-Account: {{ SuperSpace Account ID }}

Behavior:

  • For a user API key, X-Auth-Account scopes the request to a single account and sets the account context. Without it, list endpoints return resources across all accounts the key's user can access.
  • Some endpoints require it and return 400 {"errors":["Missing X-Auth-Account"]} when it is absent — Orders, Carts, Subscriptions, Users, Webhooks, DNS-zone create, and all Domain Registration endpoints.
  • OAuth tokens always carry an account, so the header is ignored for them.

Authentication Failures

A failed authentication returns 401 with the header WWW-Authenticate: Token realm="Application" and an empty body. Causes include no/invalid token, an IP not on the key's access list, a trial account, or an X-Auth-Account value that doesn't match an account the token can access.

OAuth audience binding (RFC 8707)

An OAuth token minted with a resource indicator (e.g. one issued for the MCP server at /mcp) is rejected at /api/* with HTTP 401 and a JSON body — not the empty-body WWW-Authenticate form above:

{ "error": "invalid_token", "error_description": "token audience is not valid for /api" }

/api never issues resource-bound tokens, so any token carrying a resource was minted for a different audience and cannot reach /api.


Conventions

  • All API routes are under /api/. All responses are JSON.
  • Resource IDs are GUIDs, except numeric task IDs, integer volume IDs, integer DNS record-type codes, and numeric domain_contact IDs.
  • Timestamps are ISO 8601, UTC.
  • Async operations return 202 Accepted — poll a task, registrar process, or cart to check completion (see Async Operations).

Pagination

Index endpoints accept page and per_page query parameters.

Param Type Default Notes
page Integer 1 Page number
per_page Integer 50 Records per page, clamped to a max of 100

Rate Limiting

Requests are limited to 600 per 10 minutes, per credential. Exceeding the limit returns 429 with an empty body.


Error Responses

Status When it occurs
400 Missing required header; invalid/no-op params; order & site-resize validation errors (unknown variant/location/term/product); no_default_payment_method; OAuth picker/DCR errors
401 Authentication failed (no/invalid token, IP blocked, trial account, account mismatch); admin-only endpoint with a non-admin credential
402 Service suspended for an unpaid invoice (service_suspended); registrar fee gate (payment_required)
403 Insufficient role ({"errors":["Not Authorized"]}); OAuth scope failure (insufficient_scope); Shield not in plan / premium required
404 Resource not found or not accessible to this token
409 Conflict — Bunny resource not active (cdn_not_active, shield_not_active); registrar process already in flight (registration_busy)
422 Validation failure or permission restriction (e.g. inherited role, reseller-only, resize constraints); billing-settle guard on a freshly created site (billing_settling); cart payment could not be initiated (cart_pay_failed)
429 Rate limit exceeded (600 / 10 min)
502 Upstream failure (Bunny CDN/Shield, or domain registrar)
503 Feature disabled (feature_disabled, the domain-registration flag) or no registrar configured for a TLD (registrar_unavailable)

Feature & plan gating

The only feature flag that gates API endpoints is domain-registration (returns 503 feature_disabled when off). Shield is plan-gated (403 shield_not_in_plan, or shield_premium_required for premium-only writes). CDN/Shield not yet provisioned on Bunny returns 409 (cdn_not_active / shield_not_active).


Async Operations

Most provisioning operations are asynchronous and return 202 Accepted with a reference to poll.

  • Tasks — PHP version changes, backups, restores, restart, site-domain add/remove, cache changes, account-role removal, and account deletion create a Task. Poll GET /api/tasks/:id or GET /api/sites/:site_id/tasks/:id. Task statuses: PENDING, RUNNING, OK, FAILED, CANCELLED, PAUSED.
  • Cartssite creation (POST /api/orders), site resize / plan-change (PATCH /api/sites/:id with plan), and domain orders (POST /api/orders/domain) are polled via the cart, not a task: they return a cart envelope; poll the cart for materialized orders.
  • Registrar processes — domain-registration mutations may open a process; poll it for completion.

Completion Callback

Order creation accepts an optional callback so you receive a webhook when the async work finishes instead of polling:

{ "callback": { "url": "https://your-app.com/webhook", "authorization": "Bearer your-secret" } }

See Callbacks for the full contract.


About Endpoint

SuperSpace offers an 'about' endpoint that provides information about who you are logged in as, as well as information about available resources. It accepts any valid token regardless of OAuth scope.

GET /api/about

Returned Params
  • version: String | Api Version Information
  • logged_in_as: String | Your user ID
  • account_scoped: String | If you authenticated with an account, this is your ID.
  • locations: Array
    • id: String
    • name: String
  • products: Array
    • id: String
    • name: String
    • description: String
  • php: Array | [] when no versions are available
    • id: Integer
    • label: String
    • is_default: Boolean
Example
curl -H "Authorization: Bearer $SUPERSPACE_TOKEN" \
  https://your-instance/api/about