Skip to content

Import transactions

Import is how bank rows become Beancount transactions. BeanHub uses the open-source beanhub-import engine. You describe inputs and rules in .beanhub/imports.yaml. The engine extracts rows with beanhub-extract, matches them, and writes or updates transactions in your .bean files.

You do not need to memorize the YAML on day one. The sample book already has rules. Follow the steps below with the sample CSV.

Open .beanhub/imports.yaml from Home. The sample file maps import-data/mercury/*.csv to Assets:Bank:US:Mercury:Checking and matches payees such as Netflix-style SaaS names. Full syntax: beanhub-import docs. A long tutorial: Academy step-by-step.

Input Files (under Import) lists paths that currently match those rules.

  1. Sidebar ImportUpload Files.
  2. Click Upload file.
  3. Choose a CSV (accept="text/csv" in the form).
  4. Upload.
Import File Upload page with a CSV file picker.

The sample CSV used by the cookiecutter README is beanhub-import-sample.csv. Download it, then upload.

BeanHub opens a review page for the uploaded file. Check the path it will write to (it should match an inputs.match glob, for example import-data/mercury/2024.csv). Click Import.

Review uploaded CSV with Import button.

Import copies the CSV into the Git tree (if needed), runs the rules, and commits. Matched rows become Beancount transactions. Unmatched rows become Open transactions (the Open TXNs page): bank rows that still need a human to pick the other account.

ImportOpen TXNs lists rows that did not match any rule. This is expected for one-off purchases.

Open Transactions list with Add on each unmatched bank row.
  1. Click Add on a row.
  2. The form is mostly filled (date, amount, the bank account posting). Fill the other account (autocomplete) and narration if needed.
  3. Submit. The row moves to Pending TXNs.

When you have reviewed the pending list, commit them. BeanHub writes transactions with import-override: "none" so later automatic rules do not overwrite your manual choices. You can change that metadata later. Details: Manual Import blog post.

Pending Transactions page ready to commit.

Deleting a pending transaction sends it back to Open TXNs.

Rules are YAML. A minimal match on description prefix:

inputs:
- match: "import-data/mercury/*.csv"
config:
extractor: mercury
default_file: "books/{{ date.year }}.bean"
prepend_postings:
- account: Assets:Bank:US:Mercury:Checking
amount:
number: "{{ amount }}"
currency: "{{ currency | default('USD', true) }}"
imports:
- name: Coffee
match:
extractor:
equals: "mercury"
desc:
prefix: "STARBUCKS"
actions:
- txn:
narration: "Coffee"
postings:
- account: Expenses:Food
amount:
number: "{{ -amount }}"
currency: "{{ currency | default('USD', true) }}"

prepend_postings on the input is the bank leg. The action adds the expense leg. Templates use Jinja. Commit the YAML from your laptop or by editing the file locally and pushing. The website file viewer is read-only.

Same engine, no BeanHub account required:

Terminal window
pip install "beanhub-cli>=3.0.0"
bh import

Docs: beanhub-cli import.

Method Who it is for
Upload CSV Free and paid. You download from the bank yourself.
Connect Paid. Plaid syncs, BeanHub writes CSVs on a schedule, then runs the same import rules.

Both end in .beanhub/imports.yaml. Write the rules once.