How to attach documents to Beancount transactions

Published

I don't know about you, but I'm almost never able to find receipts or invoices when I actually need them. A month after I buy something, the PDF is buried either in my emails, or somewhere in my Downloads folder named something completely unhelpful like invoice-R12134.pdf.

One of the features of Beancount that I love the most is the ability to attach documents to transactions. It only makes sense that documents such as invoices or receipts live there too.

In this post I'll walk you through the two main ways to attach documents to your Beancount ledger, and then show you how to access them through Fava. By the end, you should have a system where you can quickly find every invoice/receipt you care about, whenever you need it.

BTW, if you're new to Beancount, you should first read what is plaintext accounting, and if you're in the process of importing your data into Beancount, check out how to import external data.

The document directive

The simplest way to attach a file is the document directive. It looks like this:

2026-01-01 document Expenses:Netflix "/home/alice/receipts/netflix-2026-01-01.pdf"

The format is very simple: a date, the keyword document, an account name, and the absolute path to your file. That's it. With something like this in place, when you're browsing your ledger in Fava and come across the relevant Netflix transaction, you'll see that linked PDF is sitting right next to the transaction.

Automatic discovery with option "documents"

The explicit document directive is fine when you have a handful of files, but it can quickly get out of hand. This is where Beancount's automatic document discovery comes in. Instead of writing a document directive for each file, you tell Beancount where your documents live and let it figure out the rest:

option "documents" "documents/"

This line tells Beancount that the documents/ directory inside our finances root directory contains all the documents we'll be attaching to our transactions. The one prerequisite that Beancount has from this directory is that the files need to be organized in a structure that mirrors your own hierarchy of accounts.

For instance, if your accounts look like this:

Expenses:Online:Netflix
Expenses:Supermarket:ALDI

... then the directory holding your Beancount ledger should look like this:

|── alice.beancount
|── documents/
  └── Online/
    └── Netflix/
        └── 2026-01-01.pdf
  └── Supermarket/
    └── ALDI/
        └── 2026-01-01.pdf

Each filename must start with a date in the YYYY-MM-DD format. Beancount scans this directory and automatically attaches the documents to the transactions on that specific date for that specific account for every file it finds. The behavior remains the same, and there's no need to manually declare every single document.

You can have multiple document folders too. Here's an example:

option "documents" "documents-2025/"
option "documents" "documents-2026/"

This is a good option if you want to organize your documents further. I've personally never needed this option (if it makes a difference, at the time of this writing I have 500+ documents attached to my Beancount ledger) but your requirements may vary. So it's good to know that this option is there if you need it.

Viewing documents in Fava

OK, you've attached your documents. How do you actually find them later?

The Journal view

The most natural place is the journal. When you open the journal for an account in Fava (click any account name in the balance sheet or income statement), you'll see its transactions in chronological order. All the document entries should appear inline with clickable filenames.

And if you want to see all documents across every account, navigate to the Documents section using the link in the left sidebar.

There's a neat Fava plugin that connects automatically-discovered documents to the transactions they belong to. To enable it, add this to your ledger:

plugin "fava.plugins.link_documents"

Here's what happens: when Beancount discovers a document in your documents folder, the plugin looks for a transaction on the same date in the same account. If it finds one, it adds a link attribute connecting the two, and tags both the transaction and the document entry with #linked. This means you can filter your journal to see only transactions that have supporting documents.

Similarly, the tag_discovered_documents plugin tags auto-discovered document entries with #discovered:

plugin "fava.plugins.tag_discovered_documents"

With both plugins enabled, you can easily distinguish between documents you manually attached (document directives you wrote) and ones Beancount found on its own (#discovered), and you can see which transactions are backed by a document (#linked).

Conclusion

Attaching documents to transactions is probably the one feature of Beancount that I like the most. Having your transactions and the documents relevant to those transactions in the same place can be very handy.

And If you have questions or run into issues, the Beancount mailing list and the Fava issue tracker are great places to ask.