Skip to content

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:

  1. Options - Global configuration (undated)
  2. Directives - Dated accounting entries
  3. 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:

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:

  1. Balance assertions and other non-transaction directives first
  2. 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"