Output formats

Render BankSync CLI output as a table, JSON, NDJSON, CSV, YAML, or TOON, with a TTY-aware default and column control via --fields and --sort.

4 min read

On this page

Every command that returns data can render it in six formats. The CLI picks a sensible default based on where the output is going, so a human at a terminal gets a readable table and a pipeline gets clean JSON, both with no flag.

Formats at a glance#

Choose a format with -o (or --output). --json is a shorthand for -o json.

FormatFlagBest for
Table-o tableHumans at a terminal (the default on a TTY)
JSON-o json or --jsonScripts, jq, agents (the default when piped)
NDJSON-o ndjsonStreaming large pulls, one entity per line
CSV-o csvSpreadsheets and data tools
YAML-o yamlConfig-style, human-readable structured output
TOON-o toonToken-efficient tabular output for LLMs and agents

The TTY-aware default#

The default format depends only on whether stdout is a terminal:

  • Interactive terminal: table.
  • Piped or redirected (not a terminal): json.

So these two commands render differently even though neither passes a format flag:

Shell
banksync banks list            # prints a tablebanksync banks list | jq .     # emits JSON, because stdout is a pipe

This means banksync tx list --bank amex | jq and agent invocations "just work" without a flag. An explicit -o/--json always wins over the default.

Color and notices are for humans only

ANSI color, spinners, footers, and empty-state hints appear only in table output on a terminal. In any machine format, when piped, under --quiet, or in CI, stdout carries data and nothing else, so it stays safe to parse. NO_COLOR and --no-color disable color too.

Table#

The table renderer is the only one designed for reading. Text columns are left-aligned, numeric and amount columns are right-aligned, and a single status taxonomy renders the same glyph everywhere: a bank connection, a feed state, and a job status all map onto one set of symbols.

ID         STATUS       TYPE          WRITTEN   COMPLETEDjob_9f2a   ● completed  transactions      412   2m agojob_7c1b   ◐ syncing    transactions       -     -job_4d8e   ✗ failed     balances            0    1h ago
3 jobs · feed fed_123

The glyphs carry meaning even without color: active or ok, in progress, paused, failed. On terminals without Unicode they fall back to *, ~, o, and x.

JSON and the invariant envelope#

Every read renders the same top-level shape in -o json, whatever the command. Your code can always rely on .data and page with meta:

JSON
{  "data": [    { "id": "bnk_a1b2", "name": "Chase", "source": "plaid" },    { "id": "bnk_c3d4", "name": "Amex", "source": "plaid" }  ],  "meta": {    "count": 2,    "cursor": null,    "has_more": null,    "schema_version": "1",    "api_version": "v1"  }}
  • data is the entity or array of entities, with raw API fields (ISO dates, unformatted numbers). It is never humanized: no relative time, glyphs, or color.
  • meta.count is the number of items, meta.cursor and meta.has_more drive pagination (null when the endpoint does not paginate), meta.schema_version is the output-contract version, and meta.api_version is the API the CLI speaks.
  • An empty result is {"data":[], ...}, never a human "No banks yet" sentence.

Pipe it straight into jq:

Shell
banksync banks list --json | jq '.data[] | select(.source == "plaid") | .name'

NDJSON#

NDJSON emits one raw entity per line with no envelope, which is ideal for streaming large transaction pulls and for agents consuming incrementally:

Shell
banksync tx list --bank amex --all -o ndjson
{"id":"txn_1","date":"2026-03-01","description":"UBER","amount":-24.5,"currency":"USD"}{"id":"txn_2","date":"2026-03-01","description":"WHOLE FOODS","amount":-88.12,"currency":"USD"}

Each line is a complete JSON object, so it flows into jq -c, log processors, or a line-by-line reader without buffering the whole response.

CSV and YAML#

CSV writes a header row and one row per entity (nested values are JSON-encoded in the cell), which drops straight into a spreadsheet:

Shell
banksync tx list --bank amex -o csv > transactions.csv

YAML renders the same envelope as JSON in a config-style layout:

Shell
banksync feeds get fed_123 -o yaml

TOON#

TOON (Token-Oriented Object Notation) is a compact format built for LLMs and agents. A uniform array of objects becomes a tabular block where the field names appear once in a header and the row count is explicit, which both cuts token usage (roughly 30 to 40 percent versus JSON for tabular data) and makes the schema unambiguous to a model.

Shell
banksync feeds list -o toon
data[2]{id,name,source,dataType}:  fed_1,ANZ Everyday,fiskil,transactions  fed_2,Amex,plaid,transactionsmeta:  count: 2  cursor: null  has_more: null  schema_version: "1"  api_version: v1

JSON stays the default machine format; reach for TOON when you are optimizing an agent's token budget over tabular reads.

Pick your columns with --fields#

Every renderer accepts --fields to select columns by dot-path (arrays support indexing like errors[0].message). Discover the default columns for an entity with banksync schema <entity>.

Shell
banksync tx list --bank amex --fields date,description,amount,categorybanksync banks get bnk_a1b2 --fields id,name,connectionStatus.status

Sort rows with --sort#

--sort orders rows client-side. Prefix a field with - for descending, and pass several comma-separated keys for tie-breaks:

Shell
banksync tx list --bank amex --sort -amountbanksync jobs list fed_123 --sort -completedAt,status

--no-truncate keeps wide table cells from being clipped, --utc and --tz control timestamp display (for example --tz Australia/Sydney), and --locale sets number formatting. These affect the table renderer only; machine formats always emit raw ISO timestamps and numbers.

Next steps#

Use this page with your AI assistant

Every BankSync doc is available as plain Markdown for agents and LLMs.