Here’s a scene from my ledger that happens a few times a year.

Over the course of a month, we buy a scattered pile of medical things out of pocket — a doctor’s visit copay, a box of prescribed supplies from the pharmacy, some physical-therapy sessions, a couple of online orders for a brace and a monitor. Nothing gets billed to insurance automatically, because these are the kinds of items you have to submit yourself. So I collect the receipts, fill out the insurer’s claim form, and mail off a bundle totaling something like 260 USD.

Weeks later, an Explanation of Benefits shows up. The insurer has approved 138.01 USD — not the full 260 USD — and a check for that amount is on the way. And now I have two small, annoying problems.

The first is reconciliation at the item level. The EOB doesn’t say “we reimbursed the brace and the copay but not the pharmacy order.” It shows adjusted, bundled, partially-approved line amounts that don’t map cleanly onto the charges as they hit my credit card. Figuring out which of the eight things I bought actually got covered — and which got denied — is genuinely tedious, and most of the time I don’t actually need the answer.

The second problem is worse. That pharmacy charge from six weeks ago? It got imported and auto-categorized as groceries, because the store that filled the prescription also sells groceries and my importer keyed off the merchant name. By the time the check arrives, the original purchase has scattered into three or four categories, half of them wrong, and hunting it down is its own small archaeology project.

This post is about how I book the reimbursement anyway — cleanly, in a couple of minutes — without solving either of those problems.

The Beancount example in this post can be found in: https://github.com/flyaway1217/beancount_example/blob/main/single_examples/self_submit_insurance.bean

Three real-world events

Strip the mess away and a self-submitted claim is three events on a timeline:

  1. Purchase. You pay out of pocket, usually on a credit card.
  2. Claim processed. The insurer approves some amount and issues an EOB and a check.
  3. Reimbursement received. The check clears into your bank account.

The bookkeeping question is how faithfully to model these three events — and the honest answer is that you don’t need to model all three with equal care. Two of them are cheap and worth doing every time. The third is expensive and, most of the time, skippable.

Flowchart of the three bookkeeping steps: step 1, Purchase (paid out of pocket), is drawn with a dashed border and marked OPTIONAL — you can skip it, because the purchase is already in your ledger in the wrong bucket; a dashed arrow leads to step 2, Claim processed (EOB arrives, book the receivable), and a solid arrow to step 3, Reimbursement received (check clears into checking), with steps 2 and 3 bracketed as the two you always book

The faithful version, for reference

If you had unlimited patience, you’d record all three events. It looks like this.

The purchase, categorized into a dedicated medical claims account:

2026-05-14 * "Pharmacy" "Prescribed supplies — Mia"
  Expenses:Health:Medical:Mia:Claims      200.00 USD
  Expenses:SalesTax                         18.00 USD
  Liabilities:CreditCard:Chase            -218.00 USD

The claim being processed, on the EOB date:

2026-06-20 * "Aetna" "Medical reimbursement — Mia"
  service-date: 2026-05-14
  claim-id: "aetna-8830412"
  document: "2026-06-20 aetna-eob.pdf"
  Assets:Others:Receivable:Aetna                        138.01 USD
  Expenses:Health:Medical:Mia:Aetna:ClaimsPayment   -138.01 USD

And the check clearing a few days later:

2026-06-24 * "Reimburse from Aetna" "Check #20418"
  Assets:Others:Receivable:Aetna     -138.01 USD
  Assets:Cash:Checking             138.01 USD

Two design choices are worth pausing on, because they carry over into the practical version.

First, the reimbursement is booked as a negative expense — a contra-expense — in a ClaimsPayment sub-account, not as income. Insurance money coming back to you isn’t income; it’s a refund of a cost you already bore. Modeling it this way means Claims and ClaimsPayment net to your true out-of-pocket cost for that person’s care. A 200 USD purchase minus a 138.01 USD refund leaves 61.99 USD that actually left the household, and the ledger says exactly that.

