
# Changing your budget

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

<Callout type="warning" title="Preview first">
Every write takes `--dry-run`, which shows what would change without changing anything. Every destructive action needs `--yes`. For anything scripted, try it on a copy of your budget first: in Actual, export the budget and import it as a new one.
</Callout>

<Video title="Doing tasks with fob-actual: import transactions, budget the month, clean up payees (3–4 min)" />

## Transactions

```bash
fob-actual transactions add --account Checking --date 2026-09-20 \
  --amount -42.50 --payee "Coffee Shop" --dry-run
```

```text
[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.

```bash
fob-actual transactions import --account Checking --file september.json --dry-run
```

```text
[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**:

```json
[
  { "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

```bash
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

```bash
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

```bash
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

```bash
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](/docs/actual/cli/reference/categories-and-payees).

## Rules and schedules

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

```bash
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
```

```json
{
  "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`.
