@cashrunway/cli
v0.1.5
Published
Standalone CLI for reading cashflow data from a Cash Runway server.
Readme
@cashrunway/cli
A standalone command-line client for the Cash Runway agent API. Read-only — every command maps to a GET /api/agent/* endpoint behind your cr_live_… API key.
Install
npm install -g @cashrunway/cliRequires Node 20+.
Quickstart
# 1. Save credentials (verified against the server before they hit disk)
cashrunway auth login --token cr_live_xxx
# 2. Check plan + quota
cashrunway auth status
# 3. Composite "how's my business" surface
cashrunway cash summary
# 4. Aggregate reads (default window = current FY YTD)
cashrunway revenue summary --top-n 10
cashrunway expenses summary --from 2026-01-01 --to 2026-03-31
cashrunway contacts summary
# 5. Drill into invoices, bills, contacts, forecast
cashrunway cash position
cashrunway bank list
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 4Get a token from Settings → API keys in the Cash Runway dashboard.
READ_SUMMARY is the recommended starting scope — it unlocks
cash summary + the three revenue / expenses / contacts summary
commands and is 50× cheaper on tokens than paging through list_* for
aggregate questions.
Every command accepts --json for machine-readable canonical JSON output (keys sorted, ISO dates), so the CLI composes cleanly into shell pipelines:
cashrunway invoices list --status PAID --json | jq '.invoices[].amount'
cashrunway revenue summary --json | jq '.byStatus.PAID'For aggregate questions on the list endpoints, pass --auto-paginate
(one response, up to 5,000 rows) or --totals (folds byStatus +
grandTotal across the full filtered set). See the docs site
for the complete flag reference and output examples.
Configuration
Credentials live in ~/.config/cashrunway/config.json ($XDG_CONFIG_HOME honoured) with 0600 perms. To point at a non-default server, override the URL at login or via env var:
cashrunway auth login --url https://api.cashrunway.ai --token cr_live_xxx
# or
CASHRUNWAY_API_URL=http://localhost:3001 cashrunway auth statusMultiple companies / orgs
Each cr_live_* token is bound to a single org server-side, so a CLI invocation always queries the org of whichever token it's using. There are two patterns:
Named profiles — best for humans switching between known orgs:
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 invoices list --status AUTHORISED
cashrunway auth status --all # list saved profiles
cashrunway auth logout --profile lumen
cashrunway auth logout --allYou can also set CASHRUNWAY_PROFILE=lumen instead of passing --profile on every call. The first profile you save becomes the default; promote a different one with --profile X when running auth login, or delete the current default to auto-promote another.
Stateless --token — best for AI agents, CI, or any caller that already keeps its own token-to-company map:
cashrunway --token cr_live_xxx cash position
CASHRUNWAY_API_KEY=cr_live_xxx cashrunway invoices listA flag/env token skips the saved profile entirely; nothing is written to disk. Useful when you have many orgs and don't want a profile-rot problem, or when you want every command line to self-document which key it ran with.
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 precedence and can override the profile's URL while keeping its token.
Advisory partner keys (multi-client)
An advisory partner key is different: a single key reaches many client orgs. Discover the client set, then target one per command:
# 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_xxxorgs list reports keyKind (PARTNER vs USER); for an ordinary org
key it simply lists the single org the key 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.
Scopes
The API key carries scopes; each command states the scope it needs.
| Command | Scope |
| --- | --- |
| auth status | any |
| bank list | READ_BANK |
| cash position, forecast | READ_FORECAST |
| cash summary | READ_SUMMARY |
| revenue summary, expenses summary, contacts summary | READ_SUMMARY |
| invoices list, bills list | READ_INVOICES |
| contacts list, contacts show | READ_CONTACTS |
The optional READ_SENSITIVE scope unlocks names of accounts and contacts the operator has flagged sensitive. Without it, sensitive rows are either dropped from list endpoints or have their display name rewritten to Sensitive account / Sensitive contact on composite endpoints (totals are never masked). The CLI surfaces a redactedItemCount note whenever the response indicates a masked view.
Errors
The CLI prints concise, kind-tagged messages and exits non-zero:
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:
import { CashrunwayClient } from "@cashrunway/cli";
const client = new CashrunwayClient({
apiUrl: "https://api.cashrunway.ai",
apiToken: process.env.CASHRUNWAY_API_KEY!,
});
const cash = await client.getCashPosition();
console.log(cash.effectiveStartingCash);Development
pnpm install
pnpm test
pnpm buildLicense
MIT — see LICENSE.
