Skip to content
Docs / CLI Pages

CLI

raw is one static binary for macOS, Linux and Windows. It does in one command what a person does in the console, and it answers either in words or, with --json, in the API's own JSON. It keeps itself current: once a day it looks for a newer release and swaps itself in the background, so the next run is the new one.

Install

curl -fsSL https://raw.computer/install.sh | sh

The script picks the build for your OS and architecture (macOS or Linux, amd64 or arm64), checks its sha256 against the release, and installs it as ~/.local/bin/raw, a directory you own, so the CLI can update itself there. Set RAW_INSTALL_DIR to install elsewhere. On Windows, download https://raw.computer/cli/<version>/raw-windows-amd64.exe, where <version> is the one /cli/latest.json names.

raw version
raw 0.1.0 (2c99fd7ffe65) darwin/arm64

Sign in

raw login

raw login prints a code and opens the console's Sign in the raw CLI page (pass --no-browser to only print it). Signed in to the console, check that the page shows the code your terminal does, and choose Approve. The CLI gets a personal token (rc_pat_…) and keeps it in ~/.config/raw/config.json, readable only by you (mode 0600).

To sign in, open this page and confirm the code WDJB-MJHT:

  https://raw.computer/app/device?code=WDJB-MJHT

Waiting for approval (the code expires in 10 minutes)…
Signed in as ada <ada@example.com>.
Acting in default · Default (org ada) as admin; change it with: raw workspaces use <code>

A personal token acts as you, in whichever of your workspaces a command names, with your relation there and never more. It never acts at org level, so it cannot rename an org or change its money. Each sign-in is listed in the console under API keys › Signed-in CLIs, where you can sign one out. raw logout revokes the stored token and forgets it.

In CI and other places with no browser, set an environment variable instead of signing in:

Variable Holds
RAW_TOKEN a personal token (rc_pat_…); name its workspace with RAW_WORKSPACE
RAW_API_KEY an API key of one workspace (rc_live_…, from API keys)
RAW_WORKSPACE the workspace to act in: its id (ws_…) or its code

RAW_TOKEN wins over RAW_API_KEY, and both win over the stored token. A token from the environment acts in the workspace the environment names, never in one chosen for the stored token.

Workspaces

Every command takes --workspace <ws> (an id, ws_…, or a code such as ci). Without it, a command acts in the workspace chosen last:

raw workspaces list
raw workspaces use ci
   CODE     NAME     ORG  RELATION  ID
*  default  Default  ada  admin     ws_01m6xxgde9f2c9q3y3gn9e8zdp
   ci       CI       ada  admin     ws_01m6xxh0yq5b8c0k4m2v6t9rza

raw login chooses one for you: the one chosen before, else one you administer. An API key acts in its own workspace only.

Commands

