Skip to main content
Every machine operation is available from the CLI, and all commands accept --json for scripting. This page is the full reference.

The command tree

The surface is a nested tree. This is the full first level: The three shortcuts exist because creating, connecting, and listing are what you do all day: boxd new myapp and boxd machine new myapp are the same command. remove is the delete verb everywhere (alias rm), and the common aliases are ls for list, info for get, and ssh for connect.
boxd <cmd> --help is the always-current reference for flags and subcommands, straight from your installed binary. Running bare boxd in a terminal drops into an interactive REPL (boxd (org)>) where you type the same commands without the boxd prefix, with tab completion and arrow-key pickers for missing arguments.

Managing machines

boxd new myapp and boxd m ls are the top-level and short forms. machine new folds in fork (--fork) and snapshot restore (--from-snapshot):
See Suspend, resume, and hibernate for how the idle timers work.

State control

Three categories of state transition, all boxd machine <verb> <machine>:
  • pause / resume are warm. They freeze the VMM process and keep memory, running processes, and open sockets intact. Resume is sub-millisecond. This is the same mechanism as auto-suspend, only user-triggered. Status becomes standby.
  • reboot and stop + start are cold. They kill the VMM process, so memory is lost and the restart takes ~2s.
Use pause for cost savings without losing state. Use reboot when you need a cold restart.

Running commands

Exit codes are forwarded, so a remote command that exits 42 makes boxd machine exec exit 42. The remote command’s stdout and stderr are surfaced separately on the local side, so shell redirects work as you’d expect:
PTY execs (--tty) are the exception. The kernel TTY layer merges stderr into stdout, as terminals do, so everything arrives on local stdout and 2> filters won’t separate them.
The -- separator between the machine name and the command is optional, since everything after the machine name is treated as the command. Put exec’s own flags (-e, --timeout, --tty) before the command, and use -- or quotes when your command starts with a dash.

Interactive access

boxd connect drops you straight into an interactive shell on the machine over the boxd API. It needs neither SSH config nor host keys, auto-resumes paused or hibernated machines on demand, and forwards exit codes. Type exit or Ctrl-D to come back to your local shell.
connect requires an interactive terminal and refuses to run in scripts, pipes, or other non-TTY contexts. For automation, use boxd machine exec instead:

Editor & SSH integration

The CLI keeps a managed block of Host entries in ~/.ssh/config automatically. Every machine new, fork, list, remove, and rename refreshes it, and a background agent re-syncs it periodically, so your SSH config stays current as machines come and go. There is no separate command to run. After the first sync, <vmname>.boxd is reachable to plain ssh, scp, rsync, Cursor / VS Code Remote-SSH, JetBrains Gateway, Zed Remote, and anything else that reads SSH config:
Each machine is reachable on a dedicated SSH port (10000-30000 range) on the shared proxy IP, so each stanza carries a HostName, a Port, a User, and a managed IdentityFile. The CLI also pre-trusts the proxy’s host key in ~/.ssh/known_hosts, so the first connect never prompts. Connecting to the bare <vmname>.boxd.sh hostname on port 22 reaches the proxy rather than the machine, so always use the <vmname>.boxd alias. The managed block is bracketed with # BEGIN boxd / # END boxd, and nothing outside the markers is ever modified.

Copying files

Paths after : are relative to /home/boxd unless starting with /. Uploads stream automatically, with no inherent file-size cap.

Proxy management

Every machine gets https://name.boxd.sh forwarding to its default port. Publish more ports, either HTTPS subdomains or raw TCP/UDP forwards, all under boxd machine proxy.
Subdomain proxies are HTTPS-only. To expose a database, an SSH daemon, or any non-HTTP service, use a raw port forward (below).

Custom domains

Bring your own domain instead of name.boxd.sh. See Custom domains for the full walkthrough (DNS records, confirmation step, gotchas).
Org admins can delegate a wildcard to the whole org instead of binding machines one at a time:

Raw TCP and UDP ports

