Skip to content

Cash Runway CLI

@cashrunway/cli is a standalone command-line client for the Cash Runway agent API. Every subcommand maps to one GET /api/agent/* endpoint behind your cr_live_… API key — read-only, no surprises. Use it for ad-hoc inspection, shell pipelines, CI checks, or as a stateless caller from an agent harness that already knows which token belongs to which org.

Install

bash
npm install -g @cashrunway/cli

Requires Node.js ≥ 20.

Quickstart

bash
# 1. Save a token (verified against the server before it hits disk).
cashrunway auth login --token cr_live_xxxxxxxxxxxxxxxxxxxx

# 2. Check plan + quota.
cashrunway auth status

# 3. Bootstrap the session — composite "how's my business" surface.
cashrunway cash summary

# 4. Aggregate reads (FY YTD by default).
cashrunway revenue summary --top-n 10
cashrunway expenses summary --from 2026-01-01 --to 2026-03-31
cashrunway contacts summary

# 5. Drill into records.
cashrunway invoices list --status AUTHORISED --from 2026-01-01
cashrunway bills list --limit 25 --lines
cashrunway contacts list --type customer --sort revenue
cashrunway contacts show <contact-id>
cashrunway forecast --weeks 4

Get an API token from Settings → API keys in the Cash Runway dashboard. See API keys for scope picking, rotation, and the sensitive-data audit trail.

Subcommand reference

The CLI groups subcommands by domain. Every read-command accepts the shared auth flags (--token, --url, --profile).

CommandEndpointScope
cashrunway auth login --token <t> [--profile <name>] [--url <u>](login)
cashrunway auth logout [--profile <name>] [--all]
cashrunway auth status [--all]GET /api/agent/statusany
cashrunway cash positionGET /api/agent/cash-positionREAD_FORECAST
cashrunway cash summaryGET /api/agent/daily-summaryREAD_SUMMARY
cashrunway forecast [--scenario <id>] [--weeks <n>]GET /api/agent/forecastREAD_FORECAST
cashrunway invoices list [...filters]GET /api/agent/invoicesREAD_INVOICES
cashrunway bills list [...filters]GET /api/agent/billsREAD_INVOICES
cashrunway contacts list [...filters]GET /api/agent/contactsREAD_CONTACTS
cashrunway contacts show <id>GET /api/agent/contacts/{id}READ_CONTACTS
cashrunway contacts summary [--top-n <n>]GET /api/agent/contacts/summaryREAD_SUMMARY
cashrunway revenue summary [...filters]GET /api/agent/revenue/summaryREAD_SUMMARY
cashrunway expenses summary [...filters]GET /api/agent/expenses/summaryREAD_SUMMARY

There is no cashrunway bank accounts subcommand yet — the bank-accounts endpoint surfaces through cash position, which folds in per-account balances alongside the org-wide reconciled total.

Flag reference

Shared auth flags

Every read-command (cash, forecast, invoices, bills, contacts, revenue, expenses) accepts:

FlagEnv varNotes
--profile <name>CASHRUNWAY_PROFILEPick a saved profile. Default profile is default.
--token <token>CASHRUNWAY_API_KEYStateless. Skips the saved profile entirely. Best for agents / CI.
--url <url>CASHRUNWAY_API_URLOverride the API base URL (defaults to https://api.cashrunway.ai).

Precedence (highest first): --token flag → $CASHRUNWAY_API_KEY → saved profile selected by --profile / $CASHRUNWAY_PROFILE / config's default. The --url flag and $CASHRUNWAY_API_URL follow the same rules and can override the profile's URL while keeping its token.

List flags (invoices list, bills list)

FlagNotes
--status <csv>Filter by Xero status: DRAFT,SUBMITTED,AUTHORISED,PAID,VOIDED,DELETED. Comma-separated for OR.
--contact <id>Filter by contact id (use cashrunway contacts list to discover).
--from <YYYY-MM-DD>Lower bound on expectedDate (inclusive).
--to <YYYY-MM-DD>Upper bound on expectedDate (inclusive).
--cursor <cursor>Opaque pagination cursor returned by the previous page.
--limit <n>Rows per page (max 200).
--linesInclude lines[] (line-item expansion).
--auto-paginateServer-side auto-pagination: one response, up to 5,000 rows. Sets truncated: true if the cap is hit. Cursor is ignored.
--totalsOpt-in byStatus + grandTotal aggregation across the full filtered set. Sets totalsTruncated: true if the matched set exceeds 100,000 rows.
--jsonEmit canonical JSON instead of the table renderer.

totalCount is always returned (no flag needed) — pre-redaction count of rows matching the filter. Cheapest way to answer "how many?" without paying for --auto-paginate or --totals. May exceed page length when sensitive rows are dropped — see redactedItemCount for the delta.

Contacts flags (contacts list)

FlagNotes
--type <kind>One of customer, supplier, both.
--sort <key>One of revenue, spend, recent.
--cursor, --limit, --auto-paginate, --totals, --jsonAs above. --totals returns counts only (contacts have no $ axis).

Summary flags (revenue summary, expenses summary, contacts summary)

FlagNotes
--from <YYYY-MM-DD>Lower bound on the aggregation window (revenue / expenses only).
--to <YYYY-MM-DD>Upper bound (inclusive; expanded to end-of-day).
--top-n <n>Cap on topContacts length (1–100, default 10).
--jsonCanonical JSON output.

When --from / --to are omitted, revenue summary and expenses summary default to the current financial-year YTD per the org's Xero financialYearEndDay/Month setting. Calendar-month buckets use the org's IANA timezone (default Australia/Sydney).

Forecast flags

FlagNotes
--scenario <id>Scenario id; defaults to the org's BASE scenario.
--weeks <n>Limit the number of weeks shown (positive integer).
--jsonCanonical JSON.

Output formats

The CLI renders compact tables by default and falls back to canonical JSON with --json. Tables are designed for human eyes; JSON is sorted keys + ISO dates so it composes safely into shell pipelines.

Pretty (default)

text
$ cashrunway revenue summary --top-n 3

Revenue summary as of 2026-05-24 (FY2026 YTD)
  Currency: AUD
  Grand total (PAID, ex-GST): $1,099,419.91 (847 invoices)
  By status:
    PAID         $1,099,419.91  847 invoices
    AUTHORISED   $   84,210.00   42 invoices

Top customers (by PAID ex-GST):
  Globex Industries       $312,000.00   18 invoices
  Acme Holdings           $214,500.00   24 invoices
  Initech Pty Ltd         $187,300.00   33 invoices

JSON

bash
$ cashrunway revenue summary --top-n 3 --json | jq '.byStatus.PAID'
{
  "count": 847,
  "amount": "1099419.91"
}

Compose into pipelines:

bash
cashrunway invoices list --status PAID --json | jq '.invoices[].amount'
cashrunway forecast --json | jq '.weeks[] | {weekStart, closing, net}'

Profiles and multi-company use

Each cr_live_* token is bound to one org server-side, so a CLI invocation always queries the org of whichever token it's using. Two patterns:

bash
# Named profiles — switch between known orgs by name.
cashrunway auth login --profile lumen --token cr_live_xxx
cashrunway auth login --profile acme  --token cr_live_yyy

cashrunway --profile lumen cash position
cashrunway --profile acme  revenue summary

cashrunway auth status --all      # list saved profiles
cashrunway auth logout --profile lumen
cashrunway auth logout --all

# Stateless --token — best for agents, CI, or self-documenting commands.
cashrunway --token cr_live_xxx cash position
CASHRUNWAY_API_KEY=cr_live_xxx cashrunway invoices list

Credentials live in ~/.config/cashrunway/config.json ($XDG_CONFIG_HOME honoured) with 0600 perms. The first profile you save becomes the default; promote a different one by passing --profile X to auth login, or delete the current default to auto-promote another.

Advisory partner keys (multi-client)

Advisors (accountants, bookkeepers, business coaches, fractional CFOs) install the same CLI — they just authenticate with a partner key instead of a single-org user key. A partner key starts with crun_… and reaches every client org linked to your practice, where a cr_live_… user key is bound to one org. Partner keys are minted in the Partner Portal → API keys, not under an individual business's Settings → API keys.

Discover the client set, then target one client per command:

bash
# 1. Who am I, and which clients can I reach?
cashrunway orgs list --token crun_xxx
#   → "Connected as partner → 3 clients."
#   → a table of { Org id, Name, Slug }

# 2. Run a per-client command against a chosen org.
cashrunway brief --org <org-id> --token crun_xxx

orgs list reports keyKind (PARTNER vs USER): a user key simply lists the single org it belongs to. brief --org <id> fetches that client's latest daily brief — the org id is sent in the request path, which the agent API honours as the per-request org for partner keys. Usage is metered to each client's account.

Errors

The CLI prints concise, kind-tagged messages and exits non-zero:

text
error: quota_exhausted — daily quota exhausted
Retry after 42s.

Error kinds: auth_required, invalid_scope, quota_exhausted, not_found, bad_request, server_error, network_error, validation_error.

Programmatic use

The package also exposes the typed client for direct embedding:

ts
import { CashrunwayClient } from "@cashrunway/cli";

const client = new CashrunwayClient({
  apiUrl: "https://api.cashrunway.ai",
  apiToken: process.env.CASHRUNWAY_API_KEY!,
});

const summary = await client.getRevenueSummary({ topN: 5 });
for (const c of summary.topContacts) {
  console.log(`${c.name}: ${c.amount}`);
}
  • API keys — provisioning, rotation, audit.
  • Agent API — endpoint surface and daily-summary tour.
  • API Reference — full schema catalogue.
  • MCP server — same surface for Claude Desktop / Cursor / Continue.

Released under a proprietary license.