Command What it does With --json, prints
raw login [--no-browser] sign in through the browser { "object": "login", … }
raw logout revoke the stored token and forget it { "object": "logout", … }
raw whoami the person, token, workspace and org in use GET /v1/me
raw workspaces list your workspaces; * marks the one in use GET /v1/workspaces
raw workspaces use <ws> choose the workspace commands act in the workspace
raw workspaces rename <name> rename the workspace (an admin; its code stays) POST /v1/workspaces/{id}
raw workspaces set-residency <where> any, eu, or default (the org's), an admin POST /v1/workspaces/{id}
raw keys list the workspace's API keys you may see GET /v1/api_keys
raw keys create <name> [--relation viewer] an API key; its secret is shown once POST /v1/api_keys
raw keys revoke <key> revoke an API key DELETE /v1/api_keys/{id}
raw members list the workspace's members, the org's owners among them GET /v1/members
raw members invite <email> [--relation] mail an invitation (developer by default), an admin POST /v1/invitations
raw members set <member> <relation> make viewer, developer or admin their relation POST /v1/members/{id}
raw members remove <member> remove them from the workspace, an admin DELETE /v1/members/{id}
raw invitations list the invitations nobody accepted yet, an admin GET /v1/invitations
raw invitations withdraw <invitation> withdraw one; its link stops working DELETE /v1/invitations/{id}
raw sandboxes create [--class] [--size] a sandbox (std, 4x8 by default) POST /v1/sandboxes
raw sandboxes list the workspace's sandboxes, newest first GET /v1/sandboxes
raw sandboxes get <sbx> one sandbox GET /v1/sandboxes/{id}
raw sandboxes stop <sbx> / start <sbx> stop it (only its disk is billed), start it again POST …/stop, POST …/start
raw sandboxes fork <sbx> a new sandbox from its disk and memory now POST …/fork
raw sandboxes delete <sbx> delete it and its disk DELETE /v1/sandboxes/{id}
raw snapshots list [--sandbox sbx] the workspace's snapshots, newest first GET /v1/snapshots
raw snapshots get <snp> one snapshot GET /v1/snapshots/{id}
raw snapshots create <sbx> [--name] snapshot a sandbox's disk, and memory if it runs POST /v1/snapshots
raw snapshots delete <snp> delete a snapshot, freeing its unique bytes DELETE /v1/snapshots/{id}
raw templates list the templates to start from: the workspace's and ours GET /v1/templates
raw templates get <tpl> one template GET /v1/templates/{id}
raw usage [--from day] [--to day] usage per day, class and size GET /v1/usage
raw wallet the org's balance and entries (owners and billing) GET /v1/wallet
raw budget what the workspace may spend; whether a start can pay GET /v1/workspaces/{id}/budget
raw api <METHOD> <path> [--data json] any endpoint, as the CLI's token the body the API answered
raw mcp the commands as MCP tools, for an agent's harness MCP on stdin and stdout
raw agent setup [--remove] skill and raw mcp into Claude Code, Codex, Cursor { "object": "agent_setup", … }
raw version this build, and a newer release if one is out { "object": "version", … }
raw update update now (it happens by itself once a day) { "object": "update", … }

Every command has --help, and raw help <command> is the same. Singular names work too (raw sandbox ls).

A <member> is an email or an id (usr_…), and an <invitation> an email or an id (inv_…), as the lists show them. What only an admin does needs the token of raw login as an admin of the workspace (or an owner of its org): an API key is never an admin, so the CLI with RAW_API_KEY is refused with raw login as its next step. What acts at org level (an org's owners and name, a new workspace, the monthly caps, accepting an invitation) is the console's (API › Only in the console).

Examples

raw keys create ci --relation developer        # the secret is printed once; store it
raw sandboxes create --class std --size 4x8 --name build-42
raw sandboxes create --size 8x16 --on-full fail # fail at once instead of queueing when cells are full
raw sandboxes create --template tpl_01m6xxj9a2b3c4d5e6f7g8h9jk  # start from a template (raw templates list)
raw snapshots list --sandbox sbx_ny1_01m6xxh3k2q8v7c4t9r5wdz6ya
raw members invite ada@example.com --relation admin
raw members set ada@example.com developer
raw invitations withdraw ada@example.com
raw workspaces set-residency eu
raw usage --from 2026-11-01 --to 2026-11-08
raw api GET /v1/me
raw api POST /v1/api_keys --data '{"name":"deploy","relation":"viewer"}'
echo '{"name":"from-stdin"}' | raw api POST /v1/api_keys --data -

Every create sends an Idempotency-Key, and a request that got no answer is sent again with the same key, so a dropped connection never makes two of anything. Pass --idempotency-key <key> to create, stop, start, fork, raw snapshots create, members invite and the other commands that send a POST to keep a retry across runs safe as well: the same command run again is answered as the first was (API › Idempotency).

Output

Without --json, a command writes what it did in a few lines, or a table. With --json, stdout holds exactly one JSON document: the API's answer as it came (for raw sandboxes create, the answer of POST /v1/sandboxes), or the error, in the API's error shape. Anything meant for a person (the sign-in code, notes) goes to stderr.

raw sandboxes list --json | jq -r '.data[].id'

The exit status says how it went: 0 done, 1 refused or failed, 2 a command line that cannot run (an unknown command or flag, a missing argument).

Errors

An error says what happened, then its next step, as the API gives it, with the command to run where one helps:

$ raw sandboxes create --class std --size 4x8
raw: No cell serves std yet: raw.computer is in early access. [capacity_unavailable]
  next: Read the early-access note; sandbox creates open when the first cell does.
  see:  https://raw.computer/docs/limits#early-access
  docs: https://raw.computer/docs/errors#capacity_unavailable

That is every sandbox create today: during early access no cell is open to customers (Limits). The CLI says so plainly and exits 1; it never pretends a machine started.

The API's codes are on the Errors page. A few the CLI makes itself, in the same shape:

Code When
unauthorized no token: not signed in, and RAW_TOKEN and RAW_API_KEY are not set
invalid_request a command line that cannot run (exit 2)
unreachable the API did not answer (the network, or a wrong RAW_API_URL)
interrupted stopped (Ctrl-C) before the API answered
local_error something on this machine: a file it cannot write, a build that cannot update

Updates

Once a day, a run of raw starts a copy of itself in the background that reads /cli/latest.json, downloads the build for its OS and architecture when it is newer, checks its sha256, and renames it over the binary. The run that started it does not wait, and the next run is the new version. raw update does the same now. Nothing is replaced unless the whole file arrived and its sha256 is the release's.

The first run of a release whose skill changed writes the new skill where raw agent setup put the old one (Agents).

It does not update itself in CI (where CI is set: install the newest with the script instead), in a development build, or when RAW_NO_UPDATE=1 is set. If the binary is in a directory you cannot write, raw update says so; install it again with the script.

For agents

raw agent setup writes the raw-computer skill and the MCP server raw mcp into Claude Code, Codex and Cursor, so an agent there has the commands as tools and knows how to use them (Agents). Calling the CLI itself:

  • Use --json and branch on the exit status and error.code, never on a message.
  • Name the workspace with --workspace (or RAW_WORKSPACE) so a command never depends on a choice stored earlier.
  • raw api reaches any endpoint of the API with the CLI's token and version.
  • Every error's next_step.cli, when there is one, is a raw command that helps.

Environment

Variable What it does
RAW_TOKEN a personal token to use instead of the stored one
RAW_API_KEY an API key to use instead of the stored token
RAW_WORKSPACE the workspace to act in (id or code)
RAW_API_URL the API's origin (default https://raw.computer), or --api <url>
RAW_CONFIG_DIR where the CLI keeps its files (default ~/.config/raw)
RAW_NO_UPDATE 1: never update by itself
RAW_INSTALL_DIR for install.sh: where to install (default ~/.local/bin)