Sandboxes
Create, list, inspect, and delete sandboxes.
Sandboxes are isolated micro-VMs created from an image, snapshot, or Dockerfile. Creation is asynchronous: the API returns immediately with status: "pending" and you poll (or long-poll) until running. See Creating Sandboxes for a conceptual guide.
POST /vms
Create a sandbox. Returns immediately; poll GET /vms/:id?wait=running for readiness. The response includes a per-sandbox access_token shown once — store it if you need direct sandbox access (SSH, preview URLs).
Request
| Field | Type | Required / default | Description |
|---|---|---|---|
name | string | generated (sandbox-<8 hex>) | Display name. Not unique per project. |
image | string | object | required | Image name, registry ref ("node:20"), an explicit source object ({"type":"registry","ref":...}, {"type":"named","name":...}, {"type":"dockerfile",...}), or a snapshot source {"type":"snapshot","name":...}. A bare string containing / or : is treated as a registry ref, otherwise as a named image. |
mode | string | "burstable" | "burstable" or "dedicated". See Burstable vs Dedicated. |
cpu | float | 0.125 (burstable) | Guaranteed CPU cores. Burstable: fractional floor, min 0.125. Dedicated: rounded up to a whole core (min 1, max the platform CPU cap of 16; over that is 400). Must be > 0. |
vcpus | int | 2 | Integer CPU request, used only when cpu is absent (cpu wins when both are set). A bare burstable create defaults to the 0.125 cpu floor rather than this value. |
mem_mib | int | 1024 | Guaranteed memory (MiB), ≥ 1. |
scratch_mib | int | 512 | Guaranteed disk (MiB), ≥ 1. |
gpu_host | int | 0 | Number of GPUs to attach. Each is dedicated to the sandbox; you request a count and the platform selects the hardware and a GPU-capable host. Use a CUDA image. Cold-boot only; no pause/resume. See GPU Sandboxes. |
docker_data_mib | int | none | Size (MiB) of a dedicated /var/lib/docker device for Docker-in-sandbox. Fresh per boot, never captured by snapshots. See Docker in Sandboxes. |
ports | array | [] | Ports to expose: { "vm_port": 8080, "proto": "tcp" } (proto defaults to "tcp"). |
volumes | array | [] | Volume attachments: { "volume": "<id-or-name>", "mount_path": "/data", "subpath"?: "..." }. Max 8. See Volumes. |
object_store_mounts | array | [] | Object-store mounts: { "object_store": "<id-or-name>", "mount_path": "/mnt/bucket", "read_only"?: bool }. Max 8. See Object Stores. |
secrets | array of strings | [] | Names of project secrets to attach. Unknown names fail with 400. See Secrets. |
env | object | {} | Environment variables injected verbatim. Names must match [A-Za-z_][A-Za-z0-9_]*; values ≤ 64 KiB. |
persistent | bool | false | Persistent write layer: enables warm stop/start, pause/resume, fork. See Persistent Sandboxes. |
spot | bool | false | Spot tier: discounted, but reclaimable (paused if persistent, deleted if ephemeral). Immutable after create. See Spot Sandboxes. |
egress_policy | object | none | Outbound network allow-list: {"enabled": bool, "allow": [string]} where each allow entry is an IPv4 address, an IPv4 CIDR, or a domain (*. wildcard supported). When enabled, all egress except the allow-list and DNS is blocked. Immutable after create. See Restricting outbound network. |
region | string | resolved default | Target region slug or global region id (world, us, eu, …); a global region is expanded to one of its member regions at create time. Resolution when omitted: project default → org default → platform default. Unknown/disabled regions, or a global region with no active members, fail with 400. |
cpu_arch | string | "amd64" | CPU architecture: "amd64" or "arm64". Any other value fails with 400. See Architecture support. |
cpu_type | string | none | Pin to a minimum CPU hardware tier by slug (from GET /cpu-types, e.g. graviton). Implies its architecture. Placement prefers an exact match and falls back upward to a higher tier of the same architecture only when no exact-tier host is free — never to a lower tier. A slug not in the registry, or one whose architecture contradicts an explicit cpu_arch, fails with 400. |
network_class | string | none | Pin to a minimum NIC class by slug (from GET /network-classes, e.g. 100g). Runs on that class or higher (never lower). Unknown slug fails with 400; not supported with gpu_host or Windows sandboxes. |
disk_class | string | none | Pin to a minimum NVMe class by slug (from GET /disk-classes, e.g. nvme-gen5). Runs on that class or higher (never lower). Unknown slug fails with 400; not supported with gpu_host or Windows sandboxes. |
Each class in the cpu_type / network_class / disk_class registries carries an ordered tier (1 = lowest), returned by their GET discovery endpoints. Pinning a class sets a floor: you always get that class or a higher one, never lower. cpu_type tiers are ranked per architecture.
Explicitly supplied resource values are clamped up to platform minimums; the defaults are exempt. In burstable mode the guarantees must not exceed the platform burst caps (400 otherwise).
Errors
400— invalidmode, resource guarantees over burstable caps, dedicatedcpuover the CPU cap,cpu <= 0, invalidenvname or value > 64 KiB, unknown secret name, invalid/duplicate/reservedmount_path, more than 8 volumes or object-store mounts, unknown or disabledregion(or a global region with no active members), invalidcpu_arch, unknowncpu_typeor acpu_type/cpu_archmismatch, unknownnetwork_class/disk_class(or either combined withgpu_host/Windows), full snapshot restored outside its home region.402— owning organization is out of credits.404— snapshot named inimagedoes not exist.409— snapshot notready; volume or object store notready; image/snapshot still replicating into the target region (retry shortly).429— create queue at capacity. Honor theRetry-Afterheader (default 2 s) and retry.503— queue temporarily degraded; nothing was created, safe to retry.
GET /vms
List the project's sandboxes, newest first, with cursor pagination.
| Query param | Type | Default | Description |
|---|---|---|---|
limit | int | 100 | Page size, clamped to [1, 200]. |
cursor | string | — | Opaque token from a previous page's next_cursor. Malformed cursors return 400. |
next_cursor is null on the last page.
GET /vms/:id
Fetch one sandbox, with optional long-polling on status.
| Query param | Type | Default | Description |
|---|---|---|---|
wait | string | — | Block until the sandbox reaches this status or any terminal-bound state (stopping, stopped, deleting, deleted, failed, lost). |
wait_exact | string | — | Block until the status matches exactly (only failed/lost short-circuit). Use wait_exact=stopped to wait past the transient stopping. Takes precedence over wait. |
timeout_ms | int | 30000 | Max wait, clamped to [0, 60000]. On timeout the current state is returned with 200. |
Statuses: pending, assigned, booting, building, running, stopping, stopped, pausing, paused, deleting, deleted, failed, lost.
Errors
404— unknown id, malformed id, or a sandbox in another project.
DELETE /vms/:id
Delete a sandbox. A live sandbox transitions deleting → deleted once teardown is confirmed; a resting sandbox (stopped, paused, failed, lost) is finalized to deleted immediately. Repeating a delete is idempotent. A persistent sandbox's write layer is reclaimed as part of the delete.
Use GET /vms/:id?wait_exact=deleted to wait for teardown confirmation.
Errors
404— unknown id or a sandbox in another project.