> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orcapods.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Output and scripting

> Output modes, the JSON and NDJSON contract, exit codes, pagination, and patterns for using orca in shell pipelines and CI.

> **Last updated: 2026-09-06**

Every `orca` command decides how to print based on two things: whether `--json` was passed, and whether stdout is a terminal. The rules never vary by command, so a script that works with one command works with all of them.

## Output modes

| Mode     | When                     | What stdout carries                     |
| -------- | ------------------------ | --------------------------------------- |
| JSON     | `--json` is set          | Pretty-printed JSON, and nothing else   |
| Plain    | stdout is not a terminal | Tab-separated rows, no header, no color |
| Terminal | stdout is a terminal     | Tables and panels with color and hints  |

Plain mode follows the `gh` convention: one record per line, fields separated by a tab, in a fixed column order documented on each command's reference page. Nothing needs stripping before `cut`, `awk`, or `grep` sees it.

```bash theme={"dark"}
orca agents list | cut -f1              # names only
orca runs list --agent researcher | awk -F'\t' '$3 == "error"'
```

Hints, warnings, progress, prompts, and errors always go to stderr, in every mode. Redirect `2>/dev/null` if you want a silent pipeline; stdout stays parseable either way.

## JSON

`--json` works on every command that reports something, including `login`, `doctor`, and `update`. The two exceptions are `auth logout` and `context use`, which print a short text confirmation regardless.

* Lists print a JSON array of records (the page you asked for, or every record with `--all`).
* Single-resource commands print one object.
* Mutations print the updated record where the API returns one, or a small confirmation object such as `{ "name": "researcher", "deleted": true }`.
* Interactive pickers and confirmation prompts are never shown in JSON mode; a missing argument is a usage error instead.

```bash theme={"dark"}
orca agents get researcher --json | jq -r .model
orca sessions list --all --json | jq 'length'
```

## Streams (NDJSON)

Commands that follow a live run print newline-delimited JSON under `--json`: one event object per line, flushed as it arrives, until the stream reaches a terminal state.

```bash theme={"dark"}
orca runs tail "$RUN_ID" --json | while read -r event; do
  echo "$event" | jq -r '.type'
done
```

Streaming commands: `orca run` (unless `--detach`), `orca runs tail`, `orca workflows tail`, and `orca chat`. The device-code login also emits one NDJSON event under `--json` before its final result, see [Authentication](/cli/authentication).

## Exit codes

| Code  | Meaning                                                                                                                                                                               |
| ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `0`   | Success. For a tailed run, the run finished with status `ok`                                                                                                                          |
| `1`   | Failure: an API error, a network error, a server-side 5xx, or a tailed run that finished with any status other than `ok`                                                              |
| `2`   | Usage: bad arguments, an invalid flag value, a missing positional in non-interactive mode, an invalid agent document, or a destructive command without `--yes` in a script            |
| `3`   | Authentication: no API key configured, or the API returned 401 or 403                                                                                                                 |
| `4`   | Not found: the API returned 404 for a named resource                                                                                                                                  |
| `130` | Interrupted with Ctrl-C. Interrupting a tail detaches it only: the run keeps going server-side, and the error names the `runs tail` and `runs cancel` commands to reattach or stop it |

Errors print as `orca: <message>` on stderr, followed by indented detail lines where there is a fix to suggest:

```text theme={"dark"}
orca: no API key configured for context "default"
  Run: orca auth login
  Or set ORCA_API_KEY.
```

## Pagination

List commands share one set of paging flags:

| Flag           | Default | Description                                                       |
| -------------- | ------- | ----------------------------------------------------------------- |
| `--limit <n>`  | `10`    | Page size                                                         |
| `--offset <n>` | `0`     | Page offset                                                       |
| `--all`        | off     | Fetch every page. Cannot be combined with `--limit` or `--offset` |

When more records exist than the page shows, terminal and plain modes print `Showing X of Y` on stderr. `--all` walks the collection in windows of 200 (the server's per-request cap) and stops at 10,000 records with a warning; narrow the query if you hit that.

Commands with their own paging: `orca agents changes` caps client-side with `--limit` (unlimited by default), `orca storage ls` defaults to 100 and `orca storage browse` to 1000 (both max 1000), `orca memory list` has its own `--limit` and `--offset`, and `orca keys list` does not page.

## Interactive versus scripted

The CLI decides it is interactive when both stdin and stdout are terminals. That switches three behaviors:

* Optional positionals such as `orca agents get [name]` or `orca runs tail [id]` open a picker when omitted in a terminal. In a script they are required, and omitting one exits `2`.
* Destructive commands (`delete`, `remove`, `rm`, `unpublish`, `keys revoke`, `workflows cancel`, `billing cap set`) confirm in a terminal. In a script, pass `--yes` or the command refuses with exit `2`. The exceptions are `runs cancel` and `agents keys revoke`, which never prompt, and `auth logout --revoke`, which proceeds without `--yes` in a script.
* Prompts that read values, such as `orca secrets set` without `--value`, read from stdin when it is a pipe and show a hidden prompt when it is a terminal.

`orca login` follows the same rule: no terminal means the device-code flow.

## Patterns

**Start a run, do other work, then collect the result.**

```bash theme={"dark"}
RUN_ID=$(orca run researcher "Draft the changelog" --detach)   # stdout is only the run id
# ...
orca runs tail "$RUN_ID" --json > events.ndjson
orca runs get "$RUN_ID" --json | jq -r .status
```

With `--json`, `--detach` prints the full create response instead, including `runId` and `sessionId`.

**Fail a CI job when the agent fails.** `orca run` and `orca runs tail` exit `1` when the run ends in any status other than `ok`, so no parsing is needed:

```bash theme={"dark"}
orca run release-checker "Verify build $BUILD_ID" || exit 1
```

**Capture a minted key without exposing it.** Key-minting commands print only the token to a piped stdout:

```bash theme={"dark"}
CHAT_KEY=$(orca agents keys create support-bot --label website)
```

**Create an agent from a template.**

```bash theme={"dark"}
sed "s/{{ENV}}/production/" agent.tmpl.yaml | orca agents create -f - --json
```

**Run the same script locally and in CI.** Keep `ORCA_API_KEY` in CI secrets and rely on `orca login` locally. Flags beat environment variables, which beat the config file, so nothing in the script needs to change between the two.

**Feed a coding agent.** The [MCP server](/cli/reference/mcp) built into the CLI gives Claude Code, Cursor, and Codex the same control plane as typed tools, without shelling out. For agents that do shell out, the `--json` contract above is the whole interface; see [CLI for agents](/agents/cli).
