NFIP Flood Loss Risk Screener — Property Loss History Score avatar

NFIP Flood Loss Risk Screener — Property Loss History Score

Pricing

from $4.40 / 1,000 results

Go to Apify Store
NFIP Flood Loss Risk Screener — Property Loss History Score

NFIP Flood Loss Risk Screener — Property Loss History Score

Flood loss history by property from FEMA NFIP paid claims: count, total paid, repetitive-loss flag, recency and a 0-100 flood-loss score within a radius of each lat/lon.

Pricing

from $4.40 / 1,000 results

Rating

0.0

(0)

Developer

Kyle Maloney

Kyle Maloney

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Turn a list of property coordinates into a flood loss history score built from FEMA National Flood Insurance Program (NFIP) paid claims. For each property (lat/lon) the actor summarizes past NFIP flood-insurance losses within a radius: claim count, total dollars paid, median and largest payout, repetitive-loss and severe-repetitive-loss signals, the most recent loss year and date, the dominant cause of damage, the dominant rated flood zone, the dominant named flood event, water depths, pre-FIRM exposure, Increased Cost of Compliance dollars, and a composite 0–100 flood-loss score.

Most tools republish the raw FEMA NFIP claims dump by state and year. This actor does the transform buyers actually want: asset-level loss history — "how much flood-insurance money has been paid out near THIS address, how often, how badly, how recently, and in what flood zone."

What changed in 1.2 (2026-08-04) — three defects that billed for wrong answers

1. The default radius is now 5 miles, and the input schema no longer carries a default

FEMA censors every claim to its census-tract centroid and rounds the coordinates to 0.1 degrees, so claim locations form a sparse lattice roughly 6.9 miles apart. Measured live 2026-08-04: 6,000 sampled claims across LA/TX/FL/NJ/MO/CA contained zero off-lattice coordinates, and a 0.2 x 0.2 degree window around New Orleans held exactly 3 distinct latitudes and 3 distinct longitudes.

1.1 shipped radiusMiles with "default": 1. An Apify input-schema default is injected server-side into every run, so it silently ANDed itself into every query from any caller who did not set the field. Reproduced live at 29.9276, -90.1053 (1234 Napoleon Ave, New Orleans), sinceYear: 2000:

radius1.1 publishedtruth (1.2)
1 mi0 claims, $0 — a billable "no flood loss history" in the most flood-claimed city in the US0 lattice nodes in range; verified_negative: null, radius_below_source_resolution: true, nearest published loss location 1.93 mi away
2 mi1,829 claims / $32,700,25523,233 claims
5 mi638 claims / $5,478,371less than at 2 mi23,233 claims

The four query-predicate inputs (radiusMiles, sinceYear, maxClaimsPerAsset, maxResults) now carry prefill only, never default. Defaults are applied in code, are documented here, and are covered by the offline suite.

Why 5? The worst-case distance from an arbitrary point to the nearest lattice node is half the lattice diagonal — 4.57 mi at New Orleans, up to 4.66 mi anywhere in the lower 48. A radius of 5 guarantees at least one lattice node is reachable, which is what makes a zero result meaningful.

2. Aggregates are now exact or null — never a sample

1.1 queried a padded square bounding box, capped the scan at maxClaimsPerAsset, and distance-filtered whatever came back in arbitrary server order. Because the box grows with the radius, a larger radius scanned a smaller fraction of it, so the answer moved down as you asked for more area (the 638-vs-1,829 row above). total_paid_usd was not a lower bound; it was a random sample.

1.2 enumerates the lattice nodes inside the circle and queries those exact coordinates. A node is a point, so it is wholly inside or wholly outside — there is no arbitrary subset, and a larger radius can only add nodes. That makes the answer exact and monotonic, and far cheaper: the 5-mile New Orleans query went from 158,734 candidate rows to one node.

The exact in-radius total is read from the source's own row count before any rows are fetched. If it exceeds maxClaimsPerAsset, every aggregate — claim_count, total_paid_usd, avg_payout_usd, median_payout_usd, max_single_payout_usd, repetitive_loss_flag, flood_loss_score and the rest — is null, aggregate_status is not_measured_truncated, and claims_in_radius_total carries the exact count so you still know the size of the exposure. Raise maxClaimsPerAsset (up to 50,000) for an exact answer.

