REST API Overview
The CreateOS Sandbox REST API lets you create, run, and manage microVMs programmatically.
At a glance
- Base URL:
https://api.sb.createos.sh - Auth:
X-Api-Key: <token>header — get a token - Response envelope: JSend —
{"status": "...", "data": ...}
Base URL
https://api.sb.createos.sh
All paths are versioned under /v1.
Authentication
Every request must carry one of these headers:
| Header | Description |
|---|---|
X-Api-Key | Per-user API key. Sandbox ownership is scoped to the authenticated user — GET /v1/sandboxes returns only the caller's VMs. |
X-Auth-Token | Opaque session token validated against the users service. |
X-Access-Token | OAuth-style access token. |
Get your API key at https://createos.nodeops.network/profile.
Bash1curl https://api.sb.createos.sh/v1/whoami \2 -H "X-Api-Key: $CREATEOS_API_KEY"
Response Envelope (JSend)
Every response wraps its payload in a JSend envelope.
Success (2xx)
JSON1{2 "status": "success",3 "data": { ... }4}
Fail (4xx) — validation or not-found
JSON1{2 "status": "fail",3 "data": {4 "shape": "unknown shape: s-bad"5 }6}
Error (5xx) — server fault
JSON1{2 "status": "error",3 "message": "internal error",4 "code": 5005}
Pagination
All list endpoints accept limit and offset query parameters. Paginated responses nest items under data.data[] alongside a pagination block:
JSON1{2 "status": "success",3 "data": {4 "data": [ { ... }, { ... } ],5 "pagination": {6 "total": 42,7 "limit": 50,8 "offset": 0,9 "count": 4210 }11 }12}
| Field | Description |
|---|---|
total | Total rows matching the query, ignoring limit/offset |
limit | Limit applied by the server |
offset | Offset applied by the server |
count | Items in this response (≤ limit) |
Default limit is 50; maximum is 500.
ID Formats
| Resource | Format | Example |
|---|---|---|
| Sandbox | sb_<ulid> | sb_01K… |
| Network | net-<ulid> | net-01k2x… |
| Disk | disk_<ulid> | disk_01KSHT… |
| Template | tpl_<ulid> | tpl_01K… |
Networks and disks can also be referenced by their user-facing name where the spec notes it.
Content Types
| Direction | Content-Type |
|---|---|
| JSON request bodies | application/json |
| File upload body | application/octet-stream |
| File download response | application/octet-stream |
| Streaming exec response | application/x-ndjson |
Streaming (NDJSON)
The exec endpoint supports a streaming mode (?stream=true). The response is HTTP/1.1 chunked transfer with Content-Type: application/x-ndjson — one JSON object per line. The template-logs endpoint also streams NDJSON.
Each ExecStreamEvent line is one of:
| Frame | Shape |
|---|---|
| stdout chunk | {"stdout": "…"} |
| stderr chunk | {"stderr": "…"} |
| heartbeat | {"hb": true} (every 5 s; clients ignore) |
| terminal | {"exit_code": N} — last frame |
| agent error | {"error": "…"} |
Standard HTTP Status Codes
| Code | Meaning |
|---|---|
| 200 | Success |
| 202 | Accepted — async operation in progress (poll via GET) |
| 400 | Bad request / validation error |
| 401 | Missing or invalid auth |
| 402 | Payment required / quota exceeded |
| 404 | Resource not found |
| 409 | Conflict (e.g. sandbox not in correct state) |
| 429 | Rate limited |
| 503 | Service unavailable / no host capacity |
Async operations (pause, resume, fork) return 202 with an X-Poll-After header (suggested seconds before next poll). Poll GET /v1/sandboxes/{id} until status reaches the expected terminal value.
API Sections
- Sandboxes — create, list, get, update, delete
- Execution & Files — run commands, upload and download files
- Pause, Resume & Fork — lifecycle snapshots and cloning
- Networks — private sandbox-to-sandbox networks
- Egress — outbound firewall allowlists
- Disks — S3-backed persistent volumes
- Templates — custom rootfs images built from Dockerfiles
- Bandwidth & Resize — quota management and disk resize
- Catalog & Identity — shapes, rootfs catalog, whoami