How it works

Cost Statement — how it works

A precise account of what happens to a bank statement PDF between upload and a diary entry.

1. What you upload

A PDF of a bank or card statement — the kind your bank already lets you export or download. Multiple files can be uploaded at once; each is parsed independently. Nothing about the file needs to be reformatted or prepared first.

2. Text extraction

The PDF's text layer is extracted on the server using a standard PDF-text-parsing library — the same category of tool used to make a PDF searchable, not OCR and not a vision model. If a statement is a scanned image with no embedded text layer, there is nothing to extract and no transactions will be found.

3. How a transaction is classified

Each transaction line is matched against a fixed set of rules, checked in this exact order, and the first one that matches wins:

  1. Your own saved merchant rules — if you've previously taught Migraine Today that a merchant name means a specific category (and optionally a specific exercise type, medication or supplement), that always takes priority.
  2. Multilingual pharmacy-name matching — merchant names containing a pharmacy word in German, English, French, Italian, Spanish, Polish, Portuguese, Scandinavian, Baltic, Slovak/Czech or Hungarian are classified as pharmacy purchases.
  3. The bank's own category label — many statements print a category next to each line (e.g. “Mastercard • Lebensmittel”); a fixed translation table maps known bank categories to Migraine Today's categories.
  4. Generic merchant-name patterns — a short list of gym/fitness and grocery/health-food keywords for sports and nutrition, as a last resort.
  5. Otherwise, the transaction is filed as “other” and doesn't map anywhere in the diary.

4. Why this doesn't use AI

Bank statements have a small, predictable set of layouts — a date, an amount, a merchant name, sometimes a bank-assigned category. Regular-expression pattern matching handles that reliably and deterministically: the same statement always classifies the same way, nothing is sent to a third-party model, and there's no risk of a language model inventing a category that isn't actually supported by the text. The trade-off is explicit: an unusual merchant name Migraine Today doesn't recognize falls back to “other” until you teach it — see the next section.

5. Duplicate detection

The extracted text of every uploaded statement is hashed (SHA-256), and that hash is compared against your previous uploads. Re-uploading the same statement is caught and flagged before anything is re-processed, with the option to re-analyze anyway.

6. How a transaction becomes a diary entry

Classification alone never writes to your diary. For any date with a classified purchase that isn't already logged, a review card appears showing only the field that actually matches the category — an exercise type and duration for a sports merchant, a checklist of your saved medications for a pharmacy merchant, your saved supplements for a nutrition merchant. You choose the specific item and press Save yourself, per date.

The one thing that is remembered automatically is the merchant-to-category mapping itself, once you've confirmed it a single time via “Customize” or the standalone mapping panel — so the same merchant on a future statement is recognized without repeating the classification step, though the diary save itself is still a manual, per-date confirmation.

7. What's stored, and where

Migraine Today stores the transactions extracted from a statement (date, amount, merchant text, assigned category) and your own saved merchant rules — not the original PDF file itself. Extraction happens on Migraine Today's own server; nothing from the statement is sent to a third party or an external AI service at any point. See the Privacy Policy for retention and your rights under GDPR.