README
¶
flatex-pdf-cli
Get your transaction data out of flatex/flatexDEGIRO (a German online broker, also operating in Austria) PDF statements and into something you can actually use: structured JSON for your own tooling or AI agents, CSV for spreadsheets, or ready-to-import files for Portfolio Performance. Point it at a single PDF or a whole directory — trades, dividends, interest, fund distributions, orders, crypto, savings plans.
Don't have the PDFs yet? flatex-fetch logs into the flatex.at portal and downloads them for you; this tool then turns them into structured data.
Disclaimer: This is an independent, unofficial open-source project. It is not affiliated with, endorsed by, sponsored by, or in any way associated with flatexDEGIRO AG, flatex, DEGIRO, or any of their subsidiaries. "flatex" and "flatexDEGIRO" are trademarks of their respective owners and are used here only to describe the document format this tool parses. Use at your own risk; always verify extracted data against the original documents.
Features
- Seven document types — trades, dividends, interest, accumulating funds, orders, crypto settlements, savings plans
- Three output formats — JSON, CSV, and Portfolio Performance import files (English or German)
- Every charge, itemised — Provision, Eigene/Fremde Spesen and the full Gebühren breakdown (Courtage, Tradinggebühr, Regulierung, …), plus a ready-to-use total
- Unambiguous dates — trade date, order date and value date are separate fields, not one guess
- Batch processing — single PDFs or whole directory trees; one bad file never aborts the batch
- Depot metadata & audit trail — optionally include depot number/holder and per-transaction source filename
- AI-agent ready — ships a Claude Code skill so coding agents can drive the CLI
Quick Start
brew install welworx/tap/flatex-pdf-cli
# or: go install github.com/welworx/flatex-pdf-cli@latest
flatex-pdf-cli ~/Downloads/statement.pdf
[
{
"document_type": "DIVIDEND",
"isin": "IE00B3RBWM25",
"date": "2025-10-01",
"quantity": 74.45,
"distribution_per_share": 0.422745,
"gross_amount": 31.47,
"net_amount": 22.43,
"net_currency": "EUR"
}
]
Pre-built binaries and other install options: skill/INSTALL.md.
Supported Documents
The tool automatically detects and parses the following flatex document types:
| Type | Status | Description |
|---|---|---|
| TRADE | ✅ Full | Buy/sell confirmations (Wertpapierabrechnung Kauf/Verkauf) with pricing, costs, and gain/loss |
| DIVIDEND | ✅ Full | Dividend payment statements (Ausschüttung) with distribution details and withholding tax |
| INTEREST | ✅ Full | Interest payment notices (Zinsen) on cash accounts |
| ACCUMULATING | ✅ Full | Reinvestment/accumulation notices (Ertragsmitteilung, thesaurierende Fonds) |
| ORDER | 🟡 Partial | Order confirmations (Sammelauftragsbestätigung); one record per pending order — see limitations |
| CRYPTO | ✅ Full | Crypto buy/sell settlements (Sammelabrechnung Kryptowerte) |
| SAVINGSPLAN | ✅ Full | Annual savings-plan settlement (Sammelabrechnung aus); one transaction per executed order row |
German-language PDFs only — non-German statements are rejected with an error (see Known Limitations). Developed and tested against Austrian flatex statements; German (Germany) statements use the same platform and should follow the same layout, but haven't been verified against real samples yet — please open an issue if you hit a mismatch.
Usage
Process a single PDF file (JSON to stdout) or a directory of PDFs:
flatex-pdf-cli path/to/statement.pdf
flatex-pdf-cli path/to/documents/
Flags
-o FILE— Output file (stdout if not provided)-format FORMAT— Output format:json(default),csv, orpp(Portfolio Performance)-lang LANG— Language forppoutput:en(default) orde-include-source— Add source filename to each transaction-include-metadata— Wrap output with depot metadata-quiet— Hide skipped/problematic files; emit only valid JSON-version— Show version and exit
When given a directory, the tool processes every .pdf it finds. A file it
cannot parse is reported on stderr and skipped — the rest still produce
output, so one bad document never aborts the batch. Use -quiet to suppress
the skip messages and get pure JSON on stdout.
Examples
# Save output to file
flatex-pdf-cli -o output.json path/to/documents/
# Include depot metadata in output
flatex-pdf-cli -include-metadata path/to/trade-confirmation.pdf
# Include source filename with transactions (for audit trail)
flatex-pdf-cli -include-source -o transactions.json path/to/documents/
# Combine flags
flatex-pdf-cli -include-source -include-metadata -o output.json path/to/documents/
Upgrading
flatex-pdf-cli upgrade -check # report whether a newer release is available
flatex-pdf-cli upgrade # check, then prompt to download and install it
flatex-pdf-cli upgrade -y # skip the confirmation prompt
Downloads the release asset for your platform from GitHub, verifies it
against the published SHA256SUMS.txt, and atomically replaces the running
binary.
Use Cases
Prepare a Portfolio Performance import
-format pp parses your PDFs into two CSVs shaped for PP's CSV import —
trades and account transactions — so the import is a few clicks instead of
manual column mapping. Use -lang de if your PP runs in German; PP's column
auto-recognition is locale-sensitive, and -lang de emits the German headers,
Typ values, and number format it expects.
flatex-pdf-cli -format pp -lang de -o portfolio ~/Downloads/flatex
# writes portfolio-portfolio.csv and portfolio-accounts.csv
Read more: docs/portfolio-performance.md — import walkthrough, -lang de details, caveats.
Export CSV for spreadsheets
-format csv writes one row per transaction, every parsed field as a column.
Good for spreadsheets or your own scripts.
flatex-pdf-cli -format csv -o transactions.csv ~/Downloads/flatex
Organize your downloads
Sort flatex PDFs from your Downloads folder into a structured archive — one
folder per depot, files renamed by date and document type — using the CLI's
JSON output and jq.
Read more: docs/organize-downloads.md — ready-to-paste shell recipes.
Use from AI agents
This repo ships a ready-made Claude Code skill so AI coding agents can call
the CLI and consume its JSON (flatex-pdf-cli -quiet -include-metadata <path>).
Read more: skill/SKILL.md — the full agent contract and install steps (skill/INSTALL.md).
JSON Reference
Each transaction is a flat JSON object; -include-metadata wraps the list
with depot metadata:
{
"metadata": {
"depot_number": "1234567890",
"depot_holder": "Max Mustermann",
"account_number": "9876543210"
},
"transactions": [
{
"document_type": "TRADE",
"isin": "DE0005140008",
"wkn": "514000",
"date": "2024-06-15",
"order_date": "2024-06-13",
"value_date": "2024-06-17",
"type": "BUY",
"quantity": 10.0,
"price": 25.50,
"price_currency": "EUR",
"gross_value": 255.00,
"costs": {
"provision": 5.50,
"own_expenses": 0,
"foreign_expenses": 3.00,
"total": 8.50,
"fees": {
"courtage": 0,
"trading_fee": 0.50,
"settlement": 2.50,
"closing_notes": 0,
"ls_allocation": 0,
"financial_transaction_tax": 0,
"other": 0
}
},
"final_amount": -263.50,
"final_currency": "EUR",
"custody_type": "Wertpapierrechnung",
"depositary": "Clearstream Lux.",
"deposit_country": "GB",
"execution_venue": "XETRA"
}
]
}
Two things worth knowing before you use the numbers:
dateis the trade date (Handelstag, orSchlusstag/Buchtagon crypto and savings plans) — not the date printed at the top of the letter.order_date(Auftragsdatum) andvalue_date(Valuta) are emitted alongside it, and on a real statement all three are usually different days. Dividends and interest useValutaas theirdate, since that is when the money moves.costs.totalis the transaction's total charge —ProvisionplusEigene SpesenplusFremde Spesen. The entries undercosts.feesitemiseforeign_expensesand are already counted in the total; adding them on top double-counts.costsis absent when a document has no charge block at all, which is how a real 0,00 EUR fee stays distinguishable from an unparsed one.
Full field reference (common, trade, dividend, interest, accumulating, order, and crypto fields): docs/output-format.md.
Known Limitations
- German-language PDFs only. Document-type detection and field extraction
are keyed to German labels (
Wertpapierabrechnung,Valuta,Devisenkurs, …); non-German statements are detected and rejected with an error rather than silently mis-parsed. Numbers are parsed format-agnostically (both1.234,56and1,234.56are accepted), so the restriction is purely about field labels — English support needs a real English sample to map the labels. Developed and tested against Austrian flatex statements only; German (Germany) statements haven't been verified against real samples — please open an issue if you hit a mismatch. - ORDER
security_nameincludes the execution venue. gxpdf does not always put a space between the Bezeichnung and Ausf.platz/-art columns (e.g."GLOBAL X COPPER MINERS ETXETRA"), so the venue is left attached to the name rather than split unreliably. Order confirmations therefore do not populate a separateexecution_venue. - Metadata extraction (
depot_holder,depot_number) can be empty or noisy on documents whose layout places the value far from its label. - Account number (
Konto Nr.) is matched at a fixed length (11 digits) to work around a page-break run-on in text extraction; non-standard lengths won't match. (The depot number is matched at any length.) - SAVINGSPLAN WKN is not present in Sammelabrechnung documents; the
wknfield will be empty for these transactions. deposit_countrycovers a fixed country list.Lagerlandis translated from its German name to an ISO 3166-1 alpha-2 code against a built-in table. gxpdf runs that column straight into the next one ("GroßbritannienBemessungsgrundlage: 0,00 EUR"), so matching a known name is also what separates the two — a country outside the table yields no code rather than a half-captured string. Please open an issue if a real statement names one the table misses.
Additional document types (e.g. tax reports) will be added as samples become available.
Contributing & Development
Contributions are welcome — bug reports, code, and above all real sample documents. The parsers only get better with real-world PDFs, but broker statements are full of PII. This project's test fixtures are real flatex PDFs with the PII redacted and replaced in place with synthetic values — visually and structurally identical to production documents, safe for a public repo:
The full method — and why naively generated synthetic PDFs give you passing tests and a broken parser — is covered in Your AI's Test Fixtures Are Lying to You. Make real-world synthetic PDF files, PII safe!
Project layout, test/lint setup, and the PR checklist: CONTRIBUTING.md. For issues, feature requests, or questions, open an issue on GitHub.
License
Licensed under the MIT License. You're free to use, modify, and redistribute it, including for commercial purposes, provided the copyright notice is retained. The software is provided "as is", without warranty of any kind and with no liability on the author's part — see the LICENSE file for the full disclaimer.
Documentation
¶
There is no documentation for this package.