# E2B Sandbox Usage Guide A practical guide for creating, observing, and using E2B sandboxes via the API. ## Prerequisites ### Local Dev Setup Seed the database to create a test team and API key: ```bash make -C packages/local-dev seed-database ``` ### Environment Variables ```bash E2B_API_KEY=e2b_53ae1fed82754c17ad8077fbc8bcdd90 E2B_ACCESS_TOKEN=sk_e2b_89215020937a4c989cde33d7bc647715 E2B_API_URL=http://localhost:3000 E2B_SANDBOX_URL=http://localhost:3002 ``` All examples below use `$E2B_API_URL` and `$E2B_API_KEY` — export them in your shell for convenience: ```bash export E2B_API_URL=http://localhost:3000 export E2B_API_KEY=e2b_53ae1fed82754c17ad8077fbc8bcdd90 ``` --- ## 1. Create a Sandbox ```bash curl -X POST $E2B_API_URL/sandboxes \ -H "X-API-Key: $E2B_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "templateID": "base", "timeout": 300 }' ``` **Response:** ```json { "sandboxID": "i1234567890abcdef", "templateID": "base", "envdVersion": "0.5.8", "domain": "i1234567890abcdef.your-domain" } ``` Save the `sandboxID` and `domain` from the response for subsequent commands. ### Optional Parameters | Parameter | Type | Description | |-----------|------|-------------| | `secure` | bool | Returns an `envdAccessToken` for authenticated envd access | | `envVars` | object | Inject environment variables into the VM | | `metadata` | object | Tag the sandbox for filtering (e.g. `{"purpose": "test"}`) | | `autoPause` | bool | Pause instead of kill on timeout | | `allow_internet_access` | bool | Allow internet egress from the VM | | `network.allowPublicTraffic` | bool | Allow inbound public traffic | | `network.allowOut` | array | Allowed egress destinations (IPs, CIDRs, domains) | | `network.denyOut` | array | Denied egress destinations (IPs/CIDRs only) | | `volumeMounts` | array | Mount persistent volumes (`{"name": "vol", "path": "/data"}`) | **Example with options:** ```bash curl -X POST $E2B_API_URL/sandboxes \ -H "X-API-Key: $E2B_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "templateID": "base", "timeout": 300, "secure": true, "envVars": {"MY_VAR": "hello"}, "metadata": {"purpose": "demo"} }' ``` --- ## 2. Observe Sandbox State ### Get details of a specific sandbox ```bash curl $E2B_API_URL/sandboxes/{sandboxID} \ -H "X-API-Key: $E2B_API_KEY" ``` Returns state (`running`/`paused`), CPU/memory/disk config, network settings, and TTL (`endAt`). ### List all sandboxes ```bash # Running only curl "$E2B_API_URL/v2/sandboxes?state=running" \ -H "X-API-Key: $E2B_API_KEY" # Running and paused curl "$E2B_API_URL/v2/sandboxes?state=running&state=paused" \ -H "X-API-Key: $E2B_API_KEY" # Filter by metadata curl "$E2B_API_URL/v2/sandboxes?metadata=purpose%3Ddemo" \ -H "X-API-Key: $E2B_API_KEY" ``` ### Get resource metrics (CPU, memory, disk) ```bash curl "$E2B_API_URL/sandboxes/{sandboxID}/metrics?start=$(date -v-5M +%s)&end=$(date +%s)" \ -H "X-API-Key: $E2B_API_KEY" ``` **Response:** ```json [ { "timestampUnix": 1234567890, "cpuCount": 2, "cpuUsedPct": 25.5, "memUsed": 268435456, "memTotal": 536870912, "diskUsed": 1073741824, "diskTotal": 5368709120 } ] ``` ### Get sandbox logs ```bash curl "$E2B_API_URL/v2/sandboxes/{sandboxID}/logs?limit=100&direction=backward" \ -H "X-API-Key: $E2B_API_KEY" ``` Optional query parameters: `cursor` (ms timestamp), `level` (min log level), `search` (substring match). --- ## 3. Use the Sandbox The in-VM daemon (**envd**) runs on port 49983 inside each sandbox, exposed via the sandbox's `domain`. ### Upload a file ```bash curl -X POST https://{domain}/files \ -H "Content-Type: multipart/form-data" \ -F "file=@script.py" \ -F "path=/home/user/script.py" ``` ### Using the E2B Python SDK Point the SDK at your local API: ```python from e2b import Sandbox sbx = Sandbox("base", api_url="http://localhost:3000") # Run a command result = sbx.commands.run("echo 'Hello from Firecracker VM!'") print(result.stdout) # Write and execute a file sbx.files.write("/home/user/hello.py", "print('Hello world')") result = sbx.commands.run("python3 /home/user/hello.py") print(result.stdout) # List files files = sbx.files.list("/home/user") for f in files: print(f.name) sbx.kill() ``` ### Envd Connect RPC API The envd daemon exposes Connect RPC services for programmatic access: **Process Service:** - `Start(ProcessConfig)` — start a new process - `List()` — list running processes - `Connect(ProcessSelector)` — connect to process stdio - `Signal(ProcessSelector, Signal)` — send signal to process **Filesystem Service:** - `ListDir(Path)` — list directory contents - `Stat(Path)` — get file metadata - `WatchDir(Path)` — watch for changes - `Move(Source, Dest)` — move/rename file - `RemoveDir(Path)` — remove directory --- ## 4. Lifecycle Management ### Extend timeout ```bash # Add 60 seconds to the TTL curl -X POST $E2B_API_URL/sandboxes/{sandboxID}/refreshes \ -H "X-API-Key: $E2B_API_KEY" \ -H "Content-Type: application/json" \ -d '{"duration": 60}' # Or set an absolute timeout (seconds from now) curl -X POST $E2B_API_URL/sandboxes/{sandboxID}/timeout \ -H "X-API-Key: $E2B_API_KEY" \ -H "Content-Type: application/json" \ -d '{"timeout": 120}' ``` ### Pause (snapshot to disk) ```bash curl -X POST $E2B_API_URL/sandboxes/{sandboxID}/pause \ -H "X-API-Key: $E2B_API_KEY" ``` ### Resume / reconnect ```bash curl -X POST $E2B_API_URL/sandboxes/{sandboxID}/connect \ -H "X-API-Key: $E2B_API_KEY" \ -H "Content-Type: application/json" \ -d '{"timeout": 300}' ``` Returns `200` if already running, `201` if resumed from paused state. ### Kill ```bash curl -X DELETE $E2B_API_URL/sandboxes/{sandboxID} \ -H "X-API-Key: $E2B_API_KEY" ``` ### Create a snapshot (template from running sandbox) ```bash curl -X POST $E2B_API_URL/sandboxes/{sandboxID}/snapshots \ -H "X-API-Key: $E2B_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "my-snapshot"}' ``` --- ## 5. Network Configuration Update network rules on a running sandbox: ```bash curl -X PUT $E2B_API_URL/sandboxes/{sandboxID}/network \ -H "X-API-Key: $E2B_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "allowOut": ["8.8.8.8", "example.com"], "denyOut": ["0.0.0.0/0"] }' ``` **Rules:** - If `allowOut` contains domain names, `denyOut` must include `0.0.0.0/0` - Domain names are not supported in `denyOut` (IPs/CIDRs only) - `allowOut` entries take precedence over `denyOut` - Omitting both fields clears all rules