Extracting Loss Run History From an Insurance Loss Run Report
11 min read · updated August 11, 2026
A loss run is a table of claims with money attached, and almost every number in it is provisional. Extracting it accurately and then joining two of them is how you turn accurate data into a wrong answer.
What a loss run is a snapshot of
Carriers produce loss runs to show an insured’s claim history, usually several policy years deep, usually one row per claim, usually with per-year subtotals and a grand total. They are used to underwrite a renewal, so their audience already knows how to read them and the documents are written accordingly: dense, abbreviated, and without any explanation of what a column means.
The single most important field is not on any claim row. It is the valuation date — the “as of” date in the header, sometimes phrased as “valued through”. Every money column is that column as it stood on that date, and it will be a different number next month. An extraction that drops the valuation date has produced rows that cannot be compared with any other rows, including later rows about the same claims.
Extract the header block as a first-class record: insured name, carrier, policy numbers and periods covered, valuation date, report run date (often different from the valuation date), whether amounts are gross or net of deductible, and the currency. Half of these appear once on page one of a fifty-page document, which means a page-parallel pipeline needs to propagate them onto every row rather than extracting each page independently.
The per-claim columns and the identity between them
The columns vary by carrier, but the vocabulary is standard enough to normalise onto:
- Claim number, and separately the carrier’s internal occurrence number where both appear.
- Date of loss and date reported. Two distinct dates, and the gap between them is the reporting lag — a derived field worth computing because a long lag pattern is what an underwriter is looking for.
- Status — open, closed, reopened. Closed claims with a non-zero reserve are an anomaly worth flagging.
- Coverage or line of business, and a cause-of-loss code.
- Paid indemnity and paid expense, usually separate columns because the second is legal and adjusting costs and is treated differently.
- Outstanding reserve, again often split into indemnity and expense reserves.
- Incurred, the total.
- Recovery, salvage or subrogation, which reduces the net figure.
The identity that makes the extraction checkable is:
incurred = paid_indemnity + paid_expense + reserve_indemnity + reserve_expense net_incurred = incurred - recoveries
Check it per row — it is a cross-field amount validation in the textbook sense. A row that fails it has almost always suffered a column misalignment or a dropped digit rather than a genuine accounting oddity, so it is a high-precision detector of exactly the errors that are otherwise invisible. Two caveats keep it honest: some carriers report incurred net of recoveries in the same column, so establish which convention the report uses from a handful of rows before asserting a systematic failure; and some reports exclude expense from incurred entirely under a deductible arrangement where expenses are handled separately.
Footing the years
The second check is vertical: the per-claim rows within a policy year should sum to the stated year subtotal, and the subtotals to the grand total. Work an example with three claims in one year, all figures assumed for illustration:
claim paid reserve incurred
A 12,400 0 12,400 (closed)
B 3,050 18,000 21,050 (open)
C 0 2,500 2,500 (open)
-------
sum of extracted rows 35,950
stated 2024 subtotal 41,200
difference 5,250A difference is a finding, not necessarily an error, and the diagnosable causes are a short list. A claim row may have been missed — usually one that fell across a page break or sat under a repeated header. The subtotal may include claims suppressed from the detail listing, such as those below a reporting threshold or those on a separate confidential schedule. The subtotal may be net of a deductible while the rows are gross. Or the year grouping differs: rows may be grouped by policy year while the subtotal is by accident year or report year, which puts a claim with a January date of loss on the other side of the line.
Emit the difference and the candidate explanation rather than suppressing it. A reconciliation field that says “rows sum to 35,950 against a stated 41,200; 3 rows extracted, page 4 header repeated” routes a document to a reviewer with the work already done. This is the same discipline as reconciling premium lines against a declarations page total, where the arithmetic also fails for reasons that are entirely correct.
Why the same year has two different totals
Claims develop. A claim reported at a $10,000 reserve may settle at $40,000 or close at nothing, and the reserve moves as the adjuster learns more. So a loss run valued at 2025-06-30 and one valued at 2026-06-30 will show different incurred figures for the identical policy year and the identical claims, and neither is wrong.
This has two hard consequences for a pipeline that ingests loss runs repeatedly. First, never treat two reports as additive. Appending a new report to the same table double counts every claim that appears in both, and because the amounts differ the duplicates do not even collide on an exact match. Store one row per (claim number, valuation date) and make that the key. Second, the interesting derived quantity is the change between valuations — development on a claim, or the emergence of claims reported late — and you get it for free once the key is right and cannot get it at all once you have flattened reports together.
Claim numbers themselves are not stable across carriers, and are not always stable within one carrier after a system migration. Where a claim needs to be tracked across a change of carrier, the match has to be built from date of loss, claimant and amount, which is fuzzy by nature and belongs in a reviewed process rather than in the extraction.
Where it goes wrong
- Repeated headers mid-table. Multi-page tables repeat their header on every page, and a header row parsed as data produces a claim numbered “CLAIM NO” with zero amounts that silently passes most validators. This and the shifting columns below are treated generally in table column misalignment across pages.
- Column widths shift on page two. A wide claimant name on one page can push a table renderer to different column positions on the next. Detect columns per page rather than once.
- Parenthesised recoveries. Recovery columns are often shown as negatives in parentheses, and a naive numeric parse turns a reduction into an increase.
- Zero shown as a dash. A hyphen, an em dash or an empty cell all mean zero; only one of them parses as a number.
- Claimant names are personal data. Loss runs contain names and sometimes injury descriptions. Decide what leaves your infrastructure before the file reaches a hosted model, and see PII redaction for the mechanics.