Challenge
The numbers were locked inside hundreds of pages of prose.
A 10-K is a narrative document with tables in it. The financial statements sit somewhere in the middle of hundreds of pages, and every company lays them out its own way — different section ordering, different labels for the same line item, different table structures, footnotes that change what a figure means.
So the work fell to a person: open the filing, find the statements, and re-key the figures into a spreadsheet, filing by filing. It was slow, it capped how fast the service could deliver, and every manual step was a chance to put a number in the wrong row — the kind of error that survives all the way into a user's conclusion because nobody re-checks a figure that looks plausible.
The bar the client set was uncomfortable on purpose: the extraction had to hold across all five statement types, not just the headline income statement. Anything less and their user still has to open the filing — which means the service hasn't removed the manual step, only moved it.
Solution
An extraction pipeline built around what a statement means.
We built a system that reads a filing end to end, locates the financial statements inside it, works out which of the five statement types each one is, and pulls the figures out into a consistent structure — the same shape for every company, regardless of how that company chose to present its own accounts.
Layout was the hard part, so the system doesn't rely on it. It works from what a line item is rather than where it sits on the page, which is what lets one pipeline handle filings from issuers that share no common template. Validation runs on the way out: totals that don't reconcile and figures that contradict each other are surfaced rather than silently exported.
The last mile was deliberately unglamorous. Output lands as an Excel workbook in the structure their users already work in, so the result plugs into existing models instead of asking anyone to adopt a new tool. Under the hood it runs on Python with a FastAPI service and a PDF-parsing layer — the interesting engineering is in the statement recognition, not in the stack.
The five statement types the pipeline covers
- Income statement
- Balance sheet
- Cash flow statement
- Statement of shareholders' equity
- Statement of comprehensive income
Result
Up to 98% extraction accuracy across all five statement types.
Accuracy was measured against filings that had been verified by hand, and it held across all five statement types rather than only on the statement that is easiest to parse. That is the number that mattered: coverage without a soft spot, because a soft spot is what sends a user back into the PDF.
The output landed directly in the spreadsheet format their users already worked in, so extraction stopped being a step somebody performed and became something that had already happened by the time a user opened the data. The manual re-keying — and the transcription errors that came with it — came out of the service.
We publish the figure as "up to 98%" on purpose. Extraction accuracy depends on the source documents, and we would rather quote a number we can stand behind on a fresh set of filings than one that only describes a good day.