https://<your-control-plane-url>/v1.
Authenticate every request with your organisation API key in the X-API-Key header, or an OIDC bearer token in Authorization: Bearer. See Authentication for details.
POST /v1/sandboxes
Creates a sandbox from a template. The call is synchronous and blocks until a node has acknowledged the sandbox. On success it returns the sandbox record plus a capability token for the data plane — you can start issuing data plane requests immediately. Supply anIdempotency-Key header to make retries safe: a retry with the same key returns the sandbox created by the first successful request instead of creating a second one.
string
required
A template alias (e.g.
node-tools) or an immutable artifact ID
(e.g. sha256:abc...). Aliases resolve to their current artifact at admission
time, so the sandbox is always built from a pinned digest.string
An optional display name unique within your organisation. Must match
^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$. A colliding name fails with 409
rather than silently creating a duplicate — useful as a natural idempotency key.integer
Requested lease length in seconds, measured from now. The installation caps
this at its configured maximum. Omit to use the installation default.
object
Key-value string pairs stored with the sandbox and filterable in
GET /v1/sandboxes. Use them to tag sandboxes with user IDs, job IDs, or
environment names.object
Optional egress policy fixed at create time. You cannot widen it later.
201 Created
Returns a SandboxWithToken object containing the sandbox record and a fresh capability token.
object
required
The created sandbox.
object
required
A capability token ready for data plane requests.
400 malformed request · 401 unauthenticated · 403 forbidden · 404 template not found · 409 name already taken · 429 rate limited · 503 no node capacity (retryable)
GET /v1/sandboxes
Lists your organisation’s sandboxes, most recently created first. All filters are optional and can be combined.string
Filter by state. One of
running, paused, terminated, or failed.string
Exact match on the tenant-assigned name.
string
URL-encoded
key=value pairs joined with &. A sandbox matches when every
pair matches. For example, to filter by team=platform and run=42, pass
metadata=team%3Dplatform%26run%3D42.integer
Page size. Between 1 and 100, default 20.
string
Opaque cursor from a previous page’s
next_cursor. Omit for the first page.200 OK
Sandbox[]
required
Array of sandbox objects matching the filters.
string
Cursor to pass as
cursor on the next request. Absent or null on the last page.GET /v1/sandboxes/
Gets a single sandbox by its ID.string
required
The 24-character sandbox NanoID.
200 OK
Returns the sandbox object described in the create response above.
Error codes: 401 unauthenticated · 404 not found
DELETE /v1/sandboxes/
Terminates the sandbox and releases its node capacity. If the sandbox is paused, its snapshot is also released. The sandbox record remains readable asterminated — it is not purged immediately.
string
required
The 24-character sandbox NanoID.
204 No Content
Error codes: 401 unauthenticated · 404 not found · 409 lifecycle conflict
POST /v1/sandboxes//pause
Pauses a running sandbox by taking a memory snapshot and releasing node capacity. The call returns once the node reports the VM snapshotted; the snapshot uploads to object storage in the background. The response includes arestorable_until field that tells you how long the snapshot remains restorable. The platform refreshes ageing snapshots by default; this timestamp reflects the worst-case window.
string
required
The 24-character sandbox NanoID.
200 OK
Returns the updated sandbox object with state: "paused" and a restorable_until timestamp.
Error codes: 401 unauthenticated · 404 not found · 409 lifecycle conflict (e.g. already paused)
POST /v1/sandboxes//resume
Restores a paused sandbox onto a node. The resumed instance receives a new epoch, so all capability tokens minted against the previous instance are invalidated. This endpoint returns a fresh token alongside the sandbox.string
required
The 24-character sandbox NanoID.
integer
Lease for the resumed instance, measured from now. Omit to use the
installation default.
200 OK
Returns a SandboxWithToken object with the updated sandbox (state: "running", new epoch) and a fresh capability token.
Error codes: 401 unauthenticated · 404 not found · 409 lifecycle conflict · 410 snapshot expired · 429 rate limited · 503 no capacity (retryable)
POST /v1/sandboxes//deadline
Extends the sandbox deadline to now plusdeadline_seconds, bounded by the installation’s maximum configured lease. Use this to keep a long-running sandbox alive without recreating it.
string
required
The 24-character sandbox NanoID.
integer
required
New lease length in seconds, measured from now.
200 OK
Returns the updated sandbox object with the new deadline timestamp.
Error codes: 400 malformed request · 401 unauthenticated · 404 not found · 409 lifecycle conflict
GET /v1/sandboxes//ports
Lists the port exposure records for a sandbox. A port with no record is private by default — it is reachable with a valid capability token but does not admit anonymous traffic. Records exist to make exposure explicit, durable, and auditable.string
required
The 24-character sandbox NanoID.
200 OK
PortExposure[]
required
The sandbox’s port exposure records.
401 unauthenticated · 404 not found
PUT /v1/sandboxes//ports/
Creates or updates the exposure record for a specific port. Settingvisibility to public admits anonymous traffic to that port — an explicit, durable, audited opt-in that defaults off. Setting it to private records the port without widening access. This operation is idempotent: repeating a PUT with the same value re-asserts the record.
The reserved agent port (50000) cannot be given an exposure record.
string
required
The 24-character sandbox NanoID.
integer
required
The port number to expose. Between 1 and 65535. The reserved sandbox agent
port cannot be used.
string
required
Either
public (admit anonymous traffic) or private (capability token
required, which is also the default for any port without a record).200 OK
integer
required
The port number.
string
required
The recorded visibility:
public or private.string
required
The port’s URL:
https://<port>-<sandbox_id>.<domain>.400 malformed request or reserved port · 401 unauthenticated · 404 not found · 409 lifecycle conflict
DELETE /v1/sandboxes//ports/
Removes the exposure record for a port, returning it to the default private state. Any anonymous public traffic to the port stops immediately.string
required
The 24-character sandbox NanoID.
integer
required
The port number whose record should be removed.
204 No Content
Error codes: 401 unauthenticated · 404 not found · 409 lifecycle conflict