div sandbox
Reference for div sandbox, the command that creates, runs commands in, stops, resumes, forks and deletes sandboxes.
Synopsis
div sandbox <subcommand> [arguments] [flags]
div sandbox with no subcommand is div sandbox ls. It uses the API key that div login saves. If your key was created before sandboxes existed, run div login again.
<sandbox> is a sandbox’s name or id. Every subcommand accepts --json, which prints the full API response instead of the usual output.
Subcommands
| Subcommand | Description |
|---|---|
create |
Create a sandbox and print its name. |
ls |
List the org’s sandboxes. |
exec |
Run a command in a sandbox. |
cp |
Copy a file into or out of a sandbox. |
ssh |
Open a shell on a sandbox. |
set |
Change a sandbox’s idle timeout, whether it stops when its agents finish, or its metadata. |
stop |
Stop a sandbox, keeping its files and processes. |
resume |
Resume a stopped sandbox. |
fork |
Create a new sandbox from another sandbox’s files. |
rm |
Delete a sandbox permanently. |
desktop |
Start, stop or check the desktop. |
open |
Open URLs in the desktop’s browser. |
screenshot |
Save the desktop’s screen as a PNG. |
input |
Send a click, keystroke or scroll to the desktop. |
a11y |
Read the desktop’s accessibility tree, or act on a node. |
forward |
Make a sandbox port available on your machine. |
token |
Print a token that opens only this sandbox’s desktop and screen. |
tunnel |
Make a port on your machine available in the sandbox, or send its traffic through your machine. |
create
div sandbox create [--size <size>] [--name <name>] [--secret <NAME>]... [--environment <env>] [--metadata <key>=<value>]... [--idle <duration>] [--stop-when-agents-finish] [--idempotency-key <key>]
Creates a sandbox and starts it. The sandbox is running when the command returns.
| Flag | Description | Default |
|---|---|---|
--size <size> |
small, standard, large or xl. See sizes and prices. |
small |
--name <name> |
Lower case letters, digits and dashes. Must start with a letter or digit. The org’s slug and a dash are put in front: in org acme, box becomes acme-box, and a name that already starts with acme- is kept. The full name is at most 63 characters and unique across all orgs. Commands find the sandbox by either name. |
the org’s slug, -sb- and six hex digits |
--secret <NAME> |
A secret to set as an environment variable in the sandbox, read from --environment. The secret’s products must include sandboxes. Repeat for each secret. A sandbox with secrets cannot have a token. |
none |
--environment <env> |
The secrets environment to read --secret from. resume reads from the same environment, and a fork keeps it. The environment cannot be deleted while the sandbox exists. |
default |
--metadata <key>=<value> |
A label of your own, such as the user the sandbox is for. Repeat for each label, up to 16. Keys are 1 to 40 lowercase letters, digits, _, . or -. Values are up to 256 characters. |
none |
--idle <duration> |
Stop the sandbox after this long without use: 90s, 15m, 2h, 1d, or 0 for never. Between 60 seconds and 7 days. A number without a unit is rejected. See idle timeout. |
0 |
--stop-when-agents-finish |
Stop the sandbox once its coding agents have finished a turn, no turn is running or queued, and nothing has used the sandbox for 2 minutes. | off |
--idempotency-key <key> |
A retry with the same key returns the sandbox the first attempt created instead of creating another. Up to 255 characters. | none |
Output. The name on stdout, alone, so SB=$(div sandbox create) captures it. A summary on stderr:
sb-4c1e9a
sb-4c1e9a running · small, 1 vCPU, 2 GiB · $0.05/h · runs until stopped
For a sandbox created with --environment other than default, the summary also says secrets from <env>.
Example
SB=$(div sandbox create --size standard --secret GITHUB_TOKEN --idle 30m)
SB=$(div sandbox create --metadata user=42 --metadata team=support)
SB=$(div sandbox create --environment acme --secret ANTHROPIC_API_KEY --metadata customer=acme)
Errors
| Code | When |
|---|---|
unknown_environment |
No environment named by --environment. Create it with div secrets env add, or list environments with div secrets env ls. |
unknown_secrets |
A --secret is not in the environment, or its products do not include sandboxes. Set it with div secrets set <name> --environment <env>, or run div secrets products <name> runs,sandboxes --environment <env>. |
ls
div sandbox ls [--all] [--metadata <key>=<value>]...
Lists the org’s sandboxes, newest first.
| Flag | Description | Default |
|---|---|---|
--all |
Include deleted sandboxes. | off |
--metadata <key>=<value> |
List only sandboxes with this label. Repeat to require several; a sandbox must have all of them. | all sandboxes |
Output. One row per sandbox: name, status, size with vCPUs and memory, hourly price, and total spend. The name is the first column, so div sandbox ls | cut -d' ' -f1 lists names. A summary line on stderr gives the number running and their combined hourly price.
sb-4c1e9a running small 1×2G $0.05/h spent $0.14
base stopped standard 2×4G $0.10/h spent $0.52
1 sandbox running, $0.05/h
Status is one of starting, running, stopping, stopped, resuming, destroyed or failed.
With --metadata and no match, the output is No sandboxes with that metadata. on stderr. With --json, each sandbox includes its metadata.
Example
div sandbox ls --metadata user=42
exec
div sandbox exec <sandbox> [--cwd <dir>] [--env KEY=value]... [--timeout <seconds>] -- <command> [args]...
div sandbox exec <sandbox> '<script>'
Runs a command in a running sandbox as root and waits for it to finish.
| Flag | Description | Default |
|---|---|---|
--cwd <dir> |
Working directory. | /root |
--env KEY=value |
An environment variable for this command. Repeat for each variable. | none |
--timeout <seconds> |
Maximum run time, up to 600. A command that runs longer is killed and exits 124. | 60 |
- One argument runs as a shell script:
div sandbox exec $SB 'cd app && make'. - Several arguments run as a command with those exact arguments:
-- echo "a b"printsa b. - Put
--before a command that has its own flags. Otherwisedivreads them.
Output. The command’s stdout and stderr, unchanged, on stdout and stderr. Each stream is cut at 1 MB. For more output, write it to a file and copy it back with cp. Values of the sandbox’s secrets are masked.
Exit code. The command’s exit code.
Examples
div sandbox exec $SB -- npm test
div sandbox exec $SB --cwd /root/app --timeout 600 'make && make check'
div sandbox exec $SB -- cat /root/log.txt | grep loss
cp
div sandbox cp <from> <to>
Copies one file between your machine and a sandbox. Write the sandbox side as <sandbox>:<path>. Use - for stdin or stdout. Files can be up to 64 MB. For larger files, download them from inside the sandbox with curl.
Output. The size copied, on stderr. Nothing on stdout unless <to> is -.
Examples
div sandbox cp ./app.py $SB:/root/app.py
div sandbox cp $SB:/root/out.json ./out.json
div sandbox cp $SB:/root/out.json - | jq .metrics
tar cz src | div sandbox cp - $SB:/root/src.tgz
ssh
div sandbox ssh <sandbox> [-- <command>]
Opens a root shell on a running sandbox, or runs one command, with your system’s ssh. Requires ssh and ssh-keygen on your PATH, and an API key with the sandboxes:write scope.
- The first run creates a key at
~/.config/divergent/ssh_ed25519. Eachdiv sandbox sshadds the key to the sandbox it connects to. - The session is encrypted end to end. Output is not masked.
- The shell has the sandbox’s environment, including its secrets.
- An open session counts as use, so the sandbox is not stopped as idle.
- Stopping the sandbox ends the session.
Exit code. The remote command’s exit code, or 255 if ssh fails to connect.
Examples
div sandbox ssh $SB
div sandbox ssh $SB -- tail -f /root/app/server.log
To use scp, rsync or an editor’s remote SSH, see Use a sandbox over SSH.
set
div sandbox set <sandbox> [--idle <duration>] [--stop-when-agents-finish on|off] [--metadata <key>=<value>]... [--clear-metadata]
Changes the idle timeout of a running or stopped sandbox, whether it stops when its agents finish, or its metadata. Give at least one flag.
| Flag | Description | Default |
|---|---|---|
--idle <duration> |
Same values as create. 0 means never. |
unchanged |
--stop-when-agents-finish on|off |
on stops the sandbox once its agents have finished, as in create. off keeps it running. |
unchanged |
--metadata <key>=<value> |
Replace every label with the labels given. Same rules as create. Repeat for each label. |
unchanged |
--clear-metadata |
Remove every label. Cannot be combined with --metadata. |
off |
On a running sandbox, the new timeout counts from now.
--metadata replaces the labels as a whole. To add one label, give every label the sandbox should keep.
Output
sb-4c1e9a running · small, 1 vCPU, 2 GiB · $0.05/h · stops after 2h idle
stop
div sandbox stop <sandbox>
Stops a sandbox. Its files and running processes are kept, and it is billed for storage only. Stopping a stopped sandbox succeeds and changes nothing.
Output. On stderr: the size of the stored data and the sandbox’s total spend.
sb-4c1e9a stopped · 1.2 GB stored · spent $0.14
With --json, stopped_reason is requested, idle, agents_finished or limit_reached.
resume
div sandbox resume <sandbox>
Resumes a stopped sandbox with its files and processes as they were. Takes a few seconds.
Output
sb-4c1e9a running · small, 1 vCPU, 2 GiB · $0.05/h · runs until stopped
fork
div sandbox fork <sandbox> [--name <name>]
Creates a new running sandbox with a copy of another sandbox’s files. The source can be running or stopped and is not changed. The new sandbox has the source’s size, secrets, secrets environment, idle timeout and metadata. Running processes and the desktop are not copied.
| Flag | Description | Default |
|---|---|---|
--name <name> |
Name of the new sandbox. Same rules as create. |
the org’s slug, -sb- and six hex digits |
Output. The new name on stdout, alone, and a summary on stderr:
try-b
try-b running · small, 1 vCPU, 2 GiB · $0.05/h · runs until stopped · a copy of sb-4c1e9a
rm
div sandbox rm <sandbox>
Deletes a sandbox and its stored data. Billing stops. This cannot be undone.
Output. On stderr: the sandbox’s total spend.
sb-4c1e9a destroyed with all its files · spent $0.14
desktop
div sandbox desktop <sandbox> [start|stop|status] [--resolution <WxH>]
Starts the desktop (the default action), stops it, or reports whether it is running. start returns when the browser is ready.
| Flag | Description | Default |
|---|---|---|
--resolution <WxH> |
Screen size for start. Width 320 to 1920, height 240 to 1080. |
1280x800 |
Output. The screen size and the dashboard page where you can watch it:
Desktop running on sb-4c1e9a at 1280x800. Watch it at https://app.divergentlabs.xyz/sandboxes/sb-4c1e9a.
With --json: running, size, display, vnc_port, devtools and browser.
open
div sandbox open <sandbox> <url>...
Opens each URL as a tab in the desktop’s Chromium. The desktop must be running.
screenshot
div sandbox screenshot <sandbox> [file] [--region <x0>,<y0>,<x1>,<y1>]
Captures the screen as a PNG. Writes to file, or to stdout when you give no file or -. Refuses to write to a terminal.
| Flag | Description | Default |
|---|---|---|
--region <x0>,<y0>,<x1>,<y1> |
Capture only this part of the screen: the top-left and bottom-right corners, in screen pixels. The PNG is that part scaled up to fit the screen size, keeping its aspect ratio. | the whole screen |
Output. The width, height and size, on stderr:
1280×800 PNG, 214 KB
Examples
div sandbox screenshot $SB shot.png
div sandbox screenshot $SB | your-model
div sandbox screenshot $SB zoom.png --region 0,0,640,400
input
div sandbox input <sandbox> click [<x> <y>] [--button left|middle|right] [--count 1|2|3] [--double] [--mods <keys>]
div sandbox input <sandbox> move <x> <y>
div sandbox input <sandbox> down
div sandbox input <sandbox> up
div sandbox input <sandbox> drag <x1> <y1> <x2> <y2> [--mods <keys>]
div sandbox input <sandbox> type <text>
div sandbox input <sandbox> key <combo>... [--repeat <n>]
div sandbox input <sandbox> hold <combo>... --seconds <s>
div sandbox input <sandbox> scroll <up|down|left|right> [notches] [--at <x>,<y>] [--mods <keys>]
div sandbox input <sandbox> cursor
Sends one input to the desktop. Positions are screenshot pixels from the top left.
| Action | Description |
|---|---|
click |
Click at <x> <y>, or where the pointer is when you give no position. |
move |
Move the pointer. |
down, up |
Press or release the left button where the pointer is. |
drag |
Drag with the left button from <x1> <y1> to <x2> <y2>. |
type |
Type the text where the keyboard focus is. |
key |
Press each key or combination in turn. |
hold |
Hold the keys down for --seconds. |
scroll |
Scroll by wheel notches. |
cursor |
Print the pointer’s position as JSON on stdout: {"x":640,"y":400}. |
| Flag | Description | Default |
|---|---|---|
--button <button> |
click only. left, middle or right. |
left |
--count <n> |
click only. 1, 2 (double-click) or 3 (triple-click). |
1 |
--double |
click only. The same as --count 2. Do not combine with --count. |
off |
--mods <keys> |
click, drag and scroll. Keys held down during the action: shift, ctrl, alt or super, joined by +, such as ctrl+shift. |
none |
--at <x>,<y> |
scroll only. Move the pointer here first. |
current position |
--repeat <n> |
key only. Press the keys n times, 1 to 100. |
1 |
--seconds <s> |
hold only, and required. How long to hold the keys, 0 to 300. Decimals are allowed. |
none |
typetakes the text as one argument. Quote it. Up to 10,000 bytes.keyandholdtake key names and combinations:Return,Escape,ctrl+l,alt+Tab.scrollmoves 3 notches unless you give a number from 1 to 100.- A sandbox created before an action existed refuses it with
desktop_outdated. Create a new sandbox to use it.
Examples
div sandbox input $SB click 640 400
div sandbox input $SB click 640 400 --count 3
div sandbox input $SB click 200 300 --mods ctrl
div sandbox input $SB type 'hello world'
div sandbox input $SB key ctrl+l
div sandbox input $SB key Down --repeat 5
div sandbox input $SB hold shift --seconds 2
div sandbox input $SB scroll down 5 --at 640,400
div sandbox input $SB cursor
a11y
div sandbox a11y <sandbox> [--app <name>] [--depth <n>] [--hidden]
div sandbox a11y <sandbox> do <ref> <action> [text]
The first form prints the accessibility tree of what is on screen, as JSON on stdout. The second acts on one node.
| Flag | Description | Default |
|---|---|---|
--app <name> |
Only this application, for example chromium. |
all applications |
--depth <n> |
Maximum depth. | 60 |
--hidden |
Include nodes that are not on screen. | off |
Tree output
{
"apps": [
{
"ref": "n1", "role": "application", "name": "Chromium",
"children": [
{ "ref": "n7", "role": "push button", "name": "Reload", "states": ["focusable"],
"bounds": [96, 48, 34, 34], "actions": ["press"] },
{ "ref": "n12", "role": "entry", "name": "Address and search bar",
"states": ["editable", "focusable", "focused"], "bounds": [140, 48, 880, 34],
"text": "example.com" }
]
}
],
"nodes": 214,
"truncated": false
}
| Field | Description |
|---|---|
ref |
The node’s id for do. Valid until the tree is read again. |
role, name |
What the node is and its label. |
states |
For example focusable, focused, editable. |
bounds |
[x, y, width, height] in screenshot pixels. |
actions |
Actions the node supports. |
text |
The text of a field. |
nodes |
Number of nodes returned. |
truncated |
true when the tree passed 4,000 nodes and was cut. Narrow it with --app or --depth. |
Nodes with no name, text or action are left out, and their children take their place.
Actions for do
| Action | Description |
|---|---|
press |
Press a button or follow a link. |
focus |
Move keyboard focus to the node. |
set-text <text> |
Replace the text in a field. |
read |
Print the node’s current state. |
any name in actions |
Run that action. |
If the node has changed since the tree was read, the action is refused. Read the tree again and retry.
Examples
div sandbox a11y $SB --app chromium > tree.json
div sandbox a11y $SB do n12 set-text 'https://example.com'
div sandbox a11y $SB do n7 press
forward
div sandbox forward <sandbox> <port>[:<local port>]
Makes a port on the sandbox’s 127.0.0.1 available on 127.0.0.1 on your machine until you press Ctrl-C. A single number uses the same port on both sides. Requires ssh on your PATH.
| Port | Use |
|---|---|
9222 |
The desktop browser’s DevTools protocol, for Playwright or Puppeteer. |
5900 |
The desktop’s screen, for a VNC viewer. |
Output
Forwarding localhost:9222 to sb-4c1e9a:9222. Press Ctrl-C to stop.
Examples
div sandbox forward $SB 9222
div sandbox forward $SB 3000:13000 # the sandbox's 3000 on your 13000
token
div sandbox token <sandbox> [--ability view|control] [--expires <duration>] [--origin <url>]...
Prints a token that opens one sandbox’s desktop and screen, and nothing else. Give it to a page or a program that must not hold your API key, such as the SDK’s screen. The sandbox must have no secrets.
| Flag | Description | Default |
|---|---|---|
--ability <ability> |
view watches the screen and takes screenshots. control also sends input and starts or stops the desktop. |
control |
--expires <duration> |
How long the token works: 90s, 15m or 1h. Between 60 seconds and 1 hour. A number without a unit is rejected. |
15m |
--origin <url> |
A page that may use the token in a browser, as a scheme and host with no path: https://app.example.com. Repeat for each origin, up to 10. |
none |
- Without
--origin, a request from a browser is refused. Requests from a server, which send noOriginheader, work on every plan. - The token stops working when it expires, when the key that minted it is revoked, or when the sandbox has secrets.
Output. The token on stdout, alone, so TOKEN=$(div sandbox token $SB) captures it. A summary on stderr:
dvs_SFMyNTY.g2gDdAAAAAZtAAAAAWF...
For sb-4c1e9a · view and control · expires 2026-10-07T12:15:00Z · from https://app.example.com
With --json: token, sandbox, abilities, origins and expires_at.
Examples
TOKEN=$(div sandbox token $SB --ability view --expires 1h)
div sandbox token $SB --origin https://app.example.com --origin http://localhost:5173
Errors
| Code | When |
|---|---|
sandbox_has_secrets |
The sandbox was created with --secret, in any environment. Create a sandbox without secrets. |
tunnel
div sandbox tunnel <sandbox> [<port>[:<local port>]]... [--exit]
Makes ports on your machine available on the sandbox’s 127.0.0.1, sends the sandbox’s internet traffic through your machine, or both, until you press Ctrl-C. Give at least one port or --exit. Requires ssh on your PATH.
| Argument or flag | Description | Default |
|---|---|---|
<port> |
Your machine’s port, available on the same port in the sandbox. | none |
<port>:<local port> |
Your machine’s <local port>, available on the sandbox’s <port>. The sandbox’s port comes first, as in forward. |
none |
--exit |
The sandbox’s TCP traffic and DNS lookups go out through your machine, to public addresses only. Uses port 1080 on the sandbox’s 127.0.0.1. One --exit tunnel per sandbox at a time. |
off |
- A tunnel that drops after it connects reconnects on its own. If the sandbox is stopped, the tunnel waits until it is resumed. If the sandbox is deleted, the tunnel exits 1.
- A tunnel that fails on its first attempt exits without retrying, usually because a port is already in use in the sandbox. A closed tunnel’s ports can stay in use for up to a minute.
- When the tunnel ends, the sandbox’s traffic goes out directly again.
Output
Forwarding sb-4c1e9a:3000 to port 3000 on this machine.
Forwarding sb-4c1e9a:5432 to port 15432 on this machine.
Sending sb-4c1e9a's internet traffic through this machine.
Press Ctrl-C to stop.
Examples
div sandbox tunnel $SB 3000
div sandbox tunnel $SB 3000 5432:15432 --exit
See Reach your machine from a sandbox.
Exit codes
| Code | When |
|---|---|
| the command’s own | exec, and ssh with a command |
0 |
The subcommand succeeded. |
1 |
The API refused the request, the desktop is not running, or the sandbox was deleted during a tunnel. The message says what to do next. |
2 |
A subcommand, argument or flag was typed wrong. |
124 |
exec reached its --timeout. |
255 |
ssh, forward or tunnel could not connect. |
These match every div command.