Structured output

The --output json and --json shapes, which commands support each, and where neither exists.

Structured output

Most commands can print structured JSON instead of a Rich table or a confirmation message, for scripts and agents. Verified by running one command from every group against a live organization.

Two different flags, not one

The CLI's own design decision (docs/v2/cli/decisions/0005-output-json-convention.md) says every command takes --output json, with up0 tail as the one documented exception (--json, because it streams). As shipped, four more commands also use a bare --json boolean flag instead of --output: up0 deploy, up0 monitors, up0 metrics, and up0 import. The table below documents what each command actually accepts today — check it rather than assuming --output json works everywhere.

--output json (default: table)

These commands take --output, defaulting to a human table, and print the same data as JSON when you pass json:

CommandShape
up0 whoami --output jsonone object
up0 tokens create/list/revoke --output jsonone object, or an array for list
up0 ingest test --output jsonone object
up0 service-accounts create/list/rotate/revoke --output jsonone object, or an array for list
up0 schema explain --output jsona flat array, one entry per spec field
up0 stats --output jsonone object with a series array
up0 whoami --output json
{"logged_in": true, "identity": "you@example.com", "profile": "default", "org_id": "1f1317e4-...", "org_name": "your org", "org_slug": "your-org", "api_url": "https://api.up0.io", "issuer": "https://auth.up0.io", "expires_at": "2026-09-16T21:31:50.953934+00:00", "expired": false, "secret_store": "keyring", "env_overrides": []}

up0 stats --output json is the same object up0 stats renders as two or three tables — series holds one entry per signal/dimension pair, each with a total, unit, is_estimate flag, and (when a range was given) a bucketed points array. A dimension or bucket with nothing measured yet renders null in JSON (no data/- in the table), never a computed 0 — an actual 0 is a real reading and is shown as one.

--json (default: off)

These commands take a bare boolean --json flag instead — pass it to get JSON, omit it for the human view:

CommandShape
up0 deploy create/finish/list --jsonone object, or {"items": [...]} for list
up0 monitors list/bind/unbind --jsonan array for list, one object for bind/unbind
up0 metrics ls/query --jsonone object
up0 import --json{"written": [...], "excluded_kinds": {...}}
up0 monitors list --json
[{"id": "924dfcbe-...", "name": "payments-health", "type": "http", "url": "https://example.com/health", "status": "down", "interval_seconds": 300, "last_check_at": "2026-09-16T20:32:02.710096Z", "last_response_time_ms": null, "created_at": "2026-09-16T13:29:31.037547Z", "uptime_24h": 0.0, "service_id": null, "service_name": null}]

up0 tail --json — newline-delimited, not a single object

tail streams, so --json prints one JSON object per matching record, one per line (JSON Lines), not a wrapped array — the shape a pipeline like up0 tail --json | jq expects:

up0 tail --type logs --since 1h --no-follow --json
{"timestamp": "2026-09-16T13:26:25.548778Z", "trace_id": "f8020ef0...", "span_id": "6cf3ac58...", "service_name": "checkout-api", "severity_text": "info", "severity_number": 9, "body": "downstream http call complete (target=https://example.com, status=200)", "row_id": "01a0aa65-..."}
{"timestamp": "2026-09-16T13:26:25.646493Z", "trace_id": "b27563ee...", "span_id": "a4bd5eef...", "service_name": "checkout-api", "severity_text": "error", "severity_number": 17, "body": "boom: deliberate example failure occurred", "row_id": "01a0aa65-..."}

If a poll matched more records than the render cap (--limit/-n, default 20), one extra line reports how many were left out of that poll rather than printing them all or silently dropping them:

{"summary": "... 78 more matching records this interval, showing latest 2 — narrow with --status/--service or increase your terminal's scrollback", "more": 78}

--json also suppresses the "no results in this window" note that the human view prints — stdout stays byte-clean JSON Lines, nothing else mixed in.

No structured output at all

up0 auth login, up0 auth logout, and up0 health print plain text and take no --output/--json flag — there's nothing to script against beyond the process exit code (non-zero on failure).

On this page