# CLI Scripting & Piping

The Bkper CLI is designed for scripting. Every command supports multiple output formats, and selected write commands accept piped JSON input — making it easy to build data pipelines, batch operations, and automated workflows.

## Output formats

All commands support three output formats via the `--format` global flag:

| Format | Flag                       | Best for                                |
| ------ | -------------------------- | --------------------------------------- |
| Table  | `--format table` (default) | Human reading in the terminal           |
| JSON   | `--format json`            | Programmatic access, single-item detail |
| CSV    | `--format csv`             | Spreadsheets, AI agents, data pipelines |

```bash
# Table output (default)
bkper account list -b abc123

# JSON output
bkper account list -b abc123 --format json

# CSV output -- raw data, no truncation, RFC 4180
bkper account list -b abc123 --format csv
```

**CSV output details:**

- RFC 4180 compliant — proper quoting, CRLF line endings, no truncation
- All metadata included — IDs, properties, hidden properties, URLs, and timestamps
- Raw values — dates in ISO format, numbers unformatted

> **Tip: AI agent guidance**
> When using the CLI from an AI agent or automated script, prefer `--format csv` for list commands, `--format json` for single-item commands (`get`, `create`, `update`), and stdin piping for batch operations.
## Query semantics quick reference

Use these rules in scripts to avoid ambiguous or empty results:

- `on:` supports year, month, and day (`on:2025`, `on:2025-01`, `on:2025-01-31`).
- `after:` is **inclusive** and `before:` is **exclusive**.
- A full-year range uses next-year boundary:
    - `after:2025-01-01 before:2026-01-01`

```bash
# Full year with on:
bkper transaction list -b $BOOK_ID -q "on:2025" --format csv

# Same full year with explicit boundaries
bkper transaction list -b $BOOK_ID -q "after:2025-01-01 before:2026-01-01" --format csv
```

## Batch operations

Write commands (`account create`, `transaction create`, `transaction update`) accept JSON piped via stdin. The input format follows the [Bkper API Types](https://raw.githubusercontent.com/bkper/bkper-api-types/refs/heads/master/index.d.ts) — a single JSON object or an array of objects.

Groups are created explicitly with `bkper group create --name` and optional `--parent`, so hierarchy stays deterministic.

### Creating in batch

```bash
# Create transactions from JSON
echo '[{
  "date": "2025-01-15",
  "amount": "100.50",
  "creditAccount": {"name": "Bank Account"},
  "debitAccount": {"name": "Office Supplies"},
  "description": "Printer paper",
  "properties": {"invoice": "INV-001"}
}]' | bkper transaction create -b abc123

# Create accounts
echo '[{"name":"Cash","type":"ASSET"},{"name":"Revenue","type":"INCOMING"}]' | \
  bkper account create -b abc123

# Create a group explicitly
bkper group create -b abc123 --name "Fixed Costs" --hidden

# Pipe from any script that outputs JSON
python export_bank.py | bkper transaction create -b abc123
```

Batch results are output as a flat JSON array:

```bash
bkper account create -b abc123 < accounts.json
# [{"id":"acc-abc","name":"Cash",...}, {"id":"acc-def","name":"Revenue",...}]
```

### Adding properties via CLI flag

The `--property` flag can add or override properties from the stdin payload:

```bash
echo '[{"name":"Cash","type":"ASSET"}]' | \
  bkper account create -b abc123 -p "region=LATAM"
```

## Piping between commands

All JSON output is designed to feed directly into other commands. This is the most powerful pattern — combining commands into pipelines:

### Copy data between books

```bash
# Copy all accounts from one book to another
bkper account list -b $BOOK_A --format json | bkper account create -b $BOOK_B

# Copy transactions matching a query
bkper transaction list -b $BOOK_A -q "after:2025-01-01" --format json | \
  bkper transaction create -b $BOOK_B
```

Recreate groups explicitly with `bkper group create --name ... --parent ...` before copying accounts that reference them.

### Clone a full chart of accounts

```bash
# Recreate the group hierarchy explicitly
bkper group create -b $DEST --name "Assets"
bkper group create -b $DEST --name "Current Assets" --parent "Assets"

# Then copy accounts and transactions
bkper account list -b $SOURCE --format json | bkper account create -b $DEST
bkper transaction list -b $SOURCE -q "after:2025-01-01" --format json | \
  bkper transaction create -b $DEST
```

### Batch updates with jq

Use [jq](https://jqlang.github.io/jq/) to transform data between commands:

```bash
# List transactions, modify descriptions, pipe back to update
bkper transaction list -b $BOOK -q "after:2025-01-01" --format json | \
  jq '[.[] | .description = "Updated: " + .description]' | \
  bkper transaction update -b $BOOK

# Add a property to all matching transactions
bkper transaction list -b $BOOK -q "account:Expenses" --format json | \
  bkper transaction update -b $BOOK -p "reviewed=true"

# Batch update checked transactions
bkper transaction list -b $BOOK -q "is:checked after:2025-01-01" --format json | \
  bkper transaction update -b $BOOK --update-checked -p "migrated=true"
```

### Daily export

```bash
#!/bin/bash
# Export yesterday's transactions to CSV
DATE=$(date -d "yesterday" +%Y-%m-%d)
bkper transaction list -b $BOOK_ID \
  -q "on:$DATE" \
  --format csv > "export-$DATE.csv"
```

### Bulk categorization

```bash
#!/bin/bash
# Add a property to all uncategorized transactions
bkper transaction list -b $BOOK_ID \
  -q "account:Uncategorized" \
  --format json | \
  bkper transaction update -b $BOOK_ID -p "needs_review=true"
```

## Combining with other tools

The CLI works with standard Unix tools:

```bash
# Count transactions matching a query
bkper transaction list -b $BOOK_ID -q "after:2025-01-01" --format json | jq 'length'

# Extract specific fields with jq
bkper account list -b $BOOK_ID --format json | \
  jq '[.[] | {name, type}]'

# Sort by amount
bkper transaction list -b $BOOK_ID -q "after:1900-01-01" --format json | \
  jq 'sort_by(.amount | tonumber) | reverse'
```

## Full CLI reference

For the complete command reference including all options, see the [bkper-cli app page](https://bkper.com/apps/bkper-cli.md) or run `bkper --help`.
