Extracting Structured Fields From a Home Warranty Claim Form
9 min read · updated August 11, 2026
A home warranty claim form looks like one document and behaves like two. The homeowner’s half is a short structured request; the contractor’s half is a technician’s narrative, and that narrative contains the only sentence with consequences.
Two documents sharing one form
The first half is filled in when the claim is opened: contract number, property address, the item that failed, a description of the symptom, a contact number, sometimes the date the problem was first noticed. It is form-shaped, it is usually typed or captured from a web form, and it is the half most extraction work stops at.
The second half is filled in after a service call. It carries the contractor’s identity, the appliance or system make, model and serial as read from the data plate, the diagnosis, the recommended repair or replacement, parts and labour figures, and often an opinion about why the thing failed. Structurally it is a service report bolted onto a claim form, and everything that determines what happens next lives in it.
Model them as two related records with their own dates and their own authorship rather than as one flat object — a small case of multi-entity document schema design — because they are asserted by different people at different times and they can disagree. A homeowner reporting “air conditioning not cooling” and a technician reporting a failed compressor are consistent; a homeowner reporting a leaking water heater and a technician reporting a dishwasher supply line is a mismatch a human should see.
Covered items are a per-contract vocabulary
This is where a generic taxonomy fails. Home service contracts do not cover “HVAC”. They enumerate specific covered items — typically things like the heating system, the air conditioning system, the water heater, ductwork, the built-in dishwasher, the range or oven, the garbage disposal — each with its own exclusions and often its own dollar cap. The enumeration is a property of the individual contract and plan tier, not of the industry.
So the extraction target for the item field is not a free string and not a global enum. It is a mapping onto the covered-items list of this contract, with an explicit unmatched state. Load the contract’s list, extract the item as printed, then map. Where the claim says “furnace” and the contract says “Heating System”, the mapping is a synonym rule you wrote and can inspect. Where the claim says “pool heater” and the contract has no such line, the correct output is unmatched — not the nearest neighbour, and not a coverage conclusion.
{
"contract_number": "HW-0000-EXAMPLE",
"claim": {
"reported_item_text": "furnace not igniting",
"mapped_covered_item": "Heating System",
"mapping_basis": "synonym rule: furnace -> Heating System",
"reported_on": "2026-01-08"
},
"diagnosis": {
"contractor": "Example Mechanical LLC",
"visited_on": "2026-01-10",
"equipment": { "make": "ExampleCo", "model": "EX-80B",
"serial": "SYNTHETIC-0000", "serial_source": "data plate photo" },
"narrative": "Ignitor cracked. Unit shows heavy soot at burners; no service
records provided. Recommend ignitor replacement.",
"cause_phrases": [
{ "text": "Ignitor cracked", "category": "component_failure" },
{ "text": "heavy soot at burners", "category": "maintenance_indicator" }
],
"cause_category_confidence": "low"
}
}Regional naming differences make the mapping table longer than expected — disposal and waste disposer, hob and cooktop, immersion heater and water heater. Build it as data, version it, and treat an unmatched item as a signal that the table needs a line, not that the claim is wrong.
Cause language is the field with consequences
The homeowner’s symptom description says what stopped working. The technician’s narrative says why, and the why is the part that interacts with the contract. Narratives in this genre cluster around a small number of causes that contracts treat differently: ordinary mechanical failure, lack of maintenance, improper prior installation, a pre-existing condition, damage from an outside cause, or a modification. Those phrases are not printed in labelled boxes. They are embedded in two or three sentences of trade shorthand.
Extract them as a list of spans with a suggested category and the verbatim text, never as a single resolved cause. Three reasons:
- Narratives are frequently ambiguous on purpose. “No service records provided” is an observation, not a finding of neglect, and a categoriser that turns it into one has made a determination the technician declined to make.
- Multiple causes coexist. A cracked ignitor and heavy soot are two statements and the second may or may not explain the first. Collapsing to one loses the relationship.
- The categorisation is exactly where a model is weakest. This is short, idiomatic, abbreviation-heavy text with high stakes attached to a nuance. Mark the category confidence separately from the extraction confidence — you can be certain you read the words correctly and uncertain what they mean, and one number cannot say both, which is an argument for scoring confidence per field rather than per document.
Handwriting compounds it. Service tickets are still written by hand on carbon-copy pads, so the narrative arrives as handwriting with domain abbreviations in it. An illegible clause in the cause sentence should suppress the category entirely rather than yielding a guess.
Trade fee, caps and the requested amount
Several amounts appear and they are not interchangeable. The trade service call fee is the fixed amount the homeowner pays per visit under the contract. The contractor’s quoted repair total is what the work would cost. The per-item cap is a contract term, not a number on this form. The amount requested for reimbursement, on the claim forms that have one, is what the homeowner is asking to be paid back, and it may exceed both.
Keep them as separate named fields with the label as printed attached to each, and do not compute a payable amount. Payable is a coverage determination that depends on contract terms, caps, exclusions and human judgement. An extraction pipeline that outputs a payable_amount has quietly become the adjudicator, and it will be wrong in the cases that matter most.
The one arithmetic check worth running is internal, and it is a textbook cross-field amount validation: parts plus labour plus tax against the quoted total on the same form. A mismatch is nearly always a misread digit or a missing line, and it is caught for free.
What the cross-check may conclude
Cross-referencing the claim against the contract’s covered-items list is worth doing and its output must be phrased carefully. What the check can honestly say is: this item maps to a covered item on the contract, this item does not map to any line, or this mapping is uncertain. What it cannot say is whether the claim is covered — coverage turns on exclusions, on maintenance provisions, on the cause language above and on terms this form does not contain.
The useful product of the whole extraction is therefore a routing decision rather than a verdict: claims where the item maps cleanly and the narrative shows an unambiguous component failure look routine; claims with an unmatched item, a maintenance-indicator phrase, or a mismatch between the reported and diagnosed item go to a person with the specific reason attached. That is the same pattern as any other review-routing decision, with a document-specific trigger list instead of a confidence threshold.