NodeOps
UK

Sandboxes

Core CRUD and lookup for sandbox microVMs.

At a glance

  • Base URL: https://api.sb.createos.sh
  • Auth: X-Api-Key: <token> header. Get a token
  • Response envelope: JSend, {"status": "...", "data": ...}

Sandbox status lifecycle

A sandbox moves through these statuses:

StatusDescription
creatingSpawn in progress
runningActive; can exec and transfer files
pausingSnapshot in progress
pausedSnapshotted to storage; host freed
resumingRestoring from snapshot
forkingBundle copy in progress (source stays paused)
errorResume/fork exhausted retries; POST /resume to retry
destroyingDelete in progress
destroyedPermanently gone
failedTerminal failure

POST /v1/sandboxes

Create a new sandbox. Typical time to interactive (create plus first command) is ~210 ms median, ~250 ms p95.

Auth required: Yes

Request body

FieldTypeRequiredDescription
shapestringYesVM shape. See GET /v1/shapes for the catalog. Example: s-1vcpu-256mb
rootfsstringNoRootfs catalog name. Omit for host default. See GET /v1/rootfs. Disabled names are rejected with 400.
namestringNoUser-facing VM name, unique per user among non-terminal sandboxes. Auto-generated (<adjective>-<animal>) if omitted. Used as hostname and in-network DNS name.
disk_mibintegerNoDisk size in MiB. 0 = shape default (10 GiB).
ssh_pubkeysstring[]NoOpenSSH public keys for SSH gateway access. Required for createos sandbox tunnel / createos sandbox shell (alias createos sb …).
envsobjectNoEnvironment variables exported into every exec. Keys must match ^[A-Za-z_][A-Za-z0-9_]*$. Up to 64 entries, 4 KiB per value, 64 KiB total. Values are never returned by GET, only key names.
ingress_enabledbooleanNoWhen true, sandbox is reachable at <ulid>-<port>.<domain>. Off by default.
networksobject[]NoPrivate networks to join at create time. Each entry: {"id": "<name|net-ulid>"}.
disksobject[]NoS3 disks to mount. Each entry: {"disk_id": "<name|id>", "mount_path": "/mnt/data", "sub_path": "optional/prefix"}. Disk must be pre-registered via POST /v1/disks.
egressstring[]NoOutbound allowlist. Each entry is host[:port], ip[:port], cidr[:port], or *. Omit / empty / ["*"] = allow all.
auto_pause_after_secondsintegerNoPause after this many seconds of inactivity (no exec, file transfer, or tunnel). Range: 60-86400. Null/omitted = never auto-pause.
host_idstringNoPin to a specific host. 503 if the host can't fit the VM.
regionstringNoPlacement region. Must match the control plane's configured region; mismatched values return 400.

Note: bandwidth_quota_bytes is not settable at create time; every sandbox starts with the cluster default (5 GiB). Use POST /v1/sandboxes/{id}/bandwidth/recharge to grow the budget.

Example request

Bash
1curl -X POST https://api.sb.createos.sh/v1/sandboxes \
2 -H "X-Api-Key: $CREATEOS_API_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "shape": "s-1vcpu-1gb",
6 "rootfs": "devbox:1",
7 "name": "my-sandbox",
8 "ingress_enabled": true,
9 "auto_pause_after_seconds": 600,
10 "ssh_pubkeys": ["ssh-ed25519 AAAA..."],
11 "envs": { "ANTHROPIC_API_KEY": "sk-ant-..." },
12 "egress": ["pypi.org", "1.1.1.1:53"]
13 }'

Example response

JSON
1{
2 "status": "success",
3 "data": {
4 "id": "sb-01K...",
5 "name": "my-sandbox",
6 "ip": "192.168.0.12",
7 "shape": "s-1vcpu-1gb",
8 "rootfs": "devbox:1",
9 "vcpu": 1,
10 "mem_mib": 1024,
11 "disk_mib": 10240,
12 "spawn_ms": 87.4,
13 "egress": ["pypi.org", "1.1.1.1:53"],
14 "bandwidth_quota_bytes": 5368709120
15 }
16}

Notable errors: 400 invalid body or disabled rootfs, 503 no host capacity.


GET /v1/sandboxes

List sandboxes owned by the caller (paginated).

Auth required: Yes

Query parameters

ParameterTypeDefaultDescription
limitinteger50Max results per page (maximum 500)
offsetinteger0Pagination offset
statusstringFilter by status. One of: running, creating, destroyed, failed

Example request

