Fob
Browse the docs

Changing your budget

Writes sync into your live budget as soon as the command finishes, including for anyone you share the budget with.

Video coming soon
Doing tasks with fob-actual: import transactions, budget the month, clean up payees (3–4 min)

Transactions#

fob-actual transactions add --account Checking --date 2026-09-20 \
  --amount -42.50 --payee "Coffee Shop" --dry-run
[dry-run] Would add 1 transaction(s) to 'Checking':
DATE        PAYEE        AMOUNT  NOTES
--------------------------------------
2026-09-20  Coffee Shop  -42.50  —

Drop --dry-run to add it. Negative amounts are money out. --category takes a category ID (from categories list), --cleared marks it cleared, and a new payee name is created for you.

Import from a file#

transactions import runs the same logic as importing a bank file in the Actual app: it skips duplicates and applies your rules.

fob-actual transactions import --account Checking --file september.json --dry-run
[dry-run] Would import: 1 added, 0 updated (2 submitted to 'Checking').

The file is a JSON array (or { "transactions": [...] }). Amounts are in minor units:

[
  { "date": "2026-09-21", "amount": -1999, "payee_name": "Streaming Co", "imported_id": "bank-88213" },
  { "date": "2026-09-20", "amount": -4250, "payee_name": "Coffee Shop", "notes": "team coffee" }
]

Give each row a stable imported_id from your bank's export where you have one; it makes duplicate detection exact. transactions add --file adds rows as they are, without duplicate detection or rules.

Edit and delete#

fob-actual transactions edit <id> --category <category-id> --notes "reimbursable"
fob-actual transactions delete <id> --yes

edit changes only the options you pass. Transaction IDs are in transactions list --json.

The monthly budget#

fob-actual budgets set-amount 2026-10 <category-id> --amount 450.00
fob-actual budgets carryover 2026-10 <category-id>          # --off to stop rolling over
fob-actual budgets hold 2026-10 --amount 500.00             # keep funds for next month
fob-actual budgets reset-hold 2026-10

Accounts#

fob-actual accounts create --name "Savings" --balance 1000.00
fob-actual accounts edit Savings --name "Emergency fund"
fob-actual accounts close "Old Card" --transfer-account Checking
fob-actual accounts reopen "Old Card"
fob-actual accounts delete "Old Card" --yes                 # deletes its transactions too

Closing keeps the account's history. Deleting removes it and every transaction in it.

Categories, payees and tags#

fob-actual category-groups create --name "Subscriptions"
fob-actual categories create --name "Streaming" --group <group-id>
fob-actual payees merge <keep-id> --from <other-id> --yes   # fold duplicates into one payee (--from repeats)
fob-actual tags create --tag reimbursable

Run a command with --help to see its options. All of them are in the command reference.

Rules and schedules#

Rules and schedules have nested conditions and actions, so create and edit take JSON, in the same shape show --json prints:

fob-actual rules show <id> --json | jq 'del(.id)' > rule.json   # copy an existing rule
# edit rule.json, then:
fob-actual rules create --file rule.json --dry-run
fob-actual rules edit <id> --file rule.json                      # or change the original
fob-actual schedules edit <id> --amount -1200.00 --reset-next-date
{
  "stage": null,
  "conditionsOp": "and",
  "conditions": [{ "op": "is", "field": "payee", "value": "<payee-id>" }],
  "actions": [{ "op": "set", "field": "category", "value": "<category-id>" }]
}

Copying a rule you made in the Actual app is the easiest way to get the format right. Remove its id before create: with the id kept, create overwrites that rule instead of making a new one. Schedules also take simple flags such as --name, --amount and --completed.