Beancount Syntax Overview¶
This document provides an overview of Beancount syntax. Individual directives are documented in the directives/ directory.
Core Concepts¶
Beancount is a declarative text-based double-entry bookkeeping system. Input files contain directives (entries) with dates and types, plus optional global options.
File Structure¶
A Beancount file consists of:
- Options - Global configuration (undated)
- Directives - Dated accounting entries
- Comments - Documentation (ignored by parser)
; Options at top
option "title" "My Ledger"
option "operating_currency" "USD"
; Directives follow
2024-01-01 open Assets:Checking USD
2024-01-15 * "Payee" "Description"
Assets:Checking 100.00 USD
Income:Salary
Date Format¶
All directives begin with dates in ISO 8601 format:
YYYY-MM-DD
Both dash and slash variants are accepted:
- 2024-02-03 (preferred)
- 2024/02/03
Comments¶
Lines starting with semicolon are comments:
; This is a comment
2024-01-01 * "Transaction"
Assets:Cash -20 USD ; inline comment
Expenses:Food
Non-directive lines are silently ignored, enabling org-mode formatting.
Transaction Flags¶
Flags indicate transaction status:
| Flag | Meaning |
|---|---|
* |
Complete - "this looks correct" |
! |
Incomplete - needs review, "this looks incorrect" |
txn |
Equivalent to * (keyword form) |
P |
Padding - typically auto-inserted by pad directive (can also be used manually) |
The txn keyword is optional; a flag alone suffices:
2024-01-15 * "Using star flag"
2024-01-15 txn "Using txn keyword"
2024-01-15 ! "Pending transaction"
Accounts¶
Account names consist of colon-separated components:
RootType:Component:Component:...
Root Types¶
Every account MUST start with one of five root types:
| Root Type | Purpose |
|---|---|
Assets |
Things you own |
Liabilities |
Things you owe |
Equity |
Net worth / opening balances |
Income |
Money received |
Expenses |
Money spent |
Component Rules¶
- First component MUST be one of the five root types
- Each subsequent component MUST begin with an uppercase ASCII letter (A-Z) or digit (0-9)
- Subsequent characters MAY be letters (including UTF-8), numbers, or dashes
- UTF-8 characters are supported AFTER the first ASCII character
- MUST NOT contain spaces or special characters other than dash
Examples:
Assets:US:BofA:Checking
Assets:US:BofA:Savings
Expenses:Food:Groceries
Liabilities:CreditCard:Chase
Income:Salary:2024
Commodities/Currencies¶
Currency names are recognized by syntax:
- MUST start with an uppercase letter (A-Z)
- MUST end with an uppercase letter or digit (A-Z, 0-9)
- Middle characters MAY include: uppercase letters, digits, apostrophes ('), periods (.), underscores (_), dashes (-)
- No enforced maximum length (docs mention 24 chars but not enforced)
- Single-letter currencies are valid (e.g.,
V)
Examples:
USD ; US Dollar
EUR ; Euro
MSFT ; Stock
V ; Single letter (valid)
NT.TO ; Toronto stock exchange
BRK.B ; Class B shares
VACHR ; Custom (vacation hours)
Invalid examples:
usd ; Lowercase not allowed
1USD ; Cannot start with digit
USD- ; Cannot end with special character
No pre-declaration required (though commodity directive is available).
Amounts¶
An amount is a number followed by a currency:
100.00 USD
-50 EUR
1,234.56 CAD
Number Format¶
- Decimal point:
. - Grouping separator:
,(optional) - Negative:
-prefix
Arithmetic Expressions¶
Amounts support expressions:
2024-01-01 * "Split"
Expenses:Food (100 / 3) USD
Assets:Cash
Operators: +, -, *, /, (, )
Strings¶
Text enclosed in double quotes:
"Simple string"
"Multi-line
string allowed"
Strings MAY span multiple lines.
Tags¶
Hash-prefixed identifiers for categorizing. Tags may contain letters, numbers, dashes, underscores, slashes, and periods.
2024-01-15 * "Flight" #berlin-trip #travel #project/2024
Expenses:Flights -1230.27 USD
Liabilities:CreditCard
Tag Stack¶
Apply tags to multiple directives:
pushtag #berlin-trip
2024-04-23 * "Hotel"
...
2024-04-24 * "Restaurant"
...
poptag #berlin-trip
Metadata Stack¶
Apply metadata to multiple directives:
pushmeta location: "Berlin"
2024-04-23 * "Hotel"
...
2024-04-24 * "Restaurant"
...
popmeta location:
Links¶
Caret-prefixed identifiers connecting related transactions. Links may contain letters, numbers, dashes, underscores, slashes, and periods.
2024-02-05 * "Invoice" ^invoice/2024/001
Income:Clients -8450.00 USD
Assets:Receivable
2024-02-20 * "Payment" ^invoice/2024/001
Assets:Checking 8450.00 USD
Assets:Receivable
Metadata¶
Key-value pairs attached to directives or postings:
2024-01-15 * "Purchase"
receipt: "photo.jpg"
Assets:Cash -50 USD
category: "groceries"
Expenses:Food
Key Format¶
- MUST start with lowercase letter
- MAY contain letters, numbers, dashes, underscores
Value Types¶
- Strings:
"text" - Numbers:
123.45 - Dates:
2024-01-15 - Accounts:
Assets:Cash - Currencies:
USD - Tags:
#tag - Amounts:
100 USD - Booleans:
TRUE,FALSE
Automatic Metadata¶
All directives automatically include:
| Key | Type | Description |
|---|---|---|
filename |
String | Source file path |
lineno |
Integer | Line number in source file |
Directive Types¶
| Directive | Purpose |
|---|---|
open |
Declare account existence |
close |
Mark account as inactive |
commodity |
Declare currency with metadata |
transaction |
Financial exchange |
balance |
Assert account balance |
pad |
Auto-generate balancing entry |
note |
Attach comment to account |
document |
Link external file |
price |
Record exchange rate |
event |
Track variable over time |
query |
Embed SQL query |
custom |
User-defined directive |
See directives/ for detailed documentation of each.
Entry Ordering¶
Directives are automatically sorted chronologically after parsing. Within the same date:
- Balance assertions and other non-transaction directives first
- Transactions after
File order is preserved for directives with identical date and type.
Includes¶
Split files across documents:
include "accounts.beancount"
include "2024/january.beancount"
Path Resolution¶
- Relative paths resolve to the including file's directory
- Absolute paths are used as-is
- Glob patterns are NOT supported
Option Scoping¶
- Options are parsed per-file during include processing
- Only the top-level file's options apply to the final ledger
- Options in included files are parsed but do not override
Circular Includes¶
Circular include dependencies MUST be detected and reported as errors.
Plugins¶
Load transformation modules:
plugin "beancount.plugins.implicit_prices"
plugin "my_plugin" "config_string"