---
title: "Output formats"
description: "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."
section: "CLI"
canonical: "https://banksync.io/docs/cli/output-formats"
---

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`.

| Format | Flag                  | Best for                                           |
| ------ | --------------------- | -------------------------------------------------- |
| Table  | `-o table`            | Humans at a terminal (the default on a TTY)        |
| JSON   | `-o json` or `--json` | Scripts, jq, agents (the default when piped)       |
| NDJSON | `-o ndjson`           | Streaming large pulls, one entity per line         |
| CSV    | `-o csv`              | Spreadsheets and data tools                        |
| YAML   | `-o yaml`             | Config-style, human-readable structured output     |
| TOON   | `-o toon`             | Token-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:

```bash
banksync banks list            # prints a table
banksync 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.

```text
ID         STATUS       TYPE          WRITTEN   COMPLETED
job_9f2a   ● completed  transactions      412   2m ago
job_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:

```bash
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:

```bash
banksync tx list --bank amex --all -o ndjson
```

```text
{"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:

```bash
banksync tx list --bank amex -o csv > transactions.csv
```

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

```bash
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.

```bash
banksync feeds list -o toon
```

```text
data[2]{id,name,source,dataType}:
  fed_1,ANZ Everyday,fiskil,transactions
  fed_2,Amex,plaid,transactions
meta:
  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>`.

```bash
banksync tx list --bank amex --fields date,description,amount,category
banksync 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:

```bash
banksync tx list --bank amex --sort -amount
banksync jobs list fed_123 --sort -completedAt,status
```

## Related flags

`--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

- [Scripting and CI](/docs/cli/scripting-and-ci): exit codes and non-interactive output.
- [For agents](/docs/cli/for-agents): the JSON contract and runtime discovery.
- [Syncing and jobs](/docs/cli/syncing-and-jobs): trigger and watch syncs.
