Installation & updates
--no-update.
Global flags
These flags work with any command:--json is enabled automatically whenever output is piped or redirected, so scripts get JSONL without passing the flag.
Wherever a command takes a box ID, two aliases also work: current (the last box created in this shell) and self (the box you are running inside, when using the CLI from within a box).
Shell completion
box completions <shell> prints a completion script for bash, zsh, fish, or PowerShell. It completes subcommands and your live box IDs (plus current and self), with a 15 second cache so repeated tabs are instant.
Authentication
box onboard
Full onboarding flow: opens GitHub OAuth, authenticates, and saves your token.
box login [key]
Sign in with an existing API token, or start a browser sign-in flow if no key is given. GitHub is the default; Google and email also work.
box api-key create or from the dashboard API Keys page. See API Keys for key management and Use in Docker for Docker and hosted-worker setup.
box api-key
Create and manage API keys for SDKs, CI, and other projects.
create and rotate and can never be retrieved again; list shows only each key’s prefix and last four characters.
Key lifecycle requires a browser sign-in session (box login without a key). A CLI authenticated with an API key can use Box normally but cannot create, rotate, or revoke keys. See API Keys.
box webhook
Register account-wide lifecycle webhooks for automation.
box.ready, box.error, and box.archived. Omit --event to subscribe to all three. The signing secret is shown only at create/rotate time. See Webhooks.
box logout
Sign out and clear the local token.
box status
Show API health, the signed-in account and plan, and the local config path.
Box lifecycle
box new
Create a new box.
--type picks the machine size: small is 2 vCPUs / 4 GB at half rate, default is 4 vCPUs / 8 GB, large is 8 vCPUs / 16 GB at 2x rate. A fork inherits the source box’s size unless you pass --type, and box resume --type moves an existing box between sizes. See Machine Capabilities and Billing & Limits.
--env sets per-box environment variables on top of your dashboard secrets; per-box values win on name conflicts. See Environments.
--environment <name> picks which environment the box starts from: its repositories, secrets, and credentials. Omit it to use your default. An unknown name is rejected before the box is created, so a typo costs you nothing. Note that --environment and --env are unrelated: one picks a template, the other sets a variable on this one box. See Environments.
--no-env creates a box that receives none of the secrets attached to your account, and confines the box to itself so it can’t act on your account or other boxes. Use it for boxes you give to your own users. SSH, SCP, desktop, snapshots, and public URLs still work. See Environments. For more than the occasional box, prefer an environment marked safe for third parties, which applies the same protection to every box that uses it and survives forks and resumes.
--setup-file reads a local shell script (UTF-8, up to 64KB) and runs it on the box in the background after the box is ready, and it never delays ready. Watch the outcome as setupStatus (pending, running, done, failed) and setupError in box info.
--team <TEAM_ID> runs the box on that team’s shared balance instead of yours, and --personal bills you even when a team scope is active. Neither is needed day to day: box team switch sets the scope once and every later box new follows it. See box team.
--from <name> starts the box from a named snapshot you saved with box snapshot <id> <name>, so the stack is already installed. It does not carry the source box’s environment: pass --environment, or take your default. Note this is unrelated to box env set-file --from, which reads a local file. See Snapshots & Copies.
Returns the box ID, IP, and initial state.
For a long uninterrupted workflow, disable auto-stop:
box list
List your up/running boxes with their current state and ID. By default, box list is equivalent to box list --filter r.
--filter with state group letters:
Combine letters, for example
box list --filter sr lists stopped and up/running boxes. Use --all to include every state.
box extend <id>
Change the auto-stop timer for an existing Box.
--hours or --ttl for a timed extension. Use --no-auto-stop when the Box should keep running until you stop it yourself.
box info <id>
Get details for a specific box: state, IP, desktop availability, TTL remaining.
box stop <id>
Pause a running box. Creates a snapshot then stops billing. The box enters archiving → archived.
Snapshotting takes a moment. The box is not yet stopped when the command returns; poll
box info to confirm archived state.--force stops the box anyway and permanently loses everything written since the last successful snapshot. It is irreversible, so only use it after a stop has already failed.
box delete <id>
Permanently delete a box and its snapshots. The box is force-stopped without a final snapshot, then every snapshot chain it exclusively owns is deleted from storage.
--yes to skip the prompt; in scripts (--json, or no terminal attached) --yes is required and the command refuses without it rather than hanging.
Deletion is not instant: the machine has to be torn down before its data can be removed. The box disappears from box list right away, the command prints the deletion operation id (bdop_…), and then follows that operation until it finishes.
What survives. Snapshot data shared with something else is kept, because deleting it would break whatever else reads it:
- a box you forked from this one, or a resume of it, restores from the same physical snapshot objects
- a named snapshot saved from this box (
box snapshot <id> <name>) keeps its data; remove it withbox snapshot rm <name>if you want those bytes gone too
box deletion status <operation-id>
Check back on a deletion you started earlier, here or through the API. Statuses are pending, processing, blocked and completed. blocked is not a dead end: an attempt hit something it could not finish yet, most often a snapshot another box still reads, and it is retried automatically with backoff.
box resume <id>
Resume a stopped box from its last snapshot. The box is usable in a few seconds regardless of data size; remaining file content streams in the background. See Snapshots.
box stop).
Use -e/--env to set per-box environment variables on resume, with the same semantics as box new -e: repeat for multiple values, per-box values override dashboard variables with the same name, and the set you pass replaces the box’s current per-box variables.
Use --environment <name> to move the box onto a different environment as it resumes. Omit it and the box keeps the environment version it already had; a resume never silently moves a box to a newer version. An unknown name is rejected before anything changes. If the new environment withholds something the box currently holds, that secret is scrubbed off the disk during the resume and does not come back. See Environments.
Use --no-env to resume a stopped box after dropping your account secrets and scrubbing owner secrets inherited from the snapshot. This is one-way: the box stays no-env afterward.
Use --type to resume onto a different machine size (small, default, large). Omit it to keep the box’s current size. Shrinking is refused if the box holds more data than the smaller machine can take, and the box is left untouched. See Machine Capabilities.
Use --ttl <seconds> to set the resumed box’s lifetime, or --no-auto-stop to switch auto-stop off. Omit both and the box keeps the setting it already had, so a resume never quietly shortens or extends it.
Resume behaves like a server reboot: systemd services you enabled start again automatically. Processes you ran by hand (dev servers, background jobs, tunnels, desktop sessions) do not survive; restart them, or make them a systemd service.
box fork <id>
Clone a box from its latest snapshot into a new independent box.
--type to give the fork a different machine size from its source. The source box is never modified.
Use --ttl <seconds> or --no-auto-stop to set the fork’s lifetime. A fork does not inherit its source’s: it defaults to 1 hour, so forking a box with auto-stop switched off does not silently produce another box nothing will stop.
Use --environment <name> to point the fork at a different environment. Omit it and the fork inherits exactly the environment version its source is on, so a fork never picks up configuration the source never had. The source box is never modified either way. See Environments.
Use --no-env to fork into a no-env box. A fork of a no-env source is always no-env.
Use -e/--env to set per-box environment variables on the fork, with the same semantics as box new -e. The set you pass replaces the per-box variables the fork would inherit from the source box; omit it to inherit them unchanged.
box events <id>
Read the agent’s work on a Box: prompts, responses and checkpoints. Add --follow to keep polling for new events.
This is the agent’s conversation, not the Box’s lifecycle. A Box that has never been prompted returns an empty list even though it started, stopped and resumed. For lifecycle state use
box info.box interrupt <id>
Interrupt the currently running agent work in a Box.
Access
box ssh <id> [command]
SSH into a box, or run a command non-interactively. Manages the key at ~/.ssh/ascii_box_ed25519 automatically.
box exec <id> [command...]
Run a command in a box over the Box API, without an SSH session or key setup. box exec exits with the remote command’s exit code, so it drops straight into scripts and CI.
Wait for the box to reach
ready before running box exec; earlier calls are refused with a retryable box_starting error.
For anything that may run longer than the 600 second synchronous cap, detach and poll instead:
--detach starts the command in the background and answers with a JSON object; take processId from it, as above. Remember that --json turns itself on whenever output is piped or captured, so inside a script you always get JSON here even without the flag. Output goes to ~/.ascii/processes/<pid>.log on the box. --status <pid> prints whether it is still running, the exit code once finished, and a tail of stdout/stderr. If the box’s agent restarts (stop/resume), the status degrades to lost but the log files stay on disk. See Long-Running Tasks.
box env
Manage the templates new boxes start from: repositories, secrets, and which of your credentials a box may use. Every change mints a new immutable version. Running boxes stay on the version they started with until box env upgrade. See Environments.
box env set <name>
Change what the environment injects.
Contents
set-file reads contents from --from <local-file>, or from stdin when --from is omitted. Paths are relative to the box work directory (/home/user).
box env upgrade <name>
Move this environment’s boxes onto its latest version. Live boxes get the new configuration pushed immediately, with any secret the new version withholds scrubbed off the machine first. Stopped boxes pick it up when they resume. Nothing upgrades on its own.
box host <id> <port>
Expose a running service inside a Box on a stable HTTPS URL without opening an interactive SSH session.
box scp
Copy files to/from a box. Use bx_<id>:/path as the remote address.
On macOS and Linux, recursive copies to a new directory stream one archive over SSH when
tar is available on both ends, avoiding per-file network round trips. The new directory becomes visible only after a complete transfer. Files, existing-directory merges, and unsupported trees use the installed OpenSSH scp.
box forward <id>
Forward one TCP port from a box to your local machine.
box desktop <id>
Open the box’s desktop streaming URL in your browser.
--vnc for
a VNC stream that tunnels over plain HTTPS and is far more tolerant of poor
connections. The viewer also offers a one-click switch to VNC if the default
stream struggles.
The first
--vnc on a box takes a few seconds while it prepares the VNC
stack (the CLI shows a spinner); subsequent opens are instant.Snapshots
box snapshots [id]
List snapshots across your boxes, or for one box.
box snapshot <id> <name>
Save a box’s disk under a name, so box new --from <name> can deploy it as many times as you like. Reuse a name to replace it.
ready. You can keep up to 10 named snapshots. See Snapshots & Copies.
box snapshot latest|tree|pull
Inspect or download a snapshot. Works while the box is stopped.
pull writes home_user/ (your /home/user) and docker/ (named volumes). See Snapshots.
box snapshot delete <snapshotId>
Permanently delete one ordinary filesystem snapshot. Refused with 409 while a later incremental snapshot or an active restore still depends on it. Named snapshots are removed by name with box snapshot rm <name> instead.
AI agents
box prompt <id>
Send a natural-language prompt to an AI agent running inside the box.
Run
box prompt --help to fetch the current provider, model, and reasoning-effort list from the Box API.
Account
box limits
Display your current usage, quota, and subscription status.
box dashboard
Open your web dashboard in the browser. The CLI passes your local Box token to the dashboard. If that token is a service API key, Box operations still work, but creating, rotating, or revoking API keys requires signing in through the browser flow.
box team
Show or switch the billing scope for new boxes. The choice is sticky: it applies to every later box new until you switch again.
box new --team <TEAM_ID> or box new --personal. Manage members, invites and usage on the Team tab of the dashboard. See Billing & Limits.
box data-retention
Show or enable zero data retention, which queues every archived box for permanent deletion.
box login without a key), not an API key. See Data retention and deletion.
box self-update
Check for and install the latest CLI release on your current channel.
~/.config/ascii/box/config.json. box status prints its path along with the resolved API URL, account and plan.