---
title: The ibby command
description: The ibby command line tool. One command for each API operation, a --json mode for scripts and agents, and exit codes you can rely on.
---

```sh
npm install --global @ibby-ai/cli
```

It needs Node 20 or later. `ibby --help` lists every command with a worked example, and `ibby <group> <command> --help` shows a command's options.

## Your key

The tool reads your key only from `IBBY_API_KEY`. It never takes the key as an argument, so the key stays out of shell history and process lists. Paste it without echoing it:

```sh
read -rs IBBY_API_KEY && export IBBY_API_KEY
```

To reach another platform, such as a staging one, set `IBBY_BASE_URL` or pass `--base-url`.

## Sandboxes

```sh
ibby sandboxes create --workdir /work --lifetime-ms 60000 --cpu 0.5 --memory-mib 512
ibby sandboxes get sbx_...
ibby sandboxes make-directories sbx_... /work/in /work/out
echo 'a,b' > data.csv
ibby sandboxes write-files sbx_... --file /work/in/data.csv=./data.csv
ibby sandboxes list-files sbx_... /work/in
ibby sandboxes read-file sbx_... /work/in/data.csv
ibby sandboxes read-file sbx_... /work/in/data.csv --output ./copy.csv
ibby sandboxes remove sbx_...
```

`write-files` takes one `--file REMOTE=LOCAL` per file. Use `-` as LOCAL to read standard input, byte for byte. `read-file` prints the file's bytes as they are, or saves them with `--output`.

`create` also takes `--image img_...` to run on an image you built (see [Images](#images)), and `--store-mount PATH --store-prefix PREFIX`, together, to attach part of the lane's store folder read-only inside the working directory:

```sh
ibby sandboxes create --workdir /work --store-mount /work/in --store-prefix runs/1/
```

To remove a sandbox by the name you gave it, for cleanup after a crash:

```sh
ibby sandboxes create --workdir /work --name nightly-report
ibby sandboxes remove-by-name nightly-report
```

## Running commands

Put the command after `--`. No shell runs unless you run one:

```sh
ibby sandboxes create --workdir /work
ibby sandboxes exec sbx_... -- ls -la /work
ibby sandboxes exec sbx_... --timeout-ms 30000 --env GREETING=hello -- sh -c 'echo $GREETING'
ibby sandboxes remove sbx_...
```

`exec` prints the command's standard output and exits with the command's own exit code, or 124 when it timed out. In this version a command that timed out returns no output. Everything after `--` belongs to the command, so `-- tool --json` passes `--json` to the tool. A command is never retried on its own.

## Images

Write the recipe to a file, then build it. The [concepts page](/concepts#images) explains recipes.

```sh
echo '{"base":{"reference":"python:3.13-slim","digest":"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"},"packages":[]}' > recipe.json
ibby images build ./recipe.json
ibby images get img_...
ibby sandboxes create --workdir /work --image img_...
```

`images get` fails with `image_not_built` when the image has no build on the lane's current provider, which happens only after a lane changes provider; build the recipe again. `images build` prints the build job. When it is `done`, its result names the image. Use `-` as the file to read the recipe from standard input. A file that is not JSON exits with code 2; a recipe that breaks the rules gets `400 invalid_request` from the API.

## Jobs

```sh
ibby jobs get job_...
ibby jobs cancel job_...
```

## Usage

```sh
ibby usage --since 2026-11-01T00:00:00Z
```

Lists your lane's runs and their estimated costs as a table with fixed columns, then the totals. Every cost is an estimate. The [usage page](/usage) lists the columns.

## Scripts and agents

Add `--json` to any command to print the API's own JSON instead of text:

```sh
ibby sandboxes create --workdir /work --json
```

Where the API sends no JSON, the tool prints a fixed shape:

| Command | `--json` prints |
| --- | --- |
| `sandboxes remove` | `{ "removed": "<sandbox id>" }` |
| `sandboxes remove-by-name` | `{ "removed_name": "<name>" }` |
| `sandboxes read-file` | `{ "path", "size_bytes", "content_base64" }` |
| `usage` | `{ "runs", "totals", "next_cursor": null }`, over every page |

A failed call prints `{ "error": { "code", "message", "request_id", "status" } }` on standard error.

Exit codes:

| Code | Meaning |
| --- | --- |
| 0 | Success |
| 1 | The API refused the call or could not be reached |
| 2 | The command was used wrongly, for example a missing argument or no key |
| other | `sandboxes exec` without `--json`: the command's own exit code, or 124 on a timeout |
