Last updated: 2026-09-06Every
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
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.
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.
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.
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.
Exit codes
Errors print as
orca: <message> on stderr, followed by indented detail lines where there is a fix to suggest:
Pagination
List commands share one set of paging flags:
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]ororca runs tail [id]open a picker when omitted in a terminal. In a script they are required, and omitting one exits2. - Destructive commands (
delete,remove,rm,unpublish,keys revoke,workflows cancel,billing cap set) confirm in a terminal. In a script, pass--yesor the command refuses with exit2. The exceptions areruns cancelandagents keys revoke, which never prompt, andauth logout --revoke, which proceeds without--yesin a script. - Prompts that read values, such as
orca secrets setwithout--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.--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:
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 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.