# CLI quickstart (/docs/quickstart/cli)



Drive the full sandbox lifecycle from your terminal: log in, create a
sandbox, run a command, move files in and out, export an artifact, expose a
preview, stream logs, and clean up.

For agent or repo-test work where you already have a `.tar.gz` or `.tgz`
archive, use [Workspace Runs](/docs/cli/workspace-runs):

```bash title="Terminal"
crownest workspace-runs run-archive repo.tgz --template python-node -- pnpm test
```

`run-archive` does not pack local directories. It uploads an existing
archive, streams output, exits with the remote command's exit code, and
keeps durable evidence.

## Prerequisites [#prerequisites]

You need two things before you start.

* Node.js 18 or later, to install the `@crownest/cli` package.
* A CrowNest API key, created in the dashboard at
  [https://crownest.dev](https://crownest.dev). See
  [API keys](/docs/concepts/api-keys) for scopes and presets.

<Callout type="warn" title="Warning">
  The raw API key is shown once, at creation time. Copy it immediately and store it
  somewhere safe — you can't view it again later.
</Callout>

## Install and log in [#install-and-log-in]

Install the CLI globally, then save your credentials.

1. Install the package. It provides the `crownest` binary.

   ```bash title="Terminal"
   pnpm add -g @crownest/cli
   ```

2. Log in with your API key. This saves credentials to
   `~/.config/crownest/config.json` (under `$XDG_CONFIG_HOME` instead when
   that variable is set; override the location entirely with
   `CROWNEST_CONFIG_PATH`).

   ```bash title="Terminal"
   crownest login --api-key cn_live_...
   ```

   Running `crownest login` without `--api-key` prints guidance instead.
   You can also skip the config file and set a credential in the environment:
   `CROWNEST_BEARER_TOKEN` (preferred — accepts `cn_agent_…` and `cn_live_…`
   tokens) or the legacy `CROWNEST_API_KEY`. `CROWNEST_API_URL` overrides the
   API endpoint (default `https://api.crownest.dev`).

## Walk through the lifecycle [#walk-through-the-lifecycle]

Each step uses the sandbox ID printed in step 1; substitute your own.

```bash title="Terminal"
crownest new
crownest run <sandboxId> -- python3 -c "print('hello from crownest')"
```

1. Create a Sandbox. The quick verb prints its ID and next-step commands.

   ```bash title="Terminal"
   crownest new
   ```

   ```text title="Output"
   Created sbx_a1b2c3d4 (python-node, expires in 1h)

     Run a command:   crownest run sbx_a1b2c3d4 -- python3 --version
     Open a shell:    crownest shell sbx_a1b2c3d4
     List sandboxes:  crownest ls
   ```

   Use `--project <prj_id>` to create the sandbox in a specific project.
   `crownest ls` prints a table of your live Sandboxes. Add
   `--json` to either command when you need a stable `{ "data": ... }`
   response for scripts.

2. Run a command with `run`. Everything after `--` runs inside the
   sandbox, and the CLI prints the finished command record.

   ```bash title="Terminal"
   crownest run sbx_a1b2c3d4 -- python3 -c 'print(40 + 2)'
   ```

   The output includes the command's `id`, `status`, `exitCode`, `stdout`,
   and `stderr`. Add `--json` before `--` for the stable JSON envelope:
   `crownest run sbx_a1b2c3d4 --json -- python3 -c 'print(40 + 2)'`.

   <Callout type="warn" title="Important">
     The CLI's own exit code reports whether execution succeeded: `0` for success, `1`
     for errors, and `2` for usage errors. A command that runs to completion with a
     non-zero exit code still exits `0` — inspect `exitCode` in the output, or
     `.data.exitCode` with `--json`, to check whether your command failed.
   </Callout>

3. Upload and read files. All paths are inside `/workspace`, the sandbox's
   working filesystem area.

   ```bash title="Terminal"
   crownest files upload sbx_a1b2c3d4 ./data.csv --to data.csv
   crownest files write sbx_a1b2c3d4 notes.txt "hello from crownest"
   crownest files read sbx_a1b2c3d4 notes.txt
   ```

   ```text title="Output"
   hello from crownest
   ```

   `files read` writes the raw file content to stdout, so you can pipe it.
   Related commands: `files list`, `files stat`, `files mkdir`,
   `files move`, and `files delete` — see the [CLI reference](/docs/cli).

4. Export an artifact. The workspace disappears with the sandbox, so copy
   anything you want to keep to durable storage. The command prints an
   artifact record.

   ```bash title="Terminal"
   crownest artifacts create sbx_a1b2c3d4 notes.txt --name notes
   ```

   ```text title="Output"
   id: art_e5f6g7h8
   name: notes
   sizeBytes: 19
   ```

   Download it later — even after the sandbox is gone — with
   `crownest artifacts download art_e5f6g7h8 --output ./notes.txt`.

5. Expose a preview. Start an HTTP server in the background with
   `commands start`, then create a preview for its port. The command prints
   the authenticated preview URL.

   ```bash title="Terminal"
   crownest commands start sbx_a1b2c3d4 -- python3 -m http.server 8000
   crownest previews create sbx_a1b2c3d4 --port 8000
   ```

   ```text title="Output"
   https://p-a1b2c3.crownest.dev
   ```

   Previews require authentication in v1; see
   [Previews](/docs/concepts/previews). Revoke one with
   `crownest previews revoke <preview-id>`.

6. Stream logs. `crownest logs` follows a command's output live until it
   reaches a terminal state — useful with long-running commands launched by
   `commands start`. The output printed by `commands run` and `commands start`
   includes the command ID; add `--json` when you want to read it from
   `.data.id`.

   ```bash title="Terminal"
   crownest logs cmd_i9j0k1l2
   ```

   You can also scope by sandbox:
   `crownest logs sbx_a1b2c3d4 --command cmd_i9j0k1l2`. Cancel a running
   command with `crownest commands cancel cmd_i9j0k1l2` (add `--force` to
   skip graceful shutdown).

7. Kill the sandbox. This stops billing and releases the environment. The
   command prints the sandbox record with its new status.

   ```bash title="Terminal"
   crownest sandboxes kill sbx_a1b2c3d4
   ```

   ```text title="Output"
   id: sbx_a1b2c3d4
   status: destroyed
   ```

   Sandboxes also expire automatically at their TTL — see
   [Sandboxes](/docs/concepts/sandboxes).

## Next steps [#next-steps]

* Browse every command and flag in the [CLI reference](/docs/cli).
* Run archive-based workflows with [Workspace Runs](/docs/cli/workspace-runs).
* Learn how lifetimes, templates, and statuses work in
  [Sandboxes](/docs/concepts/sandboxes).
* Understand log streaming and collection in
  [Commands](/docs/concepts/commands).
* Build programmatically with the
  [TypeScript SDK quickstart](/docs/quickstart/sdk) or the
  [Python SDK quickstart](/docs/quickstart/python).
