Pause, Resume & Fork
Snapshot a sandbox to free its host, restore it later, or clone it into a new independent identity.
At a glance
- Base URL:
https://api.sb.createos.sh - Auth:
X-Api-Key: <token>header — get a token - Response envelope: JSend —
{"status": "...", "data": ...}
State preserved on pause
Pausing snapshots the full VM state to object storage:
- Disk — filesystem contents
- Memory — full RAM image (processes, open files, network connections)
- CPU state — exact register values and execution context
The host is freed immediately after the snapshot is uploaded. On resume, the sandbox is restored to a different (or the same) host within ~10–13 s from storage.
POST /v1/sandboxes/{id}/pause
Pause a running sandbox, preserving disk and memory state.
Auth required: Yes
Path parameters
| Parameter | Description |
|---|---|
id | Sandbox id (must be running) |
Returns 202 Accepted with the sandbox in pausing status. Poll GET /v1/sandboxes/{id} until status flips to paused. Typical pause completes in ~3 s for a 1 GiB sandbox. Returns 200 if already paused (idempotent).
The response header X-Poll-After carries the suggested number of seconds to wait before the first poll.
Example request
Bash1curl -X POST https://api.sb.createos.sh/v1/sandboxes/sb_01K.../pause \2 -H "X-Api-Key: $CREATEOS_API_KEY"
Example response (202)
JSON1{2 "status": "success",3 "data": {4 "id": "sb_01K...",5 "status": "pausing"6 }7}
Notable errors: 409 sandbox is not running.
POST /v1/sandboxes/{id}/resume
Resume a paused sandbox.
Auth required: Yes
Path parameters
| Parameter | Description |
|---|---|
id | Sandbox id (must be paused or error) |
Returns 202 Accepted with the sandbox in resuming status. Poll GET /v1/sandboxes/{id} until status flips to running. The server retries on different hosts if the first attempt fails. If all retry attempts are exhausted the row goes to error — POST /resume again to try with a fresh budget.
Returns 200 if already running (idempotent).
Example request
Bash1curl -X POST https://api.sb.createos.sh/v1/sandboxes/sb_01K.../resume \2 -H "X-Api-Key: $CREATEOS_API_KEY"
Example response (202)
JSON1{2 "status": "success",3 "data": {4 "id": "sb_01K...",5 "status": "resuming"6 }7}
Notable errors: 409 sandbox is not paused or in error, 503 no host with capacity.
POST /v1/sandboxes/{id}/fork
Clone a paused sandbox into a new, independent sandbox identity.
Auth required: Yes
Path parameters
| Parameter | Description |
|---|---|
id | Source sandbox id — must be paused |
The server copies the four bundle artifacts from snapshots/<src>/ to snapshots/<new>/ byte-identically (server-side CopyObject). The new sandbox is fully independent:
- Separate sandbox id and IP address
- Separate bandwidth ledger
- Separate placement (may land on a different host)
By default the new sandbox auto-resumes to running. Pass start_paused: true to keep it in paused.
Request body (optional)
| Field | Type | Required | Description |
|---|---|---|---|
start_paused | boolean | No | Keep the new sandbox paused after the bundle copy completes. Default false (auto-resumes to running). |
ssh_pubkeys | string[] | No | SSH public keys to authorize on the new sandbox. |
egress | string[] | No | Outbound allowlist for the new sandbox. |
ingress_enabled | boolean | No | Enable public ingress on the new sandbox. |
Example request
Bash1curl -X POST https://api.sb.createos.sh/v1/sandboxes/sb_01K.../fork \2 -H "X-Api-Key: $CREATEOS_API_KEY" \3 -H "Content-Type: application/json" \4 -d '{"start_paused": true}'
Example response (200)
JSON1{2 "status": "success",3 "data": {4 "id": "sb_01KNEW...",5 "name": "brave-otter-fork",6 "status": "paused",7 "ip": "192.168.0.55",8 "shape": "s-1vcpu-1gb",9 "vcpu": 1,10 "mem_mib": 1024,11 "disk_mib": 10240,12 "forked_from": "sb_01K..."13 }14}
The response carries the new sandbox id under data. The X-Poll-After header indicates how long to wait before polling if you passed start_paused: false and want to confirm the sandbox is running.
Notable errors: 409 source sandbox is not paused.
Polling pattern
All three lifecycle operations are asynchronous. Use this pattern to wait for completion:
Bash1ID="sb_01K..."23# Trigger the operation (e.g. resume)4curl -X POST "https://api.sb.createos.sh/v1/sandboxes/$ID/resume" \5 -H "X-Api-Key: $CREATEOS_API_KEY"67# Poll until running8while true; do9 STATUS=$(curl -s "https://api.sb.createos.sh/v1/sandboxes/$ID" \10 -H "X-Api-Key: $CREATEOS_API_KEY" | jq -r '.data.status')11 echo "status: $STATUS"12 [ "$STATUS" = "running" ] && break13 [ "$STATUS" = "error" ] && { echo "resume failed"; exit 1; }14 sleep 215done