Bash
1curl "https://api.sb.createos.sh/v1/sandboxes?status=running&limit=10" \
2 -H "X-Api-Key: $CREATEOS_API_KEY"

Example response

JSON
1{
2 "status": "success",
3 "data": {
4 "data": [
5 {
6 "id": "sb-01K...",
7 "name": "my-sandbox",
8 "status": "running",
9 "ip": "192.168.0.12",
10 "vcpu": 1,
11 "mem_mib": 1024,
12 "disk_mib": 10240,
13 "shape": "s-1vcpu-1gb",
14 "rootfs": "devbox:1",
15 "region": "eu",
16 "ingress_enabled": true,
17 "auto_pause_after_seconds": 600,
18 "created_at": "2026-06-17T08:00:00Z"
19 }
20 ],
21 "pagination": {
22 "total": 1,
23 "limit": 10,
24 "offset": 0,
25 "count": 1
26 }
27 }
28}

GET /v1/sandboxes/{id}

Get details for a single sandbox.

Auth required: Yes

Path parameters

ParameterDescription
idSandbox id (sb-<ulid>)

Example request

Bash
1curl https://api.sb.createos.sh/v1/sandboxes/sb-01K... \
2 -H "X-Api-Key: $CREATEOS_API_KEY"

Example response

JSON
1{
2 "status": "success",
3 "data": {
4 "id": "sb-01K...",
5 "name": "my-sandbox",
6 "status": "running",
7 "ip": "192.168.0.12",
8 "vcpu": 1,
9 "mem_mib": 1024,
10 "disk_mib": 10240,
11 "shape": "s-1vcpu-1gb",
12 "rootfs": "devbox:1",
13 "region": "eu",
14 "ingress_enabled": true,
15 "bandwidth_ingress_bytes": 1048576,
16 "auto_pause_after_seconds": 600,
17 "envs": ["ANTHROPIC_API_KEY"],
18 "ssh_pubkeys": ["ssh-ed25519 AAAA..."],
19 "egress": ["pypi.org"],
20 "created_at": "2026-06-17T08:00:00Z",
21 "running_at": "2026-06-17T08:00:01Z",
22 "paused_at": null,
23 "last_resumed_at": null,
24 "forked_from": null
25 }
26}

Notable errors: 404 sandbox not found.

envs returns only the key names; values are never exposed via the API.


PATCH /v1/sandboxes/{id}

Partially update a sandbox. Only fields you include are changed.

Auth required: Yes

Path parameters

ParameterDescription
idSandbox id

Request body

FieldTypeRequiredDescription
ingress_enabledbooleanNoToggle public ingress on or off
auto_pause_after_secondsintegerNoNew idle-pause timeout. Range: 60-86400. Omit to leave unchanged.
disable_auto_pausebooleanNoSet true to turn off auto-pause entirely. Takes precedence over auto_pause_after_seconds when both are sent.

Example request

Bash
1curl -X PATCH https://api.sb.createos.sh/v1/sandboxes/sb-01K... \
2 -H "X-Api-Key: $CREATEOS_API_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{"ingress_enabled": false, "auto_pause_after_seconds": 1800}'

Example response

Returns the full updated SandboxView object (same shape as GET).

Notable errors: 400 invalid values, 404 not found.


DELETE /v1/sandboxes/{id}

Destroy a sandbox permanently.

Auth required: Yes

Path parameters

ParameterDescription
idSandbox id

Example request

Bash
1curl -X DELETE https://api.sb.createos.sh/v1/sandboxes/sb-01K... \
2 -H "X-Api-Key: $CREATEOS_API_KEY"

Example response

JSON
1{
2 "status": "success",
3 "data": {
4 "id": "sb-01K...",
5 "status": "destroying"
6 }
7}

Idempotent: deleting an already-destroyed sandbox returns the same shape with status: "destroyed". A fresh delete returns "destroying" and completes within a few seconds.

Notable errors: 404 not found.


GET /v1/sandboxes/by-ip/{ip}

Look up a sandbox by its VM IP address.

Auth required: Yes

Path parameters

ParameterDescription
ipVM IP address (e.g. 192.168.0.12)

Example request

Bash
1curl https://api.sb.createos.sh/v1/sandboxes/by-ip/192.168.0.12 \
2 -H "X-Api-Key: $CREATEOS_API_KEY"

Example response

Returns a SandboxView object (same shape as GET /v1/sandboxes/{id}).

Notable errors: 404 no sandbox found with that IP.

100,000+ Builders. One Platform.

Get product updates, builder stories, and early access to features that help you ship faster.

NodeOps is the agentic operating system for production AI. CreateOS is its flagship product.