The granular spec behind the "Property data prefill" box on the architecture map: which external data providers exist, what each API takes and returns, what each call costs, how we decide call-all vs choose-one, where the data lands in our own tables so we never pay twice for the same fact, when we re-pull, and how every returned field maps onto the product model's provisions & options — plus how the same data feeds the RAG / agentic layer.
See it live: the Policy Design page ↗ seeds its provision/option defaults from this data — look for the ⬡ prefill / 🔒 read-only provenance icons on each field · where this service sits on the architecture map ↗.
On this page: 0 · Our API contract · 1 · Vendor catalog & costs · 1b · Published vendor API contracts · 2 · Choose-one vs call-all · 3 · Our storage tables · 4 · Refresh criteria · 5 · Field → provision mapping · 6 · Post-AI era
Flows never talk to vendors. They call our prefill service — Groundwork (Cloud Run; "the ground truth under every quote") — through one stable contract; the vendors behind it are swappable line items. Every field comes back with source + confidence + fetched-at — provenance is part of the contract, not an afterthought.
Six source classes. Costs are indicative, order-of-magnitude figures (real pricing is contract-negotiated and volume-tiered) — but the ratios between tiers are what drive the architecture, and those are stable: free public records → cents-level aggregators → dollar-level AI/consumer reports. Every vendor's own published API contract — endpoint, request, response, attribute by attribute — is documented in §1b below.
| Source | You send | You get back | Indicative cost | Quality / coverage notes |
|---|---|---|---|---|
| County assessor / parcel | APN or address | year built, sq ft, stories, lot size, assessed value, deed/sale history | $0 (bulk files) | Authoritative but 3,000+ counties, 3,000+ schemas — the cost is normalization engineering, not per-call fees. Aggregators below exist to solve exactly this. |
| FEMA NFIP flood maps | lat/lng | flood zone (X / AE / VE…), BFE, map panel + effective date | $0 (open API) | Authoritative for flood. Changes only on map action (LOMR/LOMA/panel revision) — effectively never stale until an event we can subscribe to. |
| CAL FIRE FHSZ (CA only) | lat/lng | fire-hazard severity zone (Moderate / High / Very High) | $0 (open data) | Regulatorily load-bearing in CA — drives defensible-space/disclosure duties, and CA's Safer-from-Wildfires rule (state regulation Cal. Code Regs. §2644.9 — not a section of this page) requires insurers using wildfire risk in rating to recognize mitigation. Multi-state: outside CA the fire-zoning slot is filled by state wildfire-risk maps (OR/WA/CO publish their own), USFS (US Forest Service) Wildfire Risk to Communities, or a vendor score (Class F) — same field, per-state source hierarchy. |
| USGS / NOAA layers (federal geology & weather agencies) | lat/lng | slope, aspect, vegetation class, historic weather | $0 | Inputs to our own cat-model rather than shown to customers. |
| Vendor | You send | You get back | Indicative cost | Quality / coverage notes |
|---|---|---|---|---|
| Regrid | address or lat/lng | normalized parcel record + geometry, APN, zoning, owner | ~$0.02–0.10/lookup or flat data license |
The "address → parcel" resolver. Strong geometry; thin on structure detail. Often the first hop that every other call keys off. |
| ATTOM | address / APN | property detail: beds/baths, construction, heating, sale + mortgage history, AVM | ~$0.10–0.50/property (subscription tiers) | Broad national coverage, recompiled from county data — good fill rate, occasional staleness on recent renovations. |
| Cotality (form. CoreLogic) | address | insurance-grade characteristics: construction class, roof type, plumbing/electrical, hazard attributes | ~$0.50–2.00/property | Insurance-tuned (carriers are the customer base). Typically the primary characteristics vendor candidate vs Verisk in a bake-off. |
| Verisk (ISO ProMetrix / Location) | address | ISO Protection Class (PPC), hydrant/station distance, territory codes, construction | ~$0.50–2.00/report | The de-facto standard for fire-protection grading — PPC is referenced directly in filed rates, so this one is hard to substitute. |
| LexisNexis (non-FCRA tier) | address + named insured | identity verification, property linkages, occupancy signals | ~$0.25–1.00/txn | Dual-natured vendor: its identity products are non-FCRA; its C.L.U.E. product (Class D) is a consumer report. Never blur the two tiers. |
| Vendor | You send | You get back | Indicative cost | Quality / coverage notes |
|---|---|---|---|---|
| Cape Analytics (Moody's) | address | AI-extracted: roof condition score, roof material/geometry, vegetation overhang, defensible space, pool/trampoline detection | ~$1–3/property | Attributes, not pixels — built for exactly this underwriting use. Condition scores carry model confidence; treat as signal, not ground truth. |
| Nearmap AI | address / polygon | high-res recent imagery + AI layers (roof, solar, vegetation) | annual subscription (area-based) + AI packs ≈ $0.50–2 effective/lookup at portfolio volume |
Imagery freshness is the differentiator (multiple captures/yr in metro areas). Subscription model favors portfolio-wide use over per-quote calls. |
| EagleView | address | measured roof report (squares, pitch, facets), imagery | ~$20–50/full report | Too expensive for quote-time. Belongs in claims (scope-of-repair) and targeted underwriting inspections — a per-flow cost decision, not a prefill default. |
| Vendor | You send | You get back | Indicative cost | Quality / coverage notes |
|---|---|---|---|---|
| LexisNexis C.L.U.E. Property | named insured + address + permissible purpose | 7 yrs of claims: date, peril, amount paid, status | ~$2–5/report | A consumer report: needs a permissible purpose, drives adverse-action duties, access-scoped, and never cached for reuse on a different consumer's quote. |
| Verisk A-PLUS | same | same shape — the competing claims database | ~$2–5/report | Coverage overlaps C.L.U.E. but not 100% — carriers contribute to one or both. This is the one class where call-both can be justified for high-value risks. |
| Vendor | You send | You get back | Indicative cost | Quality / coverage notes |
|---|---|---|---|---|
| Verisk 360Value | address + characteristics (sq ft, quality grade, features) | component-based replacement-cost estimate + assumptions | ~$1–3/valuation | Quality of output = quality of input characteristics — which is why it runs after Class B/C in the waterfall, fed by their fields. |
| Cotality RCT | same | same shape (the competing estimator) | ~$1–3/valuation | Pick one and pin its version with each estimate — the figure backs Coverage A (the dwelling limit — the most the policy pays to rebuild the house), so the basis must be reproducible at claim time. |
| Vendor | You send | You get back | Indicative cost | Quality / coverage notes |
|---|---|---|---|---|
| Verisk FireLine | address | wildfire hazard score (fuel, slope, access) | ~$0.50–2.00/score | The incumbent score many state filings reference. |
| ZestyAI Z-FIRE | address | ML wildfire risk score, structure-specific | ~$1–2/score | Newer ML challenger; approved in several state filings. A natural A/B candidate against FireLine. |
| Our climate cat-model | POST /peril-scores {lat,lng} | wildfire / flood / wind scores + model version | internal (licensed core) | Already a first-class platform service — vendor scores above act as independent challengers to it, not replacements. |
| Feed | You send / subscribe to | You get back | Indicative cost | Quality / coverage notes |
|---|---|---|---|---|
| County recorder / deed monitoring | APN watchlist | deed transfer, sale, foreclosure events | $0 (bulk) or via ATTOM feed (~bundled) | Powers the "deed/sale change detected" trigger; aggregators resell it as a delta feed so we don't poll 3,000 counties. |
| Building-permit data (BuildFax / Shovels) | address / APN watchlist | permit filed: re-roof, solar, addition, pool | ~$0.10–0.50/property/yr (watchlist) | The "permit signal" trigger — a re-roof permit is the cheapest possible roof-age update (vs a $2 imagery call). |
| FEMA map-change feed (LOMR/LOMA) | map-panel subscription | flood-map revisions for watched panels | $0 | The event that replaces a flood-zone TTL entirely. |
| Verisk PPC re-grade bulletins | community watchlist | community protection-class changes | bundled with ProMetrix/LOCATION contract | Community-level, announced — refresh only the affected book slice. |
| Cat-event polygons | event subscription | wildfire/hail/wind footprint geometries | internal (cat-model) / NOAA-NIFC $0 | Intersect against parcel geometry → targeted imagery refresh of only the exposed slice (the §4 imagery trigger). |
The stakeholder question this section answers: "what does each service actually return?" Read the response shapes side by side and the procurement call becomes visible — this one is cheaper and good enough for presale; that one is worth it at formal quote; that one belongs only in claims. Tags say how readable each vendor's docs are today, without an NDA: public docs read the full schema now · endpoint public · schema gated URL + auth + params published, response schema on contract · gated / NDA representative shape from public sources, confirm under contract (NDA = non-disclosure agreement — the vendor shares full docs only after a contract is signed).
How to read each card: the highlighted "Why we call it" box states the full chain — what goes in, what comes out, which API consumes that output next, and where it finally lands in the quote (no API on this page exists for its own sake). Below the raw request/response, the "In plain English" line translates the URL and JSON for readers who don't live in them. One translation up front, used everywhere: when a card says API key, token, or header, those are just our account credentials attached to the request — the vendor's way of knowing who's calling and who to bill (OAuth is just a standardized handshake for obtaining such a token). And every Tier number on this page is a rung of the cost waterfall — click any tier mention for the ladder.
When: Tier 0.5 fallback geocode + the FIPS keys (state/county/tract) every downstream peril lookup joins on.
Why we call it: on its own, a coordinate pair is useless to a quote — no policy provision asks for latitude. We call this API because the two hazard services below (FEMA flood, CAL FIRE fire) can only be queried by point, not by address. The chain: address in → coordinates (x,y) out → those exact numbers become the geometry= parameter of the FEMA NFHL and CAL FIRE FHSZ calls → which return the flood zone and fire zone → which set the flood-coverage and wildfire-mitigation defaults in §5. The GEOID (FIPS state/county/tract codes strung together) is the second prize: it's the join key for tract-level datasets — e.g. joining tract-level wildfire-loss experience into territory rating — and COUNTY cross-checks Smarty's county_fips.
In plain English — what we send: the one-line property address as the customer typed it, plus two version pins (benchmark, vintage) so the same address always resolves the same way. What we get back: the government's official coordinates for that address and its census geography codes. We never show these to anyone — they exist purely to feed the next two calls on this page.
Docs: geocoding.geo.census.gov — Geocoding Services API · Auth: none · Cost: $0
When: every quote (Tier 1). SFHA_TF: "T" = Special Flood Hazard Area → the mandatory-flood-insurance trigger; FLD_ZONE + STATIC_BFE drive the §5 flood mapping.
Why we call it: this is where the geocoder's coordinates get spent. Coordinates in (the geometry= param) → one underwriting question answered: is this property in a federally mapped flood zone? SFHA_TF:"T" means a Special Flood Hazard Area — by federal rule, a mortgaged home there must carry flood insurance, so the quote flow has to surface flood coverage and the NFIP referral. FLD_ZONE + STATIC_BFE fill our normalized flood_zone field → §5 maps that to the flood provisions and the referral copy the customer sees.
In plain English — what we send: just a point — the longitude/latitude the geocoder produced — and the list of fields we want back. (The URL is the ArcGIS query format — the standard map-server software US government agencies run — which is why the CAL FIRE call below looks nearly identical.) What we get back: the flood-zone designation for that exact point. FLD_ZONE:"AE" = high-risk river/coastal flooding; SFHA_TF:"T" = the mandatory-flood-insurance flag; STATIC_BFE: 42.0 = how high (in feet) the water is expected to reach in the benchmark flood — the number elevation certificates argue about.
Docs: hazards.fema.gov — NFHL MapServer layer 28 · Auth: none · Cost: $0
When: every CA quote (Tier 1) — fills the normalized fire_zone field. Service verified live; this MapServer carries the 2007 SRA / 2011 LRA vintage — the 2024–25 adopted zones publish via the CAL FIRE FHSZ Hub with the same HAZ_CLASS vocabulary.
Why we call it: the second place the geocoder's coordinates get spent — same pattern as FEMA, this time for wildfire. Coordinates in → HAZ_CLASS ("Moderate" / "High" / "Very High") out → that value fills our normalized fire_zone field → §5 turns it into the wildfire-mitigation options (defensible-space credits, roof-class requirements), and it cross-checks our own climate cat-model's score. SRA tells us whether the state or the local fire department is responsible for that land — which decides which zone-map vintage applies.
In plain English — what we send: the geocoder's coordinates again, asking for three hazard fields and no map shapes (returnGeometry=false keeps the response tiny and fast). What we get back: California's official fire-hazard severity rating for that point. "Very High" is the rating that triggers mitigation requirements — and for some carriers, declination; for us it triggers the mitigation-credit options in §5.
Docs: services.gis.ca.gov — Fire_Severity_Zones MapServer · Auth: none · Cost: $0
When: Tier 0.5, before any money is spent — CASS-certified normalization (USPS's stamp that the address comes back in its one official spelling) so the cache key can never split on "Dr" vs "Drive". Bonus underwriting signals for free: rdi (residential/commercial) and dpv_vacant.
Why this is the FIRST call in the chain: every later vendor — and our own cache (the database where Groundwork stores every vendor answer it has already paid for) — keys off the address string. If "1842 Skyline Dr" and "1842 Skyline Drive" looked like different properties, we'd buy the same data twice and split one property's history in two. Smarty returns the single USPS-canonical form → that string becomes the cache key → Regrid turns it into an APN / property_id. Its latitude/longitude can replace the Census geocoder call entirely (one less hop), and rdi / dpv_vacant are free eligibility gates: a commercial or vacant "home" fails homeowner eligibility before we spend a cent on paid vendors.
In plain English — what we send: the raw address parts the customer typed, plus our account keypair. What we get back: the same address the way USPS writes it (delivery_line_1), its ZIP+4, coordinates, the county FIPS code (the government's numeric ID for the county), and two cheap red flags — rdi:"Commercial" (this isn't a residence) and dpv_vacant:"Y" (USPS says nobody lives there). Either flag stops the prefill chain before any paid call happens.
Docs: smarty.com/docs — US Street Address API · Auth: auth-id/auth-token keypair · Pricing: published at smarty.com/pricing
When: first hop on every cache miss (a property we haven't bought data for yet) — address → APN mints property_id. Full schema is public; building fields (yearbuilt, footprint) are in standard tiers.
Why we call it: the Assessor Parcel Number (parcelnumb) is the missing primary key. Addresses change spelling and formatting; the APN is how the county itself identifies the land. Clean address (from Smarty) in → APN out → we mint our internal property_id from it → every later vendor result, cache entry, and refresh event hangs off that one id — one id means one paid data history per property, the dedupe that makes the §2 cache savings real. The bonus characteristics (yearbuilt, building sqft, land use) give the quote form its first real defaults, and landval/improvval sanity-check the replacement-cost estimate in Class E.
In plain English — what we send: the normalized address (or a map point, or an APN directly if we already have one) plus our token. What we get back: the county's parcel record — the APN, what's built on it (year, style, square footage, footprint), how it's zoned, the lot size, and the assessor's land/improvement values. usedesc:"Single Family Residential" confirms we're even quoting the right product.
Docs: support.regrid.com — Parcel API endpoints · full parcel schema · Auth: token query param · Pricing: plans behind signup, free 30-day trial
Decision lens: the "cheaper and good enough for presale" candidate — broad national fill at ~$0.10–0.50. Construction/roof attributes exist in deeper packages but aren't in the public sample — verify fill-rate in the §2 bake-off before relying on them for rating.
Why we call it: the presale characteristics fill. Address in → tax-record profile out: yearbuilt, livingsize, beds/baths become the quote-form defaults the customer confirms instead of types, and they're the inputs the replacement-cost estimator (Class E) needs to produce a Coverage A number. The apn/fips echoed back lets us double-check Regrid's parcel match before caching anything under the wrong property_id.
In plain English — what we send: the street line and city/state of the property, with our API key in a header. What we get back: a profile assembled from county tax records — what kind of building it is, when it was built, its living area and room counts, lot size, and an estimated market value. Cheap (~$0.10–0.50) and nationally broad, but tax records can lag reality — which is exactly why the §2 bake-off measures fill-rate before we trust these fields for rating.
Docs: api.developer.attomdata.com/docs (interactive, free trial key) · Auth: apikey header · Pricing: subscription tiers, not public
Decision lens: the insurance-grade characteristics candidate for formal_quote — carriers are the customer base. US property/CLIP API schema requires contract; its MLS product (Trestle — MLS is the real-estate listing system agents use) and AU (automated-underwriting) portal are public, which shows the integration style.
Why we'd call it: the formal-quote upgrade over ATTOM. The CLIP id plays the same role as Regrid's APN — a universal property key — but the payload is the insurance-grade set: construction class, roof type/material, plumbing/electrical age. Those are exactly the fields the 360Value/RCT replacement-cost call (Class E) consumes and the rating engine prices by. Address or CLIP in → carrier-grade characteristics out → Coverage A default + construction rating factors.
In plain English — what we send (under contract): an OAuth login, then a property lookup by address or CLIP id. What we get back: the property's physical build sheet at the accuracy level carriers rate on. Exact field names are NDA'd — so the right read of this card is "this is the vendor conversation to have when the §2 bake-off shows ATTOM's gaps in construction/roof fields cost more in Coverage A error than Cotality's per-call premium," not "integrate today."
Portal: developer.corelogic.com (marketing shell; access via sales) · Public reference of style: Trestle docs · Auth: OAuth 2.0 · Pricing: contract
When: the natural §2 bake-off challenger to Regrid — full OpenAPI spec is readable today; evaluation keys on registration. Also wraps FEMA NFHL as a convenience API.
Why we'd call it: the bake-off challenger to Regrid for the same job in the chain — address → parcel/APN → property_id. Keeping two interchangeable vendors for the chain's first paid hop is deliberate: it keeps per-call pricing honest and gives us a failover if one has an outage. Its FEMA-NFHL convenience wrapper also means one vendor could collapse two calls (parcel + flood zone) into one bill.
In plain English — what we send: a free-text address (or a FIPS+APN pair — county number plus parcel number — or a map point) with an API key header. What we get back: the parcel identified (parcelApn, fips), where it sits, how the land is used, assessed values, and an occupancy flag — OWNER_OCCUPIED matters because owner-occupied vs rented changes which policy form even applies.
Docs: lightbox.document360.io — Parcels · Auth: x-api-key header · Pricing: not public
When: every formal quote — PPC is referenced directly in filed rates, so this is the hard-to-substitute call. Endpoint, params and auth are publicly documented; the response schema ships under contract.
Why we call it: PPC is the fire-protection grade (1 = best, 10 = worst) that filed rates reference by name — the approved rating table literally has a PPC column, so no PPC means no priceable formal quote. Address in → split class out (e.g. 4/4X) → the rating engine reads it directly. It's also the one field on this page we can't substitute with our own model, because the regulator approved our rates as filed against PPC.
In plain English — what we send: street/city/state/zip plus Verisk credentials (a token and org ids). What we get back: the community's fire-protection grade for this address. "4/4X" decodes as: a fire station within 5 road-miles earns class 4; the X suffix says the home is more than 1,000 ft from a hydrant — water has to be trucked in, so it prices worse. respondingStation.distanceMiles is the underlying driver an underwriter can verify on a map.
Docs: prometrixapi.iso.com/docs — PPC by Address · split-class explainer · Auth: Verisk STS token (their central login service) + branch id · Pricing: contract
Decision lens: the only imagery-AI vendor with a fully public field-level schema — and its supplementals (wildfireScore, defensibleSpace) overlap Class F, so one subscription can cover two catalog rows. Credit/subscription model favors portfolio sweeps + renewal refresh over per-quote calls.
Why we call it: aerial-photo AI sees what tax records can't — the current physical condition of the roof and the vegetation around it. Address in → parcel-clipped AI features out → roofSpotlightIndex + roof material feed the §5 loss-settlement options (a worn roof gets actual-cash-value settlement terms, not full replacement-cost), and defensibleSpace/wildfireScore overlap Class F — so one Nearmap subscription can double as the wildfire-score source.
In plain English — what we send: the address, which "packs" of AI features we want (roof condition, vegetation), and parcelMode=true so results are clipped to this parcel — not the neighbor's roof. What we get back: machine-read facts from the latest aerial survey (surveyDate says how fresh): what the roof is made of (Tile, 82% of the area), its condition score (roofSpotlightIndex: 0.71 — closer to 1 is healthier), and how much burnable vegetation sits within striking distance of the structure.
Docs: developer.nearmap.com — AI Feature API · Auth: apikey · Pricing: subscription + AI export credits, list not public
When: the conditional Tier 3 quote-time call. API reference is customer-gated, but the attribute vocabulary is public via product pages and rate filings — the 5-band roof condition scale below is what §5 maps to loss-settlement options.
Why we'd call it: the conditional Tier-3 call — fired only when the cached roof data is stale or the cat-model score is borderline, because every call costs real money. Address in → graded roof verdict out → roof_condition_rating is the field §5 maps to loss-settlement options, and the reason_codes (tarp, patching, standing water) are human-readable evidence an underwriter can act on — and that we can show the customer to explain a referral (routing the quote to a human underwriter instead of auto-approving it).
In plain English — what we send (under contract): an address or coordinates, choosing which analytic modules to run. What we get back: a graded roof verdict — "Fair" on a Severe→Excellent scale — plus the visible reasons behind the grade (streaking, patching), and yard-level liability flags like a pool or trampoline, which trigger liability questions in the quote flow.
Vocabulary: Roof Condition Rating v5 · reason codes · Auth/pricing: contract
Decision lens: an ordered report, not a real-time lookup — $20–50 and hours, not milliseconds. That shape alone tells the stakeholder where it belongs: claims scope-of-repair and targeted inspections, never quote-time prefill.
Why we'd call it: this isn't prefill at all — it's how a claims adjuster gets exact roof measurements (area in squares, pitch, every facet edge) to price a repair without climbing the roof. The chain runs from the other direction: claim filed → order placed → measured report hours later → scope-of-repair estimate. Its presence on this page is a scoping decision made visible: $20–50 per report and hour-scale latency disqualify it from quote-time.
In plain English — what we send: an order — the property address plus product codes saying which report type and delivery speed we're buying. What we get back, immediately: just order and report IDs (a receipt). The actual deliverable — a measured roof report with area in roofing squares, pitch, and edge lengths — is fetched later through the status/report endpoints once their measurement pipeline finishes.
Docs: developer.eagleview.com (a JavaScript single-page app — open it in a browser; public Postman workspace exists) · Auth: OAuth2 (24 h token) · Pricing: contract
When: formal_quote only, under permissible purpose. Docs require an approved portal application; the report contents are well-documented by regulators (7-year claim window).
Why we call it: past claims are the strongest single predictor of future claims — and the one thing a customer can't tell us reliably. Name + address in → 7 years of claims on both the property and the person out → §5's underwriting referral rules fire on loss count/type/amount (e.g. a prior water loss routes the quote to water-damage review instead of straight-through bind). The FCRA strings are the cost: only at formal quote, only with certified permissible purpose, and a declination based on it triggers adverse-action notice duties.
In plain English — what we send (under contract): who is asking to be insured (name, date of birth) and which property, plus a certified statement of why we're allowed to ask (insurance underwriting). What we get back: every reported claim in the last 7 years — when, what kind (WATER), how much was paid, which carrier. A clean report sails through; an $18,400 water claim two years ago routes the quote to an underwriter.
Product: risk.lexisnexis.com — C.L.U.E. Property · Report contents per Wisconsin insurance regulator's (WI OCI) consumer FAQ · Auth: OAuth via approved dev-portal account · Pricing: contract (~$2–5 indicative)
When: formal_quote; the one class where call-both (with C.L.U.E.) is justifiable on high-value risks — the two claim databases overlap but not 100%. Note how little the request needs: names + address are the only mandatory fields.
Why we call it: Verisk's competing claims database for the identical job as C.L.U.E. — same chain position (name + address → 7-year loss history → §5 referral rules). It earns its own card because the two databases don't fully overlap: different carriers contribute to each, so on high-value risks calling both is the rare justified call-all. Its loss-type codes (WBKP water backup vs SBKP sewer backup) are also more granular than C.L.U.E.'s categories — granularity the referral rules can use directly.
In plain English — what we send: first/last name and the property address, with Verisk's bearer token and org headers — nothing else is mandatory. What we get back: the claim list with coded loss types and statuses. status:"CWP" means closed without payment — a claim that cost the carrier nothing still counts as claims history, which is exactly the nuance worth flagging for a junior underwriter.
Docs: gateway.verisk.com — A-PLUS Claims v4 (schemas via client services) · Auth: Bearer + OrgId/ShipId · Pricing: contract (~$2–5 indicative)
When: after Class B/C fields land (the estimate is only as good as its input characteristics). Pick one, pin its version with every estimate — the figure backs Coverage A and must be reproducible at claim time. RCT's SOAP surface (ExpressLync; SOAP is an older XML-based API style still common in insurance back-ends) is visible publicly; both schemas are contract-only.
Why we call it: Coverage A — the biggest number on the policy — defaults to replacement cost, not market value, and this is the call that computes it. It consumes the upstream Class B/C characteristics (sqft, quality grade, roof material, stories) → returns reconstructionCost → §5 sets the Coverage A default from it. That's why it must run after characteristics land: garbage square footage in, garbage Coverage A out. Pinning estimatorVersion with every estimate keeps the number reproducible at claim time, years later.
In plain English — what we send: the property's build facts — square footage, construction quality, roof material, stories (360Value can even start from just the address and prefill the rest itself). What we get back: what it would cost to rebuild this exact home today — $487,000 — assembled from local material and labor costs across 431 US cost regions, itemized by component, with a version stamp we store alongside the policy.
Products: verisk.com — 360Value Personal · rct.corelogic.com · Auth/pricing: contract (~$1–3 indicative)
When: the incumbent score many state filings reference — the challenger comparison for our own cat-model. A free data sample exists on AWS Marketplace for the §2 bake-off.
Why we call it: two reasons. As a rating input where our filing references it — and as the benchmark our own climate cat-model must beat in the §2 bake-off (same property set, FireLine score vs our score vs actual losses). Address or lat/lng in → 0–30 hazard score with its drivers (fuel, slope, road access) out → rating factor + the comparison row in our model-evaluation table. If our model wins that comparison, FireLine drops from per-quote spend to an annual audit sample — a vendor line item the model can delete.
In plain English — what we send: the address (or coordinates) with Verisk auth. What we get back: a 0–30 wildfire hazard score with what's driving it — how much there is to burn (fuel), how fast fire climbs toward the home (slope), and whether fire trucks can actually reach it (road access). A 23 / "extreme" pushes the property into mitigation-required territory.
Docs: gateway.verisk.com — FireLine personal lines · Auth: Bearer + org/ship ids · Pricing: contract (~$0.50–2 indicative)
When: the ML challenger A/B against FireLine. Schema is NDA, but the model structure is public via regulator filings (adopted for rating in 6+ states): L1 = probability the property falls inside a fire perimeter; L2 = probability of destruction given fire.
Why we'd call it: the ML challenger to FireLine — and a different kind of answer. Not "how hazardous is the area" but two probabilities: L1 = chance the property ends up inside a fire perimeter, L2 = chance it's destroyed given fire reaches it. L2 is where mitigation shows up — clearing defensible space moves L2, not L1 — which is exactly the structure §5's mitigation-credit options need. Adopted in 6+ state rate filings, so using it in rating is a regulator-trodden path.
In plain English — what we send (under contract): the address. What we get back: the two probabilities and the property-level factors driving them (roof, defensible space, vegetation, slope, fire-station proximity). The L1/L2 split is the actionable part: a customer can't move their house out of L1, but clearing brush moves L2 — and the premium credit moves with it.
Product: zesty.ai — Z-FIRE · Factor list per WA OIC presentation · Auth/pricing: contract
When: the §4 refresh feed — a re-roof permit is the cheapest possible roof-age update (~$0.10–0.50/property/yr watchlist vs a $2 imagery call). Fully public, self-serve API key. (BuildFax, the Verisk-owned alternative, is contract-gated with no public reference.)
Why we call it: prefilled data decays — a 2019 roof-condition score is fiction after a 2024 re-roof. Permits are the cheapest change signal in existence: counties publish them, and a roof_replacement permit on our parcel means the cached roof facts must refresh. Address → geo_id → permit feed → the §4 refresh triggers fire (re-pull imagery, recompute replacement cost) → renewal re-rates accurately in either direction: credit the new roof, catch the unpermitted addition.
In plain English — what we send: first the address (to get Shovels' geo_id for the parcel), then a permit search on that id bounded by date range, with our self-serve API key. What we get back: the permit record — what work was done ("Tear-off re-roof, Class A comp shingle"), whether it was finished and inspected (status:"final", inspection_pass_rate: 1.0), when, and its dollar value. A finaled $24,500 roofing permit is better evidence of a new roof than the homeowner's say-so.
Docs: docs.shovels.ai — permits search · Auth: X-API-Key, self-serve · Pricing: published plans
The stakeholder question this section answers: "do we need every provider, or can we choose — and on what criteria?" Answer: never call-all by default. One primary per class, chosen by bake-off; escalation only on defined risk signals; call-both only where databases genuinely don't overlap (loss history).
| Criterion | How we measure it | Why it decides |
|---|---|---|
| Match rate | % of our target-geography addresses the vendor resolves at all (test set: ~10k addresses) | An unmatched address = full manual entry = the UX we're paying to avoid. |
| Field fill rate | % of the fields we need (per the §5 mapping) returned non-null | A cheap vendor that fills 40% of fields is dearer than a $2 vendor filling 90%. |
| Accuracy | agreement vs ground truth — inspection reports + claims-time facts on our own book | Wrong year-built or roof type flows straight into rate error and claim disputes. |
| Freshness | median lag from real-world change (sale, re-roof) to data change | Stale roof data in a wildfire zone is an underwriting leak. |
| Unit cost at our volume | negotiated per-call ÷ expected quote volume, incl. minimum commitments | Contract minimums can invert the apparent ranking. |
| Uniqueness | fields ONLY this vendor has (e.g. Verisk PPC, Cape roof condition) | Unique + rate-referenced fields make a vendor non-substitutable regardless of price. |
| Licensing / compliance | FCRA status, redistribution rights, cache/retention terms, filed-rate references | Some data may not be stored beyond X days, or used outside the quoted purpose — this constrains §3's tables. |
| API latency / SLA | p95 response time + published uptime, measured during the bake-off | The vendor sits inside the 800 ms sync budget (§0) — a 1.5 s p95 vendor is unusable on the hot path no matter how good its data; it gets demoted to async backfill. |
| Tier | Source | When it's called | Marginal cost |
|---|---|---|---|
| Tier 0 | Our own property_profile + Redis | Always first. Fresh-enough data (per §4 TTLs) is served with zero vendor calls. | $0 |
| Tier 0.5 | Address resolution → property_id | The raw typed address is CASS-normalized + geocoded, then resolved to a parcel (Regrid) — property_id is minted from the stable APN + unit, NOT the address string. "Skyline Dr" vs "Skyline Drive" therefore hit the same cache row instead of double-buying every call. Condos resolve to APN+unit; new construction not yet in any DB falls through to customer entry with a pending-parcel flag. | ~$0.02–0.10 |
| Tier 1 | Public records (Class A) | On cache miss — parcel, flood zone, fire zoning resolved from bulk-loaded open data. | $0 |
| Tier 2 | ONE primary characteristics vendor (Class B winner) + PPC | On remaining field gaps at quote intake. | ~$1–3 |
| Tier 3 | Imagery AI (Class C) | Conditionally — only if FHSZ ≥ High, or roof age/condition still unknown, or cat-model score crosses the refer threshold. Not on every quote. | ~$1–3 |
| Tier 4 | FCRA loss history (Class D) | Only at formal_quote with permissible purpose — the customer has expressed real intent. | ~$2–5 |
| Tier 5 | Replacement cost (Class E) | Once characteristics are confirmed — it consumes Tier 1–3 outputs as its inputs. | ~$1–3 |
| Fallback | Named secondary per class | Per-address no-match (every primary misses 5–15%) or primary outage (circuit breaker open): fall through to the bake-off runner-up, kept warm on a low-minimum contract; if both miss, the field goes to gaps and the customer answers it. Vendor exit: the vendor-agnostic raw store (§3 prefill_payload) is the deliberate switching hedge — re-extract history, re-point the adapter, no flow logic changes. | same as primary |
Three tables in the prefill service's own Cloud SQL (no other flow reaches in — black-box rule). Raw vendor payloads are kept append-only and immutable; the merged view is rebuilt from them; every field knows where it came from.
| payload_id | property_id | vendor | api_version | request_hash | fetched_at | cost_cents | body (JSON) |
|---|---|---|---|---|---|---|---|
| PLD-9012 | PROP-8841 | cotality | v5 | a41f… | 2026-05-02 | 175 | {raw JSON, verbatim} |
| PLD-9013 | PROP-8841 | cape_analytics | v3 | 9c20… | 2026-04-11 | 210 | {raw JSON, verbatim} |
Never edited, never deleted (except per licensing/retention terms — FCRA payloads live in a separate, access-scoped store with their own retention clock). This is what makes re-extraction, vendor disputes, cost accounting (SUM(cost_cents) per vendor per month), and the §5 RAG corpus possible without ever re-buying data.
| field | value |
|---|---|
| property_id | PROP-8841 |
| year_built | 1978 |
| construction | frame |
| roof_type / condition | comp shingle / fair |
| ppc | 4 |
| fhsz_zone | Very High |
| flood_zone | X |
| replacement_cost | $612,000 (360Value v2026.1) |
| field | source | conf. | payload_id | confirmed? |
|---|---|---|---|---|
| year_built | assessor:santa_cruz_ca | 0.97 | PLD-8990 | ✓ customer |
| roof_condition | cape_analytics | 0.81 | PLD-9013 | — |
| construction | cotality | 0.92 | PLD-9012 | ✓ customer |
"Don't pull again for the same property unless there is a criterion" — here are the criteria. Two kinds: a TTL clock per source class, and event triggers that refresh early because the world changed.
| Source class | TTL (staleness clock) | Event triggers (refresh early) | Why this policy |
|---|---|---|---|
| Assessor / parcel | 12 months | deed/sale change detected; renewal | Structures change slowly; sales are the discontinuity. |
| Characteristics (Cotality/ATTOM) | 12 months | renewal; endorsement touching the dwelling; permit signal | Vendor data itself updates on a yearly-ish cycle. |
| Imagery AI (Cape/Nearmap) | 24 months | cat-event polygon intersects parcel (wildfire/hail); roof claim reported (FNOL); renewal while in FHSZ High+ | Expensive; refresh on risk signal, not calendar. |
| PPC / fire protection | 24 months | Verisk community re-grade bulletin | Community-level; changes are announced. |
| Flood zone (FEMA) | ∞ (event-only) | LOMR / map-panel revision feed | Authoritative + versioned; the map IS the event. |
| FHSZ | ∞ (event-only) | CAL FIRE map adoption | Same — rare, state-published. |
| Loss history (C.L.U.E./A-PLUS) | no reuse across transactions | pulled fresh per formal quote / renewal with permissible purpose | FCRA: it's a consumer report tied to a purpose, not a cacheable commodity. |
| Replacement cost | 12 months | renewal (inflation-guard recalc); major endorsement | Coverage A must track building-cost inflation annually. |
The whole point of buying the data: every field lands somewhere specific in the versioned product model — defaulting an option, pricing a factor, or gating eligibility. Provision IDs continue the worked example from that page. Where a prefilled value stays editable on the design page, it is bounded by constraint rules — hard data-validity checks (a reconstruction cost can't exceed 150% of the assessed value; a roof can't be older than the building) so a bad edit is flagged at the field and can never flow silently into rating.
| Prefill field | Best source(s) | Lands in (provision / rule) | How it drives the product |
|---|---|---|---|
| replacement_cost | 360Value / RCT | PRV-COVA-LS (Coverage A) | Defaults the Coverage A limit; estimate version pinned to the quote so the basis is reproducible at claim time. |
| roof_condition + roof_age | Cape Analytics, assessor | PRV-COVA-LS options OPT-RC / OPT-ACV | Poor/old roof ⇒ the Replacement Cost option is withheld for the roof (ACV-roof endorsement becomes the only selectable option) + condition surcharge. |
| construction class | Cotality / assessor | base rate factor; masonry credit option | Frame vs masonry shifts the fire base rate; masonry unlocks a credit option. |
| year_built | assessor | eligibility rule + system-update questions | Pre-1960 ⇒ refer (R-AGE rule); triggers plumbing/electrical/roof update questions whose answers unlock options. |
| sq ft · stories · quality grade | ATTOM / Cotality | inputs to replacement cost | Feed Tier-5 valuation; also sanity-check customer-entered Coverage A changes. |
| PPC + hydrant/station distance | Verisk ISO LOCATION (ProMetrix for commercial) | filed base-rate factor; eligibility | PPC 1–10 maps directly to a filed rate table (real PPC includes split classes like 4/4X and 10W — stored as the effective dwelling-level class); PPC 10 (no protection) can be a decline rule in wildfire zones. |
| fire zone + wildfire score | CAL FIRE FHSZ in CA; state wildfire maps / USFS elsewhere; cat-model (challenged by FireLine/Z-FIRE) | wildfire surcharge; mitigation credit options; clean-underwriting gate in the R2 rating method | Very High ⇒ surcharge + defensible-space mitigation credit options become available (in CA, recognition is mandated under the Safer-from-Wildfires regulation, Cal. Code Regs. §2644.9); score past threshold ⇒ refer to underwriter. The provision rules key off the normalized fire_zone field, whatever the per-state source. |
| vegetation overhang / defensible space | Cape Analytics | mitigation credit eligibility | Verified clearance ⇒ credit option selectable without an inspection visit — imagery pays for itself here. |
| flood_zone | FEMA NFIP | PRV-WB framing + companion-product offer | Flood is excluded from the homeowner form — zone AE/VE (the high-risk river and coastal-wave flood zones) triggers the "water backup ≠ flood" explainer + NFIP companion offer instead of silently leaving a gap. |
| prior losses | C.L.U.E. / A-PLUS | loss-frequency rating; PRV-WB default; referral rule | 2+ water losses ⇒ Water Backup default drops to the $5k option + referral; any adverse use of this data follows the adverse-action notice path. |
| occupancy / vacancy signal | LexisNexis identity tier | eligibility rule | Vacant dwelling ⇒ different product (vacant-dwelling form), not a declined homeowner quote. |
| pool / trampoline detected | Cape Analytics | liability provision questions | Detected-but-undeclared attractive nuisance ⇒ targeted question, fence/net option requirements. |
We're not buying data only to fill a form. The append-only payload store is deliberately shaped to feed the AI layer — with the same governance boundary the platform already enforces (propose-only, audit-logged).
| AI use | What feeds it | The mechanics |
|---|---|---|
| RAG over comparable properties | prefill_payload → governed rag_document derivatives | A redaction job turns raw payloads into governed property narratives ("1978 frame, comp-shingle fair, FHSZ Very High, PPC 4…"), embedded into pgvector. At underwriting, the agent retrieves similar past properties + their decisions and claim outcomes as cited precedent. Vendor-derived text is untrusted corpus input — it passes the same sanitization / prompt-injection screening as any external content before entering a prompt. |
| Conflict-resolution agent | field_provenance | When sources disagree (assessor says 1978, ATTOM says 1985), the agent proposes a resolution with citations to both payloads instead of a human eyeballing two PDFs; the choice is appended to decision_log. |
| Cost-aware call orchestration | Tier table (§2) + live gap list | "Is a $2 Cape call worth it for THIS risk?" — on the 800 ms hot path this is a compiled rule policy (fire zone × cat-score × gaps), never a live LLM hop. The agent's job is offline: it mines skip/call decisions vs eventual underwriting outcomes and proposes tuning to the escalation policy; every change is a new policy version in decision_log — so the cost policy itself is auditable. |
| LLM context discipline | governed derivatives only | Raw FCRA reports never enter a prompt. Only the redacted, governed derivative does — same rule as the underwriting KB. Field citations (source + fetched_at) ride along so the model's output can cite provenance, and bias monitoring applies to any use that touches protected-class proxies. |
| Continuous data-quality eval | claims-time ground truth | Every claim adjusts reality against what prefill believed (roof actually 22 yrs, not 12). That diff feeds a per-vendor accuracy score — the §2 bake-off becomes a standing eval, not a one-time procurement exercise. |
Prefill is a synchronous read service on the quote path plus an async refresh loop —
the same canonical mechanics as everywhere else: sync reads are request/response; anything cross-flow goes
outbox → event bus → push-subscription, deduped on
event_id.
1842 Skyline Dr at intake; the BFF makes a sync POST /prefill (purpose quote_intake, 800 ms budget) to Groundwork, the prefill service on Cloud Run.property_id = APN+unit, so "Dr" vs "Drive" can never split the cache. Then Tier 0: Redis, then property_profile. Fresh-per-§4 fields are served at $0 — cost_cents_incurred: 0; a per-address singleflight lock stops concurrent quotes from double-buying.prefill_payload (vendor, api_version, cost_cents); the merge rebuilds property_profile and writes one field_provenance row per field.source + confidence + fetched_at, plus a gaps list — intake renders "confirm these, answer these" instead of a blank form, and each confirmed field flips customer_confirmed.formal_quote, the FCRA tier runs (C.L.U.E.) under permissible purpose; a material conflict with the customer's answers opens an ops_task — never a silent overwrite.submission row with the confirmed values + provenance snapshot, plus its outbox row for QuoteRequested — prefill's job on the hot path is done.RefreshPropertyData on the FIFO work queue (grouped by property_id); the worker re-pulls imagery, the roof grade drops, and the same transaction's outbox row publishes PropertyDataRefreshed — Underwriting's subscription re-scores the renewal. No one called anyone directly.| Direction | Contract | Who |
|---|---|---|
| Serves (sync) | POST /prefill {address, purpose} → fields + provenance + gaps | Customer intake, Underwriting (renewal), Claims (FNOL context) |
| Calls (sync, tiered) | vendor APIs per §1–2 waterfall | Regrid, Cotality/ATTOM, Verisk, Cape, LexisNexis (all black boxes) |
| Emits | PropertyDataRefreshed {property_id, changed_fields} | Underwriting (renewal re-score), Pricing |
| Consumes | cat-event polygons, FEMA LOMR feed, deed-change signals → refresh triggers | Cat-model, public feeds |