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:SalaryDate Format
All directives begin with dates in ISO 8601 format:
YYYY-MM-DDBoth 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:FoodNon-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:2024Commodities/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 characterNo 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 CADNumber Format
- Decimal point:
. - Grouping separator:
,(optional) - Negative:
-prefix
Arithmetic Expressions
Amounts support expressions:
2024-01-01 * "Split"
Expenses:Food (100 / 3) USD
Assets:CashOperators: +, -, *, /, (, )
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:CreditCardTag Stack
Apply tags to multiple directives:
pushtag #berlin-trip
2024-04-23 * "Hotel"
...
2024-04-24 * "Restaurant"
...
poptag #berlin-tripMetadata 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:ReceivableMetadata
Key-value pairs attached to directives or postings:
2024-01-15 * "Purchase"
receipt: "photo.jpg"
Assets:Cash -50 USD
category: "groceries"
Expenses:FoodKey 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"