Skip to main content

Beancount syntax reference: directives, accounts, amounts

Beancount language syntax reference: directives, transactions, account naming, tags, metadata, and formatting for plain-text ledgers.

This provides a concise yet comprehensive reference for the Beancount language syntax, blending practical structure, rules, and examples. For more details, see the Cheat Sheet.

Overview

Beancount is a plain-text double-entry accounting system. Its language is structured around three main building blocks:

  • Commodities (currencies, stocks, points, etc.)
  • Accounts (hierarchical, categorized ledgers)
  • Directives (dated entries recording events or configuration)

Commodities

Commodities are always written in uppercase, e.g., USD, EUR, AAPL, BTC, MILES, HOURS.

Accounts

Accounts are colon-separated, capitalized hierarchical names. They must begin with one of the five root account types:

NameTypeTypical ContentsExample
Assets+Cash, Bank, InvestmentsAssets:Checking
Liabilities-Credit Cards, LoansLiabilities:CreditCard
Income-Salary, InterestIncome:EmployerA
Expenses+Purchases, BillsExpenses:Food:Dining
Equity-Opening/Closing BalancesEquity:Opening-Balances
  • Components must be capitalized, separated by colons (:), with no spaces.
  • Numbers and dashes are allowed in components.
  • The root account names can be customized via options (see below).

Directives

Directives are the core statements in a Beancount file. Most start with a date, followed by a directive type and arguments. They are processed in chronological order (by date), not file order.

General format:

YYYY-MM-DD <directive> <arguments...>

Common Directives & Examples

Opening and Closing Accounts

2023-01-01 open Assets:Checking USD,EUR  ; Optionally specify allowed currencies
2023-12-31 close Assets:Checking

Declaring Commodities

2020-07-22 commodity AAPL
  name: "Apple Inc."

Price Declarations

2022-04-30 price AAPL 150.00 USD

Notes & Documents

2022-03-20 note Assets:Checking "Asked about refund"
2022-03-20 document Assets:Checking "statements/2022-03.pdf"

Transactions

2024-01-05 * "Coffee Shop" "Morning coffee"
  Expenses:Food         4.50 USD
  Assets:Cash         -4.50 USD
 
2024-01-06 ! "Phone Bill" "Monthly payment" #utilities ^phone
  id: "INV12345"              ; Metadata
  Expenses:Utilities  60.00 USD
  Assets:Checking

Posting Features

; With cost basis
  Assets:Stocks    1 AAPL {150.00 USD}
; With price annotation
  Assets:Cash   -100 USD @ 1.25 CAD
; With total price
  Assets:Cash   -100 USD @@ 125.00 CAD
; Implicit balance
  Assets:Cash   -100 USD
  Assets:Bank

Balance Assertions & Padding

The pad must be dated before the balance it feeds, because the assertion is checked at the start of its day:

2024-06-01 pad Assets:Checking Equity:Opening-Balances
2024-06-02 balance Assets:Checking 1000.00 USD

Events

2024-06-01 event "location" "San Francisco, CA"

Options

Set file-wide configuration:

option "title" "My Ledger"
option "operating_currency" "USD"
option "documents" "docs/"
option "name_assets" "Vermoegen"

See the Options Reference for more.

Plugins & File Organization

plugin "beancount.plugins.module_name"
plugin "beancount.plugins.module_name" "config-string"
include "other/file.beancount"
pushtag #project
; ...
poptag #project

Important Rules

  • All transactions must balance: the weights of all postings sum to zero. A posting's weight is its amount, or its cost ({}) or price (@) converted to the other currency when one is present.
  • Accounts must be opened before use; closed accounts cannot accept postings.
  • Balance assertions check only the specified currency, can be used on parent accounts, and are evaluated at the start of their date (so they exclude same-day transactions).
  • Price annotations (@ per unit, @@ total) do affect balancing: they set the posting's weight in the other currency. -100 USD @ 1.25 CAD weighs 125 CAD and offsets a 125 CAD posting; remove the price and the transaction no longer balances.

Common Patterns

Opening Accounts with Initial Balance

Open both accounts, pad on the start date, and assert the balance the next day (the assertion is checked at the start of its date):

2024-01-01 open Assets:Checking USD
2024-01-01 open Equity:Opening-Balances
2024-01-01 pad Assets:Checking Equity:Opening-Balances
2024-01-02 balance Assets:Checking 1000.00 USD

Investment Transaction

2024-01-01 * "Buy stock"
  Assets:Broker:Stock   10 AAPL {150.00 USD}
  Assets:Broker:Cash -1500.00 USD

Multi-Currency Transaction

2024-01-01 * "Currency exchange"
  Assets:USD   -100.00 USD @ 1.25 CAD
  Assets:CAD    125.00 CAD

Comments

poptag  #trip-to-peru
; inline comments begin with a semi-colon
* any line not starting with a valid directive is also ignored silently

Source: https://beancount.io/docs/Basics/syntax