3. The retry budget was 17 seconds; it is now 3.5 minutes

1.1 retried 3 times with a 1,200 ms backoff across four probe combinations. In the run that flagged this actor Under maintenance, the probe started at 01:43:37.98 and had given up by 01:43:55.24 — 17.3 seconds against Apify's 5-minute allowance. OpenFEMA flaps: two scheduled checks failed on consecutive days while manual runs minutes later succeeded on an identical input and build.

1.2 uses a wall-clock deadline of 3.5 minutes with exponential backoff plus full jitter, honours Retry-After, aborts any single request after 30 s so one hung socket cannot eat the budget, and classifies failures: 429, 5xx, the OpenFEMA HTML outage page, empty bodies, timeouts and network errors retry; 4xx other than 429 is terminal and stops immediately, because a malformed filter is our bug and retrying it four times is exactly how 1.1 burned its budget. The expected happy path gets 60% of the deadline, and one healthy endpoint is enough to answer — the fallbacks are not probed just to prove they are also down.

This does not weaken the fail-loudly contract. If OpenFEMA is down for the whole budget, the run still fails, emits nothing and bills nothing.

Also in 1.2

  • Two live lattice assertions, run before any billable row and again per asset. (a) Every coordinate returned must sit exactly on the 0.1-degree lattice. (b) A padded bounding-box count must equal the union count over the lattice nodes inside that same box — verified live at four metros (New Orleans 244,785 = 244,785; Houston 123,086; New York 55,337; Minneapolis 756). If FEMA ever changes its rounding, both break and the run fails rather than silently under-counting.
  • 9 new fields, all append-only. Nothing was removed or renamed.
  • A new prefill built from three real geocoded addresses (see below).
  • Assets are screened with bounded concurrency, so a realistic portfolio finishes well inside the auto-QA window.

What changed in 1.1 (2026-08)

  • Moved to the current dataset. 1.0 queried OpenFEMA v2/FimaNfipClaims, which FEMA has deprecated (removal 2026-10-15) and whose data has been frozen since 2026-06-01. 1.1 queries v3/NfipClaims and keeps v2 only as a fallback. Every row now carries dataset_version and data_as_of.
  • A live drift probe runs before any billable row. The endpoint must resolve, FEMA must echo the bounding-box $filter back intact, a positive canary must return claims, a negative control must return exactly zero, required fields must be present, and the extract must not be stale. Any failure fails the run and bills nothing.
  • An asset that could not be screened no longer publishes 0 claims and $0 paid. In 1.0 an upstream outage produced a billable row reading claim_count: 0, total_paid_usd: 0, repetitive_loss_flag: false — a confident "$0 in flood claims" answer that was never measured. Those fields are now null, and nfip_claims_status says why.
  • Silent truncation is now visible. A dense grid point can hold tens of thousands of claims; maxClaimsPerAsset stops the scan. 1.0 logged that and emitted the aggregate anyway. 1.1 publishes claims_scanned, claims_in_bbox_total, scan_truncated and data_completeness, and verified_negative can only be true on a complete scan.
  • 41 new fields from data the actor was already entitled to fetch.

Who it's for

  • P&C insurers & reinsurers — pre-bind flood exposure, repetitive-loss and severe-repetitive-loss screening, SFHA-vs-non-SFHA loss mix.
  • Mortgage lenders & CRE due diligence — flood-loss history alongside Phase I and property condition.
  • Real estate & appraisal — quantify neighborhood flood-loss burden and pre-FIRM exposure.
  • Risk / cat modeling teams — a keyless historical-loss density signal by point.

Example input

{
"assets": [
{ "lat": 40.5716, "lon": -74.6107, "label": "100 N Bridge St, Somerville, NJ (Raritan River)", "state": "NJ" },
{ "lat": 33.9848, "lon": -118.455, "label": "4200 Marina City Dr, Marina del Rey, CA", "state": "CA" },
{ "lat": 40.7359, "lon": -106.2821, "label": "100 W Main St, Walden, CO (clean control)", "state": "CO" }
],
"radiusMiles": 5,
"sinceYear": 2000,
"maxClaimsPerAsset": 5000,
"maxResults": 500
}

