Sign in

Sandboxes

Create a sandbox

One request boots a Firecracker microVM from a prebuilt snapshot and returns when the agent inside it is ready to run code.

POST /session

Behind the call, we pick a machine with room for the size you asked for, reserve its CPU, memory, disk and a network slot, and restore the VM from a snapshot of that size — inside its own cgroup and network namespace, with its own copy-on-write disk.

curl -sS -X POST "$SPAWN_API_URL/session" \
  -H "Authorization: Bearer $SPAWN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "dependency-check",
    "os": "alpine",
    "template": "base",
    "size": "nano",
    "metadata": {
      "project": "docs"
    },
    "env": {
      "APP_ENV": "dev"
    },
    "network": {
      "internet": true
    },
    "idle_timeout_s": 300,
    "max_lifetime_s": 3600
  }'
Response 201 Created
{
  "status": "success",
  "request_id": "4e245aae-1694-4dd5-b944-7180bf480fe8",
  "session": {
    "session_id": "3ecb0221-faf1-4976-a8ae-6fd6262de59a",
    "state": "active",
    "os": "alpine",
    "template": "base",
    "billing_model": "payg",
    "created_at": "2026-08-17T11:00:00Z",
    "last_used": "2026-08-17T11:00:00Z",
    "expires_at": "2026-08-17T11:05:00Z"
  },
  "limits": {
    "max_sessions": 100,
    "active_sessions": 0,
    "max_execution_ms": 30000,
    "idle_timeout_ms": 300000
  },
  "tenant": {
    "tenant_id": "<user-id>",
    "billing_model": "payg"
  }
}

Request body

Every field is optional; an empty body creates a nano sandbox with defaults.

name string
A label shown in the dashboard. Defaults to "sandbox".
os string
The OS image. Defaults to "alpine" — see OS images and templates below.
template string
The software on top of the OS: "base" (default) or "agents" (Claude Code and Codex).
size string
nano, small, medium or large — see Sizes below. Each template runs only at the sizes it lists. Defaults to nano.
resources object
An exact shape instead of a size name: { vcpus, memory_mb, disk_gb }. It must match one of the sizes exactly, and takes precedence over size.
image string
Legacy: an image ID (alpine, agents), used only when os and template are unset. A value that disagrees with them is rejected.
env object of strings
Environment variables set for code and commands you run in the sandbox.
metadata object
Your own labels, stored with the sandbox and returned when you list it.
network.internet boolean
Whether the sandbox can reach the internet. Defaults to true; set false for untrusted code that shouldn’t make outbound calls.
idle_timeout_s integer
Seconds without activity before the sandbox pauses itself. Defaults to 300 (5 minutes). Capped by the maximum lifetime.
max_lifetime_s integer
Seconds after creation when the sandbox is destroyed, whatever it’s doing. Capped by your account’s policy.

OS images and templates

A sandbox is an OS image, a template of software on top of it, and a size. Each template runs at the sizes listed for it.

OSTemplateWhat’s insideSizes
alpinebaseAlpine Linux 3.22, Python 3.12, Node 22, gitnano, small, medium
alpineagentsBase plus Claude Code and Codexlarge

Ubuntu and Debian images are coming. The current list is always available from the catalog:

GET /v1/catalog

curl -sS "$SPAWN_API_URL/v1/catalog" \
  -H "Authorization: Bearer $SPAWN_API_KEY"
Response 200 OK
{
  "os": [{
    "id": "alpine",
    "name": "Alpine Linux 3.22",
    "templates": [
      { "id": "base", "name": "Base", "description": "Python 3.12, Node 22, git",
        "sizes": ["nano", "small", "medium"], "image": "alpine" },
      { "id": "agents", "name": "Agents", "description": "Base plus Claude Code and Codex",
        "sizes": ["large"], "image": "agents" }
    ]
  }],
  "sizes": [
    { "name": "nano", "vcpus": 1, "memory_mb": 256, "disk_gb": 1 },
    { "name": "small", "vcpus": 2, "memory_mb": 512, "disk_gb": 10 },
    { "name": "medium", "vcpus": 2, "memory_mb": 1024, "disk_gb": 20 },
    { "name": "large", "vcpus": 2, "memory_mb": 4096, "disk_gb": 20 }
  ]
}

Sizes

Only these shapes are accepted; anything else is rejected rather than rounded.

SizevCPUMemoryDisk
nano1256 MiB1 GiB
small2512 MiB10 GiB
medium21024 MiB20 GiB
large24096 MiB20 GiB

Response

session.session_id string
The sandbox ID. Every other call takes it.
session.state string
active once the call returns.
session.os string
The OS image the sandbox runs.
session.template string
The template the sandbox was created from.
session.expires_at timestamp
When the sandbox will pause if it stays idle. Each run or command pushes it back.
limits.max_execution_ms integer
The longest a single run or command may take.
limits.idle_timeout_ms integer
The idle timeout that was applied.
limits.max_sessions integer
Your account’s sandbox limit.

Errors

StatusCodeMeaning
400invalid_resourcesThe size or resource shape isn’t one of the supported ones.
400invalid_templateThe OS or template doesn’t exist. The message lists the available ones.
400size_not_availableThe template doesn’t run at that size. The message lists the sizes it does.
402—The account has no balance left.
403sessions_not_allowedYour account’s policy doesn’t allow sandboxes.
503no_capacityNo machine has room for this size right now. Retry with backoff.
503scheduler_busyPlacement stayed contended after retries. Retry with backoff.
500provision_failedThe VM failed to boot.

List your sandboxes

GET /session

Returns every sandbox on your account that hasn’t been destroyed.

curl -sS "$SPAWN_API_URL/session" \
  -H "Authorization: Bearer $SPAWN_API_KEY"
Response 200 OK
{
  "sandboxes": [
    {
      "id": "3ecb0221-faf1-4976-a8ae-6fd6262de59a",
      "name": "dependency-check",
      "state": "active",
      "billing_model": "payg",
      "vcpus": 1,
      "memory_mb": 256,
      "disk_gb": 1,
      "idle_timeout_ms": 300000,
      "metadata": {"project": "docs"},
      "created_at": "2026-08-17T11:00:00Z"
    }
  ]
}

Get one sandbox

GET /session/{sandbox_id}

Returns its state and limits, plus run statistics. An ID that doesn’t exist and one that belongs to another account both return 404.

curl -sS "$SPAWN_API_URL/session/$SANDBOX_ID" \
  -H "Authorization: Bearer $SPAWN_API_KEY"
Response 200 OK
{
  "status": "success",
  "session": {
    "session_id": "3ecb0221-faf1-4976-a8ae-6fd6262de59a",
    "state": "active",
    "last_used": "2026-08-17T11:01:00Z",
    "expires_at": "2026-08-17T11:03:00Z",
    ...
  },
  "stats": {
    "run_count": 2,
    "total_execution_ms": 138.4,
    "last_exit_code": 0
  },
  ...
}
Ctrl I