Skip to main content

Installation & updates

The CLI auto-checks for updates on each run. Suppress with --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.
Create production API keys with 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.
Secrets are shown once at 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.
Supported events are 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:
See Long-Running Tasks.

box list

List your up/running boxes with their current state and ID. By default, box list is equivalent to box list --filter r.
Use --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.
Use --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 archivingarchived.
Snapshotting takes a moment. The box is not yet stopped when the command returns; poll box info to confirm archived state.
If a stop is refused. Stopping saves the disk first. If that save is failing, we refuse the stop and leave the box running rather than discard your work, retry automatically, and email you. You are not billed for the time your box spends in that state, the meter pauses from the first failed attempt. --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.
--force discards unsaved work. Check box info for the last snapshot time first, so you know exactly what you are giving up.

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.
box delete destroys data. A deleted box cannot be resumed, forked or recovered, and there is no deleted-boxes list to restore from.If you want the data usable later, box stop it instead of deleting it. A stopped box is free, keeps its disk, and box resume brings it back where you left it.
The command asks for confirmation. Pass --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 with box snapshot rm <name> if you want those bytes gone too
Storage is released once the last box or named snapshot using a chain is gone.

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.
See Data retention and deletion.

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.
Requires the box to have a completed snapshot (i.e. it was stopped cleanly via 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.
Returns the new box ID asynchronously (HTTP 202). Requires the source box to have a completed snapshot. Forking copies the snapshotted filesystem into a new Box; enabled systemd services start automatically, like on resume. Processes the source box ran by hand are not forked; start them again in the fork if needed. Use --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.
--environment and --env are different. box new --environment staging picks which environment the box uses. box new --env KEY=value sets one variable on that single box, on top of what the environment gives it.

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.
A secret the new version withholds is deleted from the box’s disk, not hidden. Re-pinning to the older version does not bring it back.

box host <id> <port>

Expose a running service inside a Box on a stable HTTPS URL without opening an interactive SSH session.
The command opens the Box firewall, registers the HTTPS subdomain, and prints the URL. Calling it again for the same Box and port returns the same URL.
The service you expose must listen on 0.0.0.0, not only on localhost or 127.0.0.1.

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.
By default the desktop streams over Moonlight (60fps WebRTC). On restrictive or low-bandwidth networks where WebRTC is choppy or won’t connect, use --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.
Saving from a running box takes a fresh capture first, so it can run for minutes; the CLI polls until the snapshot settles at 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.
See Data retention and deletion.

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.
Override per box with 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.
Enabling requires a browser sign-in session (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.
Local configuration lives at ~/.config/ascii/box/config.json. box status prints its path along with the resolved API URL, account and plan.