Output fields (one row per asset)

Identity & scope

FieldMeaning
asset_labelCaller-supplied label for the property
asset_latLatitude of the screened property
asset_lonLongitude of the screened property
stateOptional 2-letter state supplied with the asset (metadata only)
radius_milesRadius used for the aggregation
since_yearThe sinceYear filter actually applied

Did anyone actually check? (read these before the numbers)

FieldMeaning
nfip_claims_statusok, unavailable, or invalid_input. Anything but ok means the loss figures were not measured
nfip_claims_errorNull on success; the upstream failure message otherwise
data_completenesscomplete / truncated_by_cap / unverified / not_checked. Only complete carries measured aggregates
verified_negativetrue only when the source answered, the scan was complete, and the radius reached the source lattice. null means nobody could prove a negative — it is not a clean property
claims_scannedClaim records actually fetched and aggregated. Null when the scan was not affordable
claims_in_bbox_totalFEMA's own total for the padded bounding box the lattice check was run against (a superset of the radius)
scan_truncatedTrue when the exact in-radius total exceeded maxClaimsPerAsset, so every aggregate is null
dataset_versionv3 (current) or v2 (deprecated, frozen)
dataset_entityThe OpenFEMA entity queried
dataset_deprecatedTrue when FEMA flags the answering dataset as deprecated
dataset_deprecation_dateFEMA-published removal date, else null
data_as_ofThe asOfDate vintage of the NFIP extract behind this answer

Loss history

