Beta This is a new service — your feedback will help us to improve it.

REST API

The DollarBox REST API lets you manage containers, volumes, orgs, members, and kubectl credentials from scripts, CI, or the Terraform provider. Everything the dashboard does for these resources, the API can do too.

The API is versioned in the URL. The current version is v1, served under:

https://app.dollarbox.dev/api/v1/

Breaking changes ship under a new version prefix (/api/v2/); v1 stays stable for existing integrations.

Get a token

The API authenticates with personal API tokens.

  1. Open Account → API tokens in the control panel (https://app.dollarbox.dev/settings/api-tokens/).
  2. Click Create token, give it a name, and choose a scope:
    • Read-onlyGET requests only.
    • Read & write — full access for the token's user.
  3. Optionally restrict the token to a single org, and optionally set an expiry.
  4. Copy the token shown on the next screen. It is displayed only once. If you lose it, revoke it and create another.

If your account has two-factor authentication enabled, you'll be asked to re-authenticate before a token is created.

Send the token as a bearer credential on every request:

curl -H "Authorization: Bearer dbx_xxxxxxxxxxxx_..." \
  https://app.dollarbox.dev/api/v1/containers/

Tokens carry the permissions of the user who created them, constrained by the org's role model (owner / admin / member). Writes additionally require the token's write scope. Revoke a token any time from the same page; revoked or expired tokens are rejected immediately.

Choose an org

Most resources belong to an org. The API resolves the target org in this order:

  1. The token's org, if it was created as org-scoped.
  2. An explicit org slug, via the X-Dollarbox-Org header or the ?org=<slug> query parameter.
  3. Your only org, if you belong to exactly one.

If you belong to several orgs and don't specify one, write requests return an org_required error.

curl -H "Authorization: Bearer $DOLLARBOX_TOKEN" \
  -H "X-Dollarbox-Org: my-org" \
  https://app.dollarbox.dev/api/v1/containers/

Resources

ResourcePathOperations
Containers/api/v1/containers/list, create, read, update, delete
Volumes/api/v1/volumes/list, create, read, delete
Namespaces/api/v1/namespaces/list, create, read, reallocate, delete
Orgs/api/v1/orgs/list, read, update
Members/api/v1/members/list, read, change role, remove
Invitations/api/v1/invitations/list, read, create, revoke
kubectl credentials/api/v1/kubectl-credentials/list, read, create, revoke

A complete, machine-readable description lives in the OpenAPI schema. Browse the full reference — every operation, with field-level request and response detail — here, no sign-in required:

The same schema is served live from the control panel for signed-in users (handy for scripts that pull the spec at runtime):

Provisioning is asynchronous

Creating a container or volume returns immediately with a status of pending; provisioning happens in the background. Poll the resource until its status settles:

# Create a container
curl -X POST https://app.dollarbox.dev/api/v1/containers/ \
  -H "Authorization: Bearer $DOLLARBOX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "web", "image": "nginx:1.27"}'

# Poll until it is running
curl https://app.dollarbox.dev/api/v1/containers/123/ \
  -H "Authorization: Bearer $DOLLARBOX_TOKEN"

A container's name is fixed once created — change other fields in place, but recreate the container to rename it. Volumes are immutable once created; delete and recreate to change size.

kubectl credentials

If an org has kubectl mode enabled, you can issue your own kubeconfig over the API. The kubeconfig (with a freshly bound token) is returned only in the create response:

curl -X POST https://app.dollarbox.dev/api/v1/kubectl-credentials/ \
  -H "Authorization: Bearer $DOLLARBOX_TOKEN" \
  -H "X-Dollarbox-Org: my-org"

Namespaces

By default an org runs in a single Kubernetes namespace. If you build a multi-tenant product on DollarBox, you can carve out isolated child namespaces under the same account — one per end customer, say — each with its own NetworkPolicies, quota, and PodSecurity boundary.

Capacity is one pool: the containers and storage you pay for. Each namespace reserves a slice of that pool via allocated_containers and allocated_volume_gb; the platform namespace gets whatever is left over. The sum of all child allocations may not exceed your paid capacity (you'll get a 409 allocation_exceeded otherwise). New namespaces start at zero allocation, so creating one costs nothing until you move capacity to it.

# Create an isolated namespace with 1 container slot + 5 GB of storage
curl -X POST https://app.dollarbox.dev/api/v1/namespaces/ \
  -H "Authorization: Bearer $DOLLARBOX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"slug": "family-smith", "allocated_containers": 1, "allocated_volume_gb": 5}'

# Reallocate capacity in place
curl -X PATCH https://app.dollarbox.dev/api/v1/namespaces/42/ \
  -H "Authorization: Bearer $DOLLARBOX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"allocated_containers": 2}'

Provisioning is asynchronous (pending → provisioning → active, or failed); poll the resource until status settles. The read-only k8s_namespace field is the real namespace name (org-<id>-<slug>). The slug is fixed once created — recreate to rename. Deleting a namespace tears it down (cascading volumes, load balancers, and secrets) and returns its allocation to the pool.

Volume snapshots

Snapshot protection is explicitly enabled per Longhorn PVC. The add-on costs €0.10 per protected source GB per month.

# Enable daily protection and retain seven successful snapshots
curl -X PUT https://app.dollarbox.dev/api/v1/namespaces/42/volumes/homeserver-data/snapshot-policy/ \
  -H "Authorization: Bearer $DOLLARBOX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"retention_days": 7}'

# Create the one permitted manual snapshot
curl -X POST https://app.dollarbox.dev/api/v1/namespaces/42/volumes/homeserver-data/snapshots/ \
  -H "Authorization: Bearer $DOLLARBOX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "before-upgrade"}'

# Restore a ready snapshot into a new PVC
curl -X POST https://app.dollarbox.dev/api/v1/namespaces/42/volumes/homeserver-data/snapshots/$SNAPSHOT_ID/restore/ \
  -H "Authorization: Bearer $DOLLARBOX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"pvc_name": "homeserver-data-restored"}'

Policy, snapshot, and restore operations are asynchronous. Poll their corresponding GET endpoint until it reaches active, ready, or bound. Disabling a policy is also asynchronous because billing continues until the retained CSI snapshots have been deleted.

Pagination

List endpoints use cursor pagination:

{
  "next": "https://app.dollarbox.dev/api/v1/containers/?cursor=cD0y",
  "previous": null,
  "results": [ ... ]
}

Use ?limit= to set the page size and follow the next URL (or its cursor) to page forward.

Errors

Errors use a stable envelope. The code is a machine-readable string you can switch on; it won't change without a version bump.

{
  "error": {
    "code": "quota_exceeded",
    "message": "This would exceed your plan's limit of 5 containers. You are using 5.",
    "detail": { "resource": "containers", "limit": 5, "current": 5 }
  }
}

Common codes include authentication_failed, permission_denied, not_found, validation_error, quota_exceeded, allocation_exceeded, rate_limited, and api_disabled.

Rate limits

Requests are rate limited per token. When you exceed the limit you'll get a 429 with a Retry-After header (in seconds) and the rate_limited error code. Back off and retry after the indicated delay.

Terraform

The official Terraform provider is built on this API — declare your containers, volumes, namespaces, and org membership as code. A namespace's slug is ForceNew (changing it recreates the namespace), while allocated_containers and allocated_volume_gb update in place. (Provider availability is tracked separately; until it ships, the API above is the supported integration surface.)