Second, the claim and the deposit are kept as two separate transactions with a receivable in between. Between the EOB date and the day the check clears, the insurer owes you money. Booking that into Assets:Others:Receivable:Aetna makes it a real balance-sheet item, and the receivable balance then answers a question you’ll actually ask: which claims have I submitted that haven’t paid out yet? It’s a small asset — money owed to you — that would otherwise be invisible until the check randomly showed up.

That’s the textbook model. Now the practical part.

The part you skip: the original purchase

In the faithful version, step ① requires you to find the original charge, confirm it, and re-categorize it into …:Medical:…:Claims. In real life, by the time the check arrives that charge is buried and mis-labeled, and reconstructing it means the item-level reconciliation I complained about at the top. It’s the single most expensive step, and it’s the one you can drop.

So here’s what I actually do. I book only the reimbursement — the receivable and the deposit — and I leave the original purchase exactly where it landed, wrong category and all:

2026-06-20 * "Aetna" "Medical reimbursement — Mia (source untracked)"
  service-date: 2026-05-14
  claim-id: "aetna-8830412"
  document: "2026-06-20 aetna-eob.pdf"
  Assets:Others:Receivable:Aetna                        138.01 USD
  Expenses:Health:Medical:Mia:Aetna:ClaimsPayment   -138.01 USD

2026-06-24 * "Reimburse from Aetna" "Check #20418"
  Assets:Others:Receivable:Aetna     -138.01 USD
  Assets:Cash:Checking             138.01 USD

Two transactions. No search through six weeks of history. No line-by-line matching against the EOB. The whole thing takes about as long as it took to read this paragraph.

Why the numbers still come out right

The surprising part is how little damage this does to the reports that matter.

Net worth is exact. The cash came in — checking is up 138.01 USD — and the original credit-card charge was already recorded when the purchase got imported, wherever it landed. The receivable opens on the EOB date and closes when the check clears, so the balance sheet is correct at every point on the timeline. Nothing about skipping step ① touches your net worth.

Total spending is exact, too. This is the part that feels like it shouldn’t work. The original purchase is sitting in the wrong category — say, groceries — overstating groceries by the medical amount. Meanwhile the −138.01 USD ClaimsPayment sits in the medical subtree. Those two errors point in opposite directions and cancel at the top line. Aggregate spending for the month is right; the money just got attributed to the wrong buckets on the way there.

So what do you actually give up?

Category accuracy. This is the real cost, and it shows up in a specific, slightly alarming way: the medical category goes negative. With no matching Claims charge to offset it, the subtree contains only the −138.01 USD reimbursement, as if the insurer paid you 138 USD for nothing. And whatever category swallowed the purchase — groceries, general shopping, a kid’s miscellaneous line — is silently inflated by the gross amount. The top line is honest; the structure underneath it is distorted.

Audit trail. If you ever want itemized medical deductions, HSA/FSA substantiation, or a clean year-end “how much did we spend on health?” number, this approach won’t give it to you, because the spend never got tagged as medical in the first place.

The principle underneath

The thing I’d take away from this is a small rule about where to spend bookkeeping effort.

Always model the money that moves through your accounts — the receivable when the insurer owes you, the deposit when the check clears. Those postings are cheap, they keep net worth and cash flow exact, and they give you a clean worklist of outstanding claims. There’s no reason to skip them.

Be willing to skip reconstructing money that already moved. The original purchase is already in your ledger somewhere; the only question is whether it’s worth the archaeology to move it into the right category. For a routine partial reimbursement, it isn’t. The numbers that drive decisions — net worth, total spend, cash on hand — don’t depend on it. Only the category-level detail does, and category detail is exactly the kind of thing you can defer until a specific report actually demands it.

That’s the trade I make every time one of those partial checks shows up. Correct top line, correct balance sheet, a slightly ugly medical category, and a two-minute entry instead of a twenty-minute one. For a claim I’ll never look at again, that’s the right price.