How to turn a bank statement into Beancount
By Kayabyte · Last updated 28 October 2026
Beancount and the Ledger family (Ledger, hledger) keep your finances in plain text files. That is their appeal and their chore: every transaction has to get into the file somehow, and banks give you PDFs and CSVs. This guide covers the common ways to get statement data into Beancount, then the checks that make the result trustworthy.
1. What a Beancount entry needs
A transaction has a date, an optional payee and narration, and at least two postings that sum to zero:
2026-09-14 * "Grocery Store" "Weekly shop"
Assets:Bank:Checking -54.20 USD
Expenses:Food:Groceries
For a statement import, the first posting is the bank account with the amount from the statement. The second posting is a placeholder (often Expenses:Uncategorized) that you reassign later. Beancount also has balance assertions, which are the best feature for this job:
2026-10-01 balance Assets:Bank:Checking 1234.56 USD
If the transactions before that date don’t add up to that balance, bean-check fails and tells you.
2. The manual way
- Download CSV from your bank if available; otherwise copy the table from the PDF into a spreadsheet.
- Clean it: one date format (Beancount wants YYYY-MM-DD), one signed amount column, descriptions on one line.
- Write the entries. For a few transactions, type them; for many, use a spreadsheet formula to build each text line, then paste into your file.
- Add a balance assertion for the statement’s closing balance on the day after the statement ends (Beancount balance assertions apply at the start of the day).
- Run
bean-check yourfile.beancount.
3. Importers
For ongoing use, people write importers with Beancount’s import tooling (the bean-extract flow and the community beangulp package; check the current docs, since the tooling has changed between versions). An importer reads a CSV or OFX file from one specific bank and emits entries. It is powerful, but you write and maintain Python for each bank, and PDFs need an extra extraction step first. Hledger users have a similar route with CSV rules files, which describe how columns map to postings.
4. Limits of the manual way
- Time. A year of statements is hundreds of lines to format.
- Sign errors. A flipped sign on a credit card posts as a plausible but wrong entry. Only a balance assertion catches it.
- Wrapped lines and page breaks in PDF text corrupt entries.
- Commodity and decimal formats.
1.234,56is not valid for Beancount; amounts must use a period for decimals and no thousands separator. - Duplicates. Plain text has no import memory; if you import the same month twice, you get double entries unless you check.
5. Where Balanced helps
Balanced is a Mac app we make that reads PDF statements (text PDFs, scans and photos using Apple’s on-device text recognition) and CSV or TSV, from any bank, with headers and months in 10 languages. The preview shows the table found; you can fix column roles, date order and sign handling, and it remembers each bank’s layout.
Its totals check does for the statement what a balance assertion does in your ledger: opening balance plus transactions must equal the closing balance, and the running balance row by row when present. If something doesn’t add up, it names the rows and the difference, and exporting needs an explicit “Export anyway”.
Choose Beancount from the Export button (Ledger/hledger is next to it) and you get entries you can paste into your file, ready to be assigned to categories. No AI guessing: every number is copied from your statement and checked, and it all stays on your Mac.
Limits: results depend on layout, so check the preview; low-quality or skewed scans can fail; unlock password-protected PDFs first with the password from your bank. We can’t promise every bank.
Download Balanced and convert for free: the free version converts and checks everything and exports the first 10 transactions per file. Pro is USD 59 per year or USD 7.99 per month, up to 3 Macs, cancel anytime. See pricing and help. macOS 14 or later.
6. After the import
- Add a
balanceassertion for the statement’s closing balance and runbean-check. - Reassign the placeholder account on each transaction, or let your own rules or scripts do it.
- Keep the original statement file next to the ledger, named by month.
- Fixing an unbalanced month? See why converted statements don’t add up.
Related guides
- Why converted statements don’t add up
- How to import a bank statement into Actual Budget
- How to import a PDF bank statement into Xero
More guides
- How to export Apple Card transactions to a spreadsheet
- How to convert a Bank of America statement to Excel
- How to turn a Chase statement into Excel or CSV
- How to convert a PDF bank statement to CSV
- How to convert a PDF bank statement to Excel
- DocuClipper alternatives for Mac: online service or an app on your Mac
- How to import a PDF bank statement into YNAB
- How to convert a PDF bank statement to OFX
- How to import a PDF bank statement into QuickBooks as a QBO file
- How to get a PDF bank statement into Quicken (QIF or QFX)
- A private bank statement converter for Mac: keep your statements off other people’s servers
- ProperConvert alternatives for Mac: what to compare before you pay