CLI

Output formats

Every command takes the same set of global output flags. With none of them you get a human-readable table, colored for the terminal.

FlagOutput
(default)Human-readable, colored, table-formatted
--jsonPretty-printed JSON
--jq <expr>JSON filtered through a jq expression in-process
--template <tpl>Output formatted with a Go text/template
--csvCSV (only honored by l4 export * commands)
--quiet / -qNo output; the exit code is the signal
--no-colorDisable ANSI colors (also NO_COLOR=1)
--web / -wOpen the equivalent dashboard URL instead
--quiet is mutually exclusive with --json, --jq, --template and --csv. Combining them is a usage error.

--json

Use --json to pipe into another tool, or when you want a shape that will not move under you. The JSON envelope is the same shape returned by the underlying API:

l4 recommendations list --json
{
  "data": {
    "success": true,
    "data": {
      "total_savings": 23545.31,
      "items": ["..."],
      "pagination": {
        "total_items": 204,
        "total_pages": 41,
        "current_page": 1,
        "page_size": 5,
        "has_next": true,
        "has_previous": false
      }
    },
    "timestamp": "2026-04-27T11:00:00Z"
  }
}

The values above are invented. The field names and their nesting are the ones the CLI emits, and Pagination covers the envelope fields inside data.

JSON paths are stable across releases. Script against them.

--jq

--jq filters the JSON output through an embedded jq expression in a single process. It runs faster than spawning jq separately, and it works where jq is not installed:

l4 recommendations list --jq '.data.data.items[] | {id: .recommendation_id, savings: .monthly_savings}'

Equivalent to:

l4 recommendations list --json | jq '.data.data.items[] | {id: .recommendation_id, savings: .monthly_savings}'

For complex multi-step pipelines (slurps, branches, table formatting), prefer the explicit pipe so each stage is debuggable. See Recipes.

Filtering and sorting has the quirks worth knowing before you write one: what --jq will not do, and why the envelope path is not the same on every command.

--template

Format the output with a Go text/template when a downstream tool wants a plain-text shape that is not quite CSV:

l4 costs summary --template '{{ range .data.providers }}{{ .provider_name }}: ${{ .monthly_spending }}/mo{{ "\n" }}{{ end }}'

--csv

Only the l4 export * commands honor --csv. On other commands a warning is printed and the format falls back to the default, so redirecting one into a .csv leaves a table in the file.

Use l4 export for spreadsheet imports:

l4 export costs --period 90d --format csv > costs.csv

l4 export has the rest, including --out and the recommendations export.

--quiet

--quiet suppresses all stdout and stderr. Use it as a boolean check or as a CI guardrail:

l4 estimate --fail-above 500 -q ./infra/ && echo "Within budget" || echo "Over budget"
--quiet prints nothing at all, on success and on failure alike, so read the result from $? against the exit codes.

l4 estimate has the CI guardrail this example comes from.

--web

Skip the terminal output and open the equivalent page in the dashboard:

l4 recommendations view REC-001 --web

The CLI computes the dashboard URL by replacing api. with dashboard. in the active API base.

l4 recommendations view has the command this example comes from.

--no-color

Either of these turns color off:

l4 costs summary --no-color
NO_COLOR=1 l4 costs summary

The CLI also drops color when stdout is not a TTY, piped or redirected, so neither case needs the flag.

Next