# @actual-app/cli > **WARNING:** This CLI is experimental. Command-line interface for [Actual Budget](https://actualbudget.org). Query and modify your budget data from the terminal — accounts, transactions, categories, payees, rules, schedules, and more. > **Note:** This CLI connects to a running [Actual sync server](https://actualbudget.org/docs/install/). It does not operate on local budget files directly. ## Installation ```bash npm install -g @actual-app/cli ``` Requires Node.js >= 22. ## Quick Start ```bash # Set connection details export ACTUAL_SERVER_URL=http://localhost:5006 export ACTUAL_PASSWORD=your-password export ACTUAL_SYNC_ID=your-sync-id # Found in Settings → Advanced → Sync ID # List your accounts actual accounts list # Check a balance actual accounts balance # View this month's budget actual budgets month 2026-03 ``` ## Configuration Configuration is resolved in this order (highest priority first): 1. **CLI flags** (`--server-url`, `--password`, etc.) 2. **Environment variables** 3. **Config file** (via [cosmiconfig](https://github.com/cosmiconfig/cosmiconfig)) 4. **Defaults** (`dataDir` defaults to `~/.actual-cli/data`) ### Environment Variables | Variable | Description | | ---------------------- | ----------------------------------------------------- | | `ACTUAL_SERVER_URL` | URL of the Actual sync server (required) | | `ACTUAL_PASSWORD` | Server password (required unless using token) | | `ACTUAL_SESSION_TOKEN` | Session token (alternative to password) | | `ACTUAL_SYNC_ID` | Budget Sync ID (required for most commands) | | `ACTUAL_DATA_DIR` | Local directory for cached budget data | | `ACTUAL_CACHE_TTL` | Cache TTL in seconds (default: 60) | | `ACTUAL_LOCK_TIMEOUT` | Budget-dir lock wait timeout in seconds (default: 10) | | `ACTUAL_NO_LOCK` | Set to `1` to disable budget-dir locking | ### Config File Create an `.actualrc.json` (or `.actualrc`, `.actualrc.yaml`, `actual.config.js`): ```json { "serverUrl": "http://localhost:5006", "password": "your-password", "syncId": "1cfdbb80-6274-49bf-b0c2-737235a4c81f", "cacheTtl": 60, "lockTimeout": 10, "noLock": false } ``` **Security:** Do not store plaintext passwords in config files (e.g. `.actualrc.json`, `.actualrc`, `.actualrc.yaml`, `actual.config.js`). Add these files to `.gitignore` if they contain secrets. Prefer the `ACTUAL_SESSION_TOKEN` environment variable instead of the `password` field. See [Environment Variables](#environment-variables) for using a session token. ### Global Flags | Flag | Description | | ------------------------- | ----------------------------------------------- | | `--server-url ` | Server URL | | `--password ` | Server password | | `--session-token ` | Session token | | `--sync-id ` | Budget Sync ID | | `--data-dir ` | Data directory | | `--cache-ttl ` | Cache TTL; `0` disables caching (default: 60) | | `--refresh` | Force a sync on this call, ignoring the cache | | `--no-cache` | Alias for `--refresh` | | `--lock-timeout ` | Lock wait timeout (default: 10) | | `--no-lock` | Disable budget-dir locking (use with care) | | `--format ` | Output format: `json` (default), `table`, `csv` | | `--verbose` | Show informational messages | ## Commands | Command | Description | | ----------------- | ------------------------------ | | `accounts` | Manage accounts | | `budgets` | Manage budgets and allocations | | `categories` | Manage categories | | `category-groups` | Manage category groups | | `transactions` | Manage transactions | | `payees` | Manage payees | | `tags` | Manage tags | | `rules` | Manage transaction rules | | `schedules` | Manage scheduled transactions | | `query` | Run an ActualQL query | | `server` | Server utilities and lookups | | `sync` | Refresh or inspect local cache | Run `actual --help` for subcommands and options. ### Examples ```bash # List all accounts (as a table; excludes closed by default) actual accounts list [--include-closed] --format table # Find an entity ID by name actual server get-id --type accounts --name "Checking" # Add a transaction (amount in integer cents: -2500 = -$25.00) actual transactions add --account \ --data '[{"date":"2026-03-14","amount":-2500,"payee_name":"Coffee Shop"}]' # Export transactions to CSV actual transactions list --account \ --start 2026-01-01 --end 2026-12-31 --format csv > transactions.csv # Set budget amount ($500 = 50000 cents) actual budgets set-amount --month 2026-03 --category --amount 50000 # Run an ActualQL query actual query run --table transactions \ --select "date,amount,payee" --filter '{"amount":{"$lt":0}}' --limit 10 ``` ### Amount Convention All monetary amounts are **integer cents** when passed as input (flags, JSON): | CLI Value | Dollar Amount | | --------- | ------------- | | `5000` | $50.00 | | `-12350` | -$123.50 | **Output formatting:** Table (`--format table`) and CSV (`--format csv`) output automatically converts cent values to decimal (e.g. `1665.00` instead of `166500`). JSON output always returns raw cents for programmatic use. ### Tips & Common Pitfalls - **Split transactions:** When summing or counting transactions, filter `"is_parent": false` to avoid double-counting. A split parent holds the total amount, and its children hold the individual parts — including both would count the total twice. - **Rapid sequential requests:** The CLI caches the budget locally (see [Caching](#caching)), so read-heavy scripts no longer need a single-query workaround by default. For very chatty scripts, run `actual sync` once and then use a long `--cache-ttl` for reads: ```bash actual sync actual --cache-ttl 3600 query run ... actual --cache-ttl 3600 accounts list ``` - **Uncategorized transactions:** `category.name` is `null` for transactions without a category. Account for this when filtering or grouping by category. - **No date sub-fields in AQL:** `date.month`, `date.year`, etc. are not supported as query fields. To group by month, fetch raw transactions with a date range filter and aggregate locally in a script. ## Caching The CLI keeps a local copy of your budget so repeated commands don't hit the sync server on every call. Within the TTL (default `60` seconds), read commands (`list`, `balance`, `query run`, …) reuse the cached budget without a network round-trip. Write commands (`add`, `update`, `set-amount`, …) always sync with the server before and after the write. - `actual sync` — refresh the cache now. - `actual sync --status` — show how stale the local cache is. - `actual sync --clear` — delete the local cache; the next command re-downloads. - `--refresh` (or `--no-cache`) — force a sync on a single call. - `--cache-ttl ` — override the TTL for a single call (use `0` to disable caching). ### Concurrency The CLI takes a shared lock for reads and an exclusive lock for writes on the per-budget cache directory. Many parallel reads are safe; writes serialize. If another CLI process is holding the lock, subsequent invocations wait up to `--lock-timeout` seconds (default `10`) before failing with an error. Pass `--no-lock` to opt out in trusted single-process setups. ## Running Locally (Development) If you're working on the CLI within the monorepo: ```bash # 1. Build the CLI yarn build:cli # 2. Start a local sync server (in a separate terminal) yarn start:server-dev # 3. Open http://localhost:5006 in your browser, create a budget, # then find the Sync ID in Settings → Advanced → Sync ID # 4. Run the CLI directly from the build output ACTUAL_SERVER_URL=http://localhost:5006 \ ACTUAL_PASSWORD=your-password \ ACTUAL_SYNC_ID=your-sync-id \ node packages/cli/dist/cli.js accounts list # Or use a shorthand alias for convenience alias actual-dev="node $(pwd)/packages/cli/dist/cli.js" actual-dev budgets list ```