# Jaz Cli

> >-

- **Type:** Skill
- **Install:** `agentstack add skill-teamtinvio-jaz-ai-cli`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [teamtinvio](https://agentstack.voostack.com/s/teamtinvio)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [teamtinvio](https://github.com/teamtinvio)
- **Source:** https://github.com/teamtinvio/jaz-ai/tree/main/cli/assets/skills/cli
- **Website:** https://www.jaz.ai

## Install

```sh
agentstack add skill-teamtinvio-jaz-ai-cli
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Clio CLI Skill

> **Audience note:** for power users and CI/automation. Load this skill only when you're scripting from a terminal, building shell pipelines, or debugging from `clio --json` output. For day-to-day accounting inside Claude Desktop / Cowork, the MCP tools cover the common flows without dropping to the CLI.

You are working with **Clio** (`jaz-clio`) — the CLI for the Jaz accounting platform. 65 command groups, 13 calculators, 12 job blueprints, 356 tools. Also fully compatible with Juan Accounting (same API, same endpoints).

## When to Use This Skill

- Running or composing `clio` commands from the terminal
- Building shell scripts or CI pipelines that automate Jaz workflows
- Debugging authentication issues (wrong org, missing key, env var conflicts)
- Understanding `--json` output structure for piping into `jq` or downstream tools
- Paginating large result sets (`--all`, `--limit`, `--offset`, `--max-rows`)
- Chaining multi-step accounting workflows (create -> finalize -> pay -> verify)
- Answering "what commands are available?" or "how do I do X from the CLI?"

## Skill Relationships

| Need | Skill |
|------|-------|
| CLI command syntax, flags, output | **jaz-cli** (this skill) |
| API field names, error codes, 141 gotchas | **jaz-api** |
| IFRS transaction recipes (depreciation, leases, loans) | **jaz-recipes** |
| Month-end close, bank recon, GST filing workflows | **jaz-jobs** |
| Migration from Xero/QuickBooks/Sage | **jaz-conversion** |

Use **jaz-cli** when running commands. Use **jaz-api** when debugging API errors or understanding field mappings.

## Auth Precedence

Resolution stops at the first match. Higher priority wins silently.

| Priority | Source | How to set |
|----------|--------|------------|
| 1 | `--api-key ` | Per-command flag |
| 2 | `JAZ_API_KEY` env | `export JAZ_API_KEY=jk-...` |
| 3 | `--org ` flag | Per-command profile lookup |
| 4 | `JAZ_ORG` env | `export JAZ_ORG=acme-sg` (pinned session) |
| 5 | Active profile | `clio auth switch ` (stored in `~/.config/jaz-clio/credentials.json`) |

**Critical gotcha**: If `JAZ_API_KEY` is set in your shell, it overrides `--org` and the active profile. Run `unset JAZ_API_KEY` before switching tenants with `clio auth switch`.

Auth subcommands:
```
clio auth add           # Validate key + save profile (auto-slugifies org name)
clio auth add  --as prod-sg   # Save with custom label
clio auth switch      # Set active profile
clio auth list               # Show all saved profiles
clio auth whoami             # Show current org + auth source
clio auth remove      # Delete a profile
clio auth clear              # Remove all profiles
clio auth shell-init         # Print shell exports (for eval)
clio auth unpin              # Unset JAZ_ORG from current shell
```

## Output Formats

Every command supports `--json`. Most list commands also support `--format `.

| Flag | Format | Use case |
|------|--------|----------|
| (default) | `table` | Human-readable, colored, truncated at 500 rows |
| `--json` | `json` | Structured JSON envelope for piping/scripting |
| `--format csv` | `csv` | Spreadsheet import |
| `--format yaml` | `yaml` | Config files, readable structured output |

JSON envelope for list commands:
```json
{ "totalElements": 142, "totalPages": 2, "truncated": false, "data": [...] }
```

When `truncated: true`, a `_meta` object appears with `fetchedRows` and `maxRows`.

Single-record commands (`get`, `create`) output the raw object in `--json` mode.

**Stderr vs stdout**: Resolution feedback (e.g., "Contact: Acme Corp (abc1234-...)") goes to stderr. Only data goes to stdout. This means `clio invoices list --json | jq .` works cleanly.

## Entity Resolution

Flags like `--contact`, `--account`, `--bank-account`, and `--tax-profile` accept either a UUID or a human-readable name. Resolution order:

1. **UUID passthrough** — if the value matches UUID format, use it directly (no API call)
2. **Server-side search** — contacts use name-contains search; accounts/tax-profiles fetch all (orgs have 50-200 accounts)
3. **Exact match** — case-insensitive match on billingName/name/code
4. **Fuzzy match** — score >= 0.7 auto-resolves; multiple close matches throw with candidates
5. **Error with suggestions** — shows available entities (up to 10) for the user to choose

Examples:
```bash
clio invoices create --contact "Acme"           # Fuzzy-resolves to "Acme Corp Pte Ltd"
clio invoices create --contact abc12345-...     # UUID passthrough, no API call
clio journals create --account "Bank - SGD"     # Resolves by account name
clio journals create --account "1000"           # Resolves by account code
```

> **IMPORTANT for agents:** Fuzzy matching works for `--contact` and top-level `--account` flags. It does NOT work inside `--lines` JSON arrays. Line item `accountResourceId` must be a UUID or exact account name.

**Resolve a name to a resourceId without writing anything:**
```bash
clio resolve account "Operating Expense" --json   # → {"resourceId":"...","displayName":"..."}
clio resolve bank "DBS Current" --json
clio resolve contact "Acme" --json
clio resolve tax-profile "Standard GST" --json
```
`clio resolve  ` runs the **same** resolver the write flags use (UUID→exact→fuzzy) and exits non-zero with candidates on an ambiguous/no match. Prefer it over `accounts search … | jq` when you just need the id: search is fuzzy and paginated (an exact name can be buried on a polluted org), whereas `resolve` fetches the full set and prefers an exact hit.

## Pagination

All list/search commands support pagination. Two modes:

**Single-page mode** (default):
```bash
clio invoices list                    # First 100 results
clio invoices list --limit 50         # First 50 results
clio invoices list --offset 2         # Page 3 (0-indexed)
```

**Auto-paginate mode** (`--all`):
```bash
clio invoices list --all              # Fetch all pages (concurrent, progress on stderr)
clio invoices list --all --max-rows 500   # Cap at 500 rows
clio invoices list --all --json       # Full dataset as JSON (progress suppressed)
```

Rules:
- `--all` and `--offset` cannot be combined (throws error)
- **Default `--max-rows` is 1,000** (lowered from 10,000 in 2026-04 — fan-out lookups like attachment counts in `bills draft list` could spiral on busy accounts). Pass `--max-rows N` explicitly when you need more.
- **`--max-rows` now caps the FETCH, not just the slice** (early-stop in `paginatedFetch`). Previously it pulled every page then sliced — multi-minute hangs on large datasets.
- Table display caps at 500 rows regardless (use `--format json` for full output)
- Progress display on stderr is TTY-aware (suppressed for `--json` and pipes)
- **`bills draft list` / `invoices draft list` / `customer-credit-notes draft list` / `supplier-credit-notes draft list` fan out one attachment lookup per draft** (5 in flight). On accounts with hundreds of drafts, this is slow even with `--max-rows`. Pass `--max-rows 10` for spot checks; expect 30s+ wall time at higher counts.

## Common Flags

| Flag | Scope | Purpose |
|------|-------|---------|
| `--api-key ` | All online commands | Override auth for this command |
| `--org ` | All online commands | Use a specific saved profile |
| `--json` | All commands | Structured JSON output |
| `--format ` | List commands | table, json, csv, yaml |
| `--limit ` | List/search commands | Max results per page |
| `--offset ` | List/search commands | Page offset (0-indexed) |
| `--all` | List/search commands | Auto-paginate all pages |
| `--max-rows ` | With `--all` | Cap total rows (default 10,000) |
| `--finalize` | Create commands | Approve immediately (skip draft) |
| `--date ` | Create/update commands | Transaction date |
| `--due ` | Create/update commands | Due date |
| `--query ` | Search commands (14 entities) | Jaz search expression (see below) |
| `--filter ` | Search commands | Raw API filter JSON (merged with flags; flags win) |
| `--status ` | Search commands | Filter by status |
| `--from / --to` | Search/report commands | Date range filter |
| `--contact ` | Transaction commands | Fuzzy-resolve contact |
| `--account ` | Transaction commands | Fuzzy-resolve account |
| `--ref ` | Search/create commands | Reference string |
| `--tag ` | Search/create commands | Tag filter or assignment |
| `--input ` | Create/update commands | Read full JSON body from file |
| `--plan` | Recipe commands | Offline plan mode (no auth) |

## Search Query Expressions (`--query`)

14 entity search commands accept `--query ` for human-readable filtering using Jaz search operators. Supported: `invoices`, `bills`, `customer-credit-notes`, `supplier-credit-notes`, `journals`, `cashflow`, `bank records`, `contacts`, `items`, `capsules`, `fixed-assets`, `subscriptions` (scheduled), `accounts`, `tax-profiles`.

```bash
# Status
clio invoices search --query "status:unpaid"
clio invoices search --query "status:unpaid AND $500+"
clio invoices search --query "(status:paid OR status:partial) AND date:this month"

# Amounts — bare $, ranges, suffixes (k=1k, m=1M, b=1B)
clio invoices search --query '$100-500'
clio invoices search --query 'amount:>2m'
clio invoices search --query 'amount:4k-5k'

# Absolute value — for mixed-sign fields (cashflow, journals)
clio cashflow search --query 'abs:1000+'

# Dates
clio invoices search --query "date:-30d"            # last 30 days
clio invoices search --query "due:overdue"          # past due + unpaid/partial
clio invoices search --query "date:jan-mar 2025"
clio invoices search --query "date:this quarter"
clio invoices search --query "submitted:last week"
clio invoices search --query "lastpayment:-7d"

# String fields
clio invoices search --query "customer:acme AND ref:INV-*"
clio invoices search --query 'ref:/INV-\d{8}/'     # regex
clio invoices search --query '=ref:INV-20260314'   # exact match (= prefix)
clio contacts search --query "customer:yes"
clio contacts search --query 'name:"Sakura Trading"'

# Blank / empty
clio invoices search --query "ref:blank"
clio invoices search --query "tag:!blank"

# Negation (never use - for negation)
clio invoices search --query "!status:void"
clio invoices search --query "NOT (status:paid OR status:void)"

# Multi-value (comma = OR)
clio invoices search --query "status:unpaid,partial"
clio invoices search --query "currency:SGD,USD,EUR"

# Combine --query with named flags (named flags win on conflict)
clio invoices search --query "date:this year" --status UNPAID

# Inline sort
clio invoices search --query "status:unpaid sort:amount:desc" --limit 10
```

**Gotchas**:
- Bad enum values (e.g. `--query "status:BADVALUE"`) return empty results silently — no error.
- Unknown field names return an error (`query_not_understood`).
- Unsupported entities have no `--query` flag (background-jobs, tags, contact-groups, etc.).
- Never use `-` for negation — it means negative amount (e.g. `$-500` = amount is -500). Use `!` or `NOT`.

See [references/search-reference.md](./references/search-reference.md) for the full syntax spec.

## Body Input

Create/update commands accept payloads three ways (priority order):

1. `--input ` — read JSON from a file
2. Stdin pipe — `echo '{"contact":...}' | clio invoices create`
3. CLI flags — `--contact "Acme" --date 2026-01-15 --lines '[...]'`

When `--input` or stdin provides a body, CLI flags are ignored.

### Bulk-upsert: FLAT vs NESTED variants

For invoices and bills, there are TWO bulk-upsert commands per entity:

- **FLAT** (`clio invoices bulk-upsert` / `clio bills bulk-upsert`) — ONE line per row. Each row carries `itemDescription` + `totalAmount` + `invoiceAccountResourceId` (or `billAccountResourceId`) at the top level. Use for CSV-like imports where each row = one transaction with a single line.
- **NESTED** (`clio invoices bulk-upsert-line-items` / `clio bills bulk-upsert-line-items`) — multi-line per row. Each row carries nested `lineItems[]` with per-line `itemDescription` + `quantity` + `unitPrice` + `accountResourceId`. Use when each transaction needs multiple lines.

Sending `lineItems[]` to the FLAT endpoint silently ignores them and creates a $0 transaction. Sending the FLAT shape to the NESTED endpoint creates an empty `lineItems` array and 422s. Match the variant to your data shape.

## Command Quick Reference

**Transactions**: `invoices`, `bills`, `customer-credit-notes`, `supplier-credit-notes`, `journals`, `cash-in`, `cash-out`, `cash-transfer`, `payments`, `cashflow`

**Contacts & Configuration**: `contacts`, `contact-groups`, `accounts`, `items`, `tags`, `currencies`, `currency-rates`, `tax-profiles`, `custom-fields`, `bookmarks`, `nano-classifiers`

**Bank & Reconciliation**: `bank` (accounts, get, records, add-records, import, auto-recon), `bank-rules`

**Employee Claims & Settings**: `claims` (lifecycle + `create` + `from-attachment` + convert + payout), `employees`, `claim-types`, `claim-profiles`, `posting-rules`

**Fixed Assets & Inventory**: `fixed-assets` (alias: `fa`), `inventory` (alias: `inv`)

**Subscriptions & Schedulers**: `subscriptions` (alias: `subs`), `schedulers`

**Reports & Exports**: `reports` (16 report types), `exports`

**AI & Automation**: `magic` (create, status, search, split), `quick-fix`, `capsules`, `capsule-transaction` (alias: `ct`, 13 recipe types)

**Calculators**: `calc` (loan, lease, depreciation, prepaid-expense, deferred-revenue, fx-reval, ecl, provision, fixed-deposit, asset-disposal, accrued-expense, leave-accrual, dividend)

**Jobs**: `jobs` (month-end, quarter-end, year-end, bank-recon, gst-vat, payment-run, credit-control, supplier-recon, audit-prep, fa-review, document-collection, statutory-filing) + tools (match, outstanding, ingest, sg-cs, sg-ca)

**Organization**: `org` (info), `org-users`, `auth`

**Introspection**: `schema` (list groups, inspect tools, show params), `health` (version, connectivity, environment checks)

**Utilities**: `help-center` (alias: `hc`), `context`, `mcp`, `serve`, `init`, `versions`, `update`

See `references/command-catalog.md` for the full catalog with subcommands and flags.

## Offline vs Online

Offline commands (no auth needed): `calc`, `jobs` (blueprints only), `capsule-transaction --plan`, `help-center`, `init`, `versions`, `update`

Everything else requires authentication (API key).

## Dashboard Deep Links (no CLI command — by design)

The navigation tools (`get_dashboard_url`, `find_dashboard_destinations`) build dashboard URLs for the user ("open this invoice", "take me to the P&L"). They are agent/MCP tools only — read-only tools get no CLI twin (one canonical surface per operation). Never hand-construct a dashboard URL in a script; if you need a link, call the MCP tool. Full usage rules live in the jaz-api skill under "Dashboard Deep Links".

## Error Handling

CLI commands exit with standard codes:
- **Exit 0** — success
- **Exit 1** — user error (missing flags, invalid input, validation failure)
- **Exit 2** — auth error (invalid key, unreachable API)

Error messages go to stderr. When `--json` is set, the error is still on stderr so stdout stays parseable. Common errors:

```bash
# Missing required flag
Error: missing required option(s): --contact, --lines

# Fuzzy resolution ambiguity
Multiple contacts match "Acme":
  Acme Corp Pte Ltd (92%)
  Acme Holdings (87%)
Be more specific, or use the full billingName.

# Auth not configured
No API key configured. Run `clio auth add `, set JAZ_API_KEY, or pass --api-key.

# API validation error (422)
API error 422: lineItems[0].accountResourceId is required when saveAsDraft is false
```

## Draft Validation

Transaction create commands (`invoices`, `bills`, `customer-credit-notes`, `supplier-credit-notes`, `journals`) perform client-side draft validation before hitting the API. The validation:

1. Checks required fields are present (contact, date, at least one line item)
2. Sanitizes line items (strips unknown fields, normalizes dates)
3. Prints a draft report showing what will be created
4

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [teamtinvio](https://github.com/teamtinvio)
- **Source:** [teamtinvio/jaz-ai](https://github.com/teamtinvio/jaz-ai)
- **License:** MIT
- **Homepage:** https://www.jaz.ai

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-teamtinvio-jaz-ai-cli
- Seller: https://agentstack.voostack.com/s/teamtinvio
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
