* 🔖 (26.5.0)
* fix release note generation script (#7635)
* fix release note generation script
* note
* fix cherrypicked commits not being respected and lint race in release note generation workflow (#7640)
* fix cherrypicked commits not being respected and lint race
* note
* coderabbit suggestions
* fix lint
* make double restore possibility safe
* fix lint (#7643)
* Generate release notes for v26.5.0
* add release note highlights
* Fix Sankey income bug, when payee it not set (#7632)
* Ensure income categories are shown correct, even if payee is not set
* Add release note
* Generate release notes for v26.5.0
* increase test coverage for budget templates (#7620)
* [AI] cover existing template engine logic with regression tests
Adds tests for goal template behavior that predates this PR so the
suite can be cherry-picked onto master to confirm no regressions. No
production code changes.
Covers:
- init() validation: schedule names, by/schedule priority match, past
by-target with and without annual/repeat, percentage source not
found, special source aliases, duplicate limit/spend/goal
directives, weekly limit missing start date, invalid limit period,
unrecognized periodic period
- runRemainder cap clamping and hideDecimal fraction removal
- Income-category branch in runTemplatesForPriority
- getLimitExcess against an aggregate weekly cap
- Past by-target rolling forward via the annual period
- runSchedule full=true (no sinking accumulation), percent and fixed
adjustments, completed-schedule filtering, past-date error for
non-repeating schedules, monthly/weekly/daily sinking contribution
branches when interval exceeds the pay-month-of cap, surplus
absorption when last-month balance exceeds the target, and
tracking-budget mode forcing all schedules pay-month-of
- applyMultipleCategoryTemplates orchestration: per-category writes,
cross-category priority clamping when funds run out, error
notification path
- applyTemplate force=false skipping already-budgeted categories
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* note
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix infinite loop when remainder is impossible to solve (#7623)
* fix infinite loop when remainder is impossible to solve
* note
* Generate release notes for v26.5.0
* Update author
Updated author information in the release notes.
* Fix shared worker resumption after tab suspend (#7656)
* [AI] Fix SharedWorker tab resume recovery
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* [AI] Fix SharedWorker reload readiness
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add release notes
* Update packages/desktop-client/src/shared-browser-server-core.ts
Co-authored-by: Matiss Janis Aboltins <matiss@mja.lv>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Matiss Janis Aboltins <matiss@mja.lv>
* Update docs release date
* Empty commit to bump CI
* Generate release notes for v26.5.0
* Revert "Generate release notes for v26.5.0"
This reverts commit b42c48bed5.
---------
Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com>
Co-authored-by: Matt Fiddaman <github@m.fiddaman.uk>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Emil Tveden Bjerglund <emilbp@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Julian Dominguez-Schatz <julian.dominguezschatz@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@actual-app/cli
WARNING: This CLI is experimental.
Command-line interface for Actual Budget. 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. It does not operate on local budget files directly.
Installation
npm install -g @actual-app/cli
Requires Node.js >= 22.
Quick Start
# 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 <account-id>
# View this month's budget
actual budgets month 2026-03
Configuration
Configuration is resolved in this order (highest priority first):
- CLI flags (
--server-url,--password, etc.) - Environment variables
- Config file (via cosmiconfig)
- Defaults (
dataDirdefaults 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):
{
"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 for using a session token.
Global Flags
| Flag | Description |
|---|---|
--server-url <url> |
Server URL |
--password <pw> |
Server password |
--session-token <token> |
Session token |
--sync-id <id> |
Budget Sync ID |
--data-dir <path> |
Data directory |
--cache-ttl <seconds> |
Cache TTL; 0 disables caching (default: 60) |
--refresh |
Force a sync on this call, ignoring the cache |
--no-cache |
Alias for --refresh |
--lock-timeout <secs> |
Lock wait timeout (default: 10) |
--no-lock |
Disable budget-dir locking (use with care) |
--format <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 <command> --help for subcommands and options.
Examples
# 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 <id> \
--data '[{"date":"2026-03-14","amount":-2500,"payee_name":"Coffee Shop"}]'
# Export transactions to CSV
actual transactions list --account <id> \
--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 <id> --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": falseto 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), so read-heavy scripts no longer need a single-query workaround by default. For very chatty scripts, run
actual synconce and then use a long--cache-ttlfor reads:actual sync actual --cache-ttl 3600 query run ... actual --cache-ttl 3600 accounts list -
Uncategorized transactions:
category.nameisnullfor 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 <seconds>— override the TTL for a single call (use0to 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:
# 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