FieldMeaning
claim_countNFIP paid claims within the radius (on/after sinceYear)
total_paid_usdSum of building + contents + ICC payments
avg_payout_usdTotal paid divided by claim count
median_payout_usdMedian single-claim payout (mean-skew resistant)
max_single_payout_usdLargest single-claim total payout
total_icc_paid_usdIncreased Cost of Compliance dollars — only paid on substantial-damage / repetitive-loss determinations
total_building_damage_usdReported gross building damage (not the payout)
total_contents_damage_usdReported gross contents damage
claims_with_unknown_payoutClaims where FEMA published no payment figure at all
repetitive_loss_flagTrue when ≥2 claims fall within the radius
severe_repetitive_loss_signalTrue when ≥4 claims fall within the radius (editorial, not FEMA's formal SRL designation)
most_recent_loss_yearYear of the most recent nearby loss
most_recent_loss_dateExact date of the most recent nearby loss
oldest_loss_yearYear of the oldest in-scope nearby loss
distinct_loss_yearsHow many separate years produced a claim
claims_last_10_yearsClaims with a loss year in the last 10 calendar years
flood_loss_scoreEditorial 0–100 composite (count + total paid + recency)

Hazard character

FieldMeaning
dominant_causeMost frequent NFIP cause of damage (human-readable)
dominant_rated_flood_zoneMost common rated flood zone (AE, VE, X, A07 …)
dominant_flood_zone_classPlain-English regulatory class of that zone
sfha_claim_share_pctShare of claims rated inside a Special Flood Hazard Area
dominant_flood_eventMost frequent named FEMA flood event
distinct_flood_eventsHow many separate named events produced claims
max_water_depth_ftDeepest reported flood water depth
median_water_depth_ftMedian reported flood water depth

Building stock

FieldMeaning
dominant_occupancyMost common occupancy type, decoded
claims_primary_residenceClaims flagged as a primary residence
claims_elevated_buildingClaims on elevated buildings
claims_pre_firmClaims on pre-FIRM construction (highest-risk segment)
claims_post_firmClaims on post-FIRM construction
nfip_community_nameMost common NFIP participating community

Nearest claim & diagnostics

FieldMeaning
nearest_claim_distance_milesDistance to the closest in-radius claim centroid
nearest_claim_yearLoss year of that closest claim
nearest_claim_paid_usdPayout on that closest claim
nearest_claim_rated_flood_zoneRated flood zone of that closest claim
unknown_cause_codesCause codes FEMA published that this actor cannot label
unknown_occupancy_codesOccupancy codes FEMA published that this actor cannot label
errorNull on success; a message when the asset could not be screened
disclaimerUsage disclaimer
source_urlThe OpenFEMA endpoint that answered
checked_atISO timestamp of the run

Grid-node query model (1.2)

FieldMeaning
spatial_query_modeHow nearby claims were located. grid_node_union = the actor enumerated the 0.1-degree lattice nodes inside the radius and queried those exact coordinates
aggregate_statusexact = every figure on this row was computed over ALL in-radius claims. not_measured_truncated = the exact total exceeded maxClaimsPerAsset, so every aggregate is null (never a sample). not_measured_unverified = the source returned no total, so completeness could not be proven. not_checked = the asset was never screened
grid_nodes_in_radiusHow many FEMA lattice nodes fall inside the radius. 0 means FEMA publishes no loss location close enough to answer
grid_node_coordinatesThe exact censored coordinates queried, nearest first, as "lat,lon" strings — precisely where FEMA says the nearby losses occurred
claims_in_radius_totalExact count of NFIP claims on the in-radius lattice nodes, from the source's own row count. Populated even when the scan was too large to aggregate
nearest_grid_node_distance_milesDistance to the nearest lattice node, in or out of the radius — the closest any NFIP claim can possibly be reported to this address
source_grid_resolution_milesWorst-case distance from this latitude to the nearest lattice node (half the lattice diagonal). A radius below this cannot produce a verified negative
radius_below_source_resolutionTrue when the radius is smaller than source_grid_resolution_miles. A zero at such a radius is not a clean property, so verified_negative is null
source_grid_verifiedTrue when the live lattice-equivalence check passed on this run, proving node enumeration is exhaustive. Null = the check did not run

What verified_negative does and does not mean

verified_negative: true means all three of these held:

  1. FEMA answered and passed every live drift and lattice assertion;
  2. the scan was complete — the exact in-radius total was measured and every one of those claims was fetched and aggregated;
  3. the radius was at or above source_grid_resolution_miles, so at least one lattice node was guaranteed to be reachable.

verified_negative: null means nobody checked, or the check could not prove a negative. It is not a clean property. Read nfip_claims_status, aggregate_status and radius_below_source_resolution to see which.

Even a true is a statement about FEMA's censored, tract-centroid data within the radius — it is not a flood-zone determination, an Elevation Certificate, or a statement that the parcel has never flooded. Uninsured losses and losses under non-NFIP policies are not in this dataset at all.

What a truncated / null aggregate means

When aggregate_status is not_measured_truncated, the actor knows exactly how many claims are in the radius (claims_in_radius_total) but could not afford to fetch and aggregate them under maxClaimsPerAsset. Every derived figure is null — deliberately. A partial sum over an arbitrary slice is not a lower bound and not conservative; in 1.1 it moved down as the radius grew. Raise maxClaimsPerAsset (maximum 50,000) or reduce the radius, and re-run.

Important: how FEMA locates claims (read this)

FEMA censors each loss to its census-tract centroid and rounds latitude/ longitude to 0.1 degrees. Claim locations are therefore a sparse lattice about 6.9 miles apart, not exact addresses. Verified live 2026-08-04 across 6,000 sampled claims in six states: zero off-lattice coordinates.

Consequences:

  • The actor queries the lattice nodes inside your radius by exact coordinate, which is why the in-radius answer is exact and grows monotonically with the radius. grid_node_coordinates shows you which nodes answered.
  • A radius below source_grid_resolution_miles (up to 4.66 mi in the lower 48) can miss every node. Keep radiusMiles at 5 or above for real addresses; the default is 5.
  • Metrics describe a tract-level neighborhood, not one parcel.
  • FEMA also publishes some claims with no coordinates at all (1 to 44 per 1,000 rows depending on the state). Those cannot be matched by any spatial query, by any method.
  • flood_loss_score is an editorial 0-100 composite (log-scaled claim count up to 40, log-scaled total paid up to 40, recency up to 20) - not a FEMA rating, flood-zone determination, or actuarial premium. It is null whenever the aggregate behind it was not exactly measured.

Inputs that populate the optional columns

Every value below was measured live on 2026-08-04 at radiusMiles: 5, sinceYear: 2000.

  • A real loss history (total_paid_usd, median_payout_usd, dominant_flood_event, max_water_depth_ft, claims_pre_firm, total_icc_paid_usd): {"lat": 40.5716, "lon": -74.6107} (100 N Bridge St, Somerville NJ) - 1,717 claims, $90,888,480 paid, 2 lattice nodes.
  • A moderate coastal history: {"lat": 33.9848, "lon": -118.455} (Marina del Rey CA) - 138 claims, $1,562,047.
  • verified_negative: true: {"lat": 40.7359, "lon": -106.2821} (100 W Main St, Walden CO) - 0 claims, complete scan, 3 lattice nodes actually queried.
  • radius_below_source_resolution: true and verified_negative: null: any real address at radiusMiles: 1 - e.g. {"lat": 29.9276, "lon": -90.1053} (1234 Napoleon Ave, New Orleans), whose nearest published loss location is 1.93 mi away.
  • aggregate_status: "not_measured_truncated", claims_in_radius_total, and null aggregates: {"lat": 29.9276, "lon": -90.1053} at radiusMiles: 5 with maxClaimsPerAsset: 100 - the exact in-radius total is 23,233.
  • dataset_deprecated: true: only when v3 is unavailable and the run falls back to the deprecated v2 endpoint.

Use as an MCP tool

This actor is a clean, chainable tool for AI agents via mcp.apify.com: pass one or more {lat, lon, label} assets and get back a structured, field-described flood-loss history row per property — ideal for underwriting copilots and property-risk agents. Agents should read nfip_claims_status and data_completeness before trusting any figure, and must treat verified_negative: null as "unknown", never as "clean".

Pricing

Pay-per-result: one billable Result per asset row, unchanged in 1.2. Rows are buffered and the billing gate runs before anything is pushed — if every asset failed to screen, the run fails and nothing is billed. A truncated row is still one Result, and it still tells you the exact in-radius total.

FAQ

Where does the data come from? FEMA OpenFEMA v3/NfipClaims (the NFIP Redacted Claims v3 release). Keyless, public, historical. The older v2/FimaNfipClaims is kept only as a fallback until FEMA removes it on 2026-10-15.

Is this a FEMA flood zone / FIRM lookup? No. It measures historical paid losses near a point, and reports the flood zones those historical claims were rated in — not the current regulatory flood zone of your parcel. Pair it with a FIRM/flood-zone determination.

Why did my run fail instead of returning zero rows? Because a zero that was never measured is worse than a failure. If FEMA is unreachable, or its response fails the live drift check, or every asset errored, the run fails loudly and bills nothing.

Why is claim_count sometimes null? Dense flood metros can hold tens of thousands of claims at one lattice node — a single node in New Orleans holds 23,233 since 2000. When the exact in-radius total exceeds maxClaimsPerAsset, every aggregate is null rather than a partial sum, because a partial sum over an arbitrary slice is not a lower bound (in 1.1 it fell as the radius grew). claims_in_radius_total still gives you the exact size of the exposure. Raise maxClaimsPerAsset (max 50,000) or reduce the radius for an exact aggregate.

Nothing came back for my address. Check radius_below_source_resolution first: FEMA's lattice is ~6.9 miles apart, so a radius under about 4.7 miles can miss every published loss location. nearest_grid_node_distance_miles tells you how far the nearest one is. Then widen sinceYear. Only verified_negative: true means genuinely clear.

Why did the answer change between 1.1 and 1.2? Because 1.1 was wrong. It scanned a padded square box, capped it, and aggregated whatever the server happened to return first — so a 5-mile query could report less money than a 2-mile one at the same address. 1.2 queries the censored coordinates directly and either returns an exact aggregate or none at all. No field was removed or renamed; existing values changed only where the old value was not measurable.

  • FEMA NRI County Risk Profile — forward-looking modeled risk to pair with this backward-looking loss history.
  • EPA Contaminated Site Screener and Site Due Diligence Bundle — the rest of a Phase I / CRE diligence stack on the same coordinates.

Each is a screening tool, not a determination.