Expenses & receipts: what you spent, where, and on what

You come back from a trip with a pocket full of receipts. Filing them one by one is only worth it if you can ask something useful afterwards — like whether that pizza really was more expensive this year.

Alexandria stores a receipt as three things you can query separately:

Expenses and purchases land on your timeline under the moment of the transaction. A place does not: you did not do a restaurant on a date.

Turn it on

Expenses is a domain — a ready-made set of tables. In the app, open Settings → Domains and press Enable on Expenses. From the command line:

akb domain enable expenses

Afterwards they are ordinary tables. Rename them, add your own columns, filter and sort them like anything else. Enabling again writes nothing, and is also how a table you damaged gets repaired.

File a receipt

Open the Expenses table and press New receipt. The merchant, the date and the total are required — an expense with no cost cannot be compared to anything. Everything else is optional: subtotal, tax, tip, payment method, address, and a row per item you bought.

Amounts are typed the way you would say them, 36.00 EUR. They are stored as exact decimals, never rounded, in a canonical form — so 36.00 EUR reads back as EUR 36.

Check the vault before saving and Alexandria answers two questions without writing anything:

Attach photo archives the receipt image with it. The same photo attached twice is stored once.

Ask the question you filed them for

akb rows Purchases --where "title~pizza" --sort unit_price
Pizza Margherita   Pizzeria ai Baffetto — 2025-07-19   EUR 15   2   EUR 7.5
Pizza Margherita   Pizzeria da Enzo — 2026-07-19       EUR 18   2   EUR 9

Money is compared exactly and only within one currency, so a euro total never sorts against a dollar one. See property types.

From the command line

akb receipts commit takes a JSON draft you write by hand — editing the draft is the review step, so a misspelled field is refused rather than silently dropped.

akb receipts commit draft.json --image IMG_1234.jpg
{
  "source": "manual",
  "external_id": "rome-2026-07-19-enzo",
  "transaction_datetime": "2026-07-19T20:35:00",
  "merchant_name": "Pizzeria da Enzo",
  "address": "Via dei Vascellari 29",
  "city": "Roma",
  "country": "IT",
  "total": "36.00 EUR",
  "payment_method": "card",
  "purchases": [
    { "external_id": "l1", "name": "Pizza Margherita", "quantity": 2,
      "unit_price": "9.00 EUR", "line_total": "18.00 EUR" }
  ]
}

source and external_id are the receipt's identity, so committing the same pair again corrects the rows it already wrote instead of filing a second copy. It corrects but never deletes: if you drop a line item and re-commit, the purchase row from the earlier run stays until you delete it yourself. Only total is required among the amounts. A receipt brings its tables with it, so this works even before you have enabled the domain.

Where it lives

Nothing here is a separate database. An expense is a note; its values live in the table's frontmatter; the place and the photo are ordinary links. It stays plain Markdown you can read, edit, back up and sync like everything else.