Raw forwards live under the same machine proxy group, selected with --raw. boxd opens a raw TCP or UDP port on the machine’s public proxy and forwards it straight to a port inside the machine, for anything that isn’t HTTP (databases, game servers, custom protocols). The public port is allocated for you. Connect on the machine’s existing name.boxd.sh endpoint at that port. See Port forwarding for the concept.
Up to 3 raw forwards per machine. Re-adding a port you already forwarded keeps the same public port and just updates the protocol set. Forwards are owner-only and removed automatically when the machine is destroyed.

Snapshots

A snapshot captures a running machine’s memory and disk at a moment in time, replicated across a few workers. Create a machine from it near-instantly with machine new --from-snapshot.
Re-saving an existing name captures a new version, and the latest version is what new machines get. Snapshots are fenced to the org context that created them and never cross an org boundary.

Checkpoints

A checkpoint captures a running machine’s memory and disk on the machine’s own worker, restorable in place: the machine reboots into that exact state with the same name, URL, and ports. Checkpoints are per-machine, live and die with the machine, and never become a reusable image. Use them as quick save points before a risky change.
Up to 10 checkpoints per machine. available: no means the checkpoint’s worker is no longer the machine’s worker (for example after a migration), so it can’t be restored until they line up again.

Integrations

Connect third-party accounts (GitHub, Linear, and Slack) under boxd manage integrations, and every personal machine in that org can use them. See Integrations for the full model.
connect prints an authorize URL for you to open in a browser, and a human has to approve it. Integrations are fenced to one org. Your own connection serves your private machines in the active org, while --shared addresses the org’s connection for its shared machines (admin only).

Env vars & secrets

Set environment variables and secrets once, and boxd injects them into every machine you own in that org. Plain vars are cleartext and readable back. --secret seals a value at rest, write-only. See Env vars & secrets for the full model (scopes, naming, injection).
To put a literal .env file on one machine, rather than an account-wide var, use boxd env push:
--file defaults to .env, --dest to the file’s name in the machine’s home directory, and --mode to 600.

Billing

Every machine is 2 vCPU / 8 GiB RAM / 100 GB disk. Your balance, usage, and payment live under boxd manage billing.
See boxd.sh/pricing for the rate card.

Organizations

Every account works in an org context, and your personal account counts as an organization of its own. Your active context decides which org a new machine is billed to and which machines list and connect see. Switching context is covered in Org context. Sharing a machine opens it to every member of the org.
  • In an org context, boxd machine new creates a machine billed to the org but private to you. Add --shared to make it visible to the whole org from birth.
  • boxd manage billing follows the active context, so in an org it shows the org’s balance and usage.
  • Share and unshare are owner-only. Any member can connect to a shared machine. A private machine, personal or org-billed, is reachable only by its owner.
  • An org has three roles: owner, admin, and member. Owners and admins invite and remove members at /app/organizations.
Sharing a machine wipes its in-VM agent logins (Claude Code, Codex, OpenCode) the instant it goes shared, so a teammate with a shell can never read your personal tokens. Unsharing restores Claude automatically, while Codex and OpenCode need a one-time re-login. Forking a shared machine gives you a private fork with your logins intact. See VM sharing for the full handoff.

Networks

Machines reach each other when they share at least one network, or when neither has any. Machines with no networks form your default network, so naming a network opts a machine out of that pool. The same rule governs direct connections, the <name>.boxd DNS name, and machine exec / cp between machines.
Networks are labels you pick, with nothing to create first, and they never cross an organization. Changes take effect immediately, without a reboot. Set them at creation with machine new --networks. machine new --isolated sandboxes a machine. It never joins the default network and never reaches another isolated machine, and boxd strips everything that could reach into the rest of your account from it: the in-VM boxd CLI, your connected integrations, your saved agent logins, and the bridge to your laptop. Outbound internet, its HTTPS domain, and inbound SSH still work. Isolation is fixed at creation and always inherited by forks and snapshot restores, while its --networks remain editable and are the only thing it can reach through. See Sandboxes.

Per-machine settings

Auto-suspend and auto-hibernate timeouts live under boxd machine config. You can also set them at creation with --auto-suspend-timeout / --auto-hibernate-timeout.

CLI settings

boxd config persists laptop-side CLI settings (kept in config.toml).
Shell completions are covered in Installation.

Open the docs

Global flags