# FEMA NFIP Repetitive Loss & Flood Insurance Market Screener (`malonestar/fema-repetitive-loss-flood-market-screener`) Actor

Resolve any US coordinate to its NFIP community, then return that community's repetitive-loss and severe-repetitive-loss property rollup, CRS class and premium discounts, NFIP participation status, and county flood-insurance market penetration. Four FEMA OpenFEMA datasets joined in one call.

- **URL**: https://apify.com/malonestar/fema-repetitive-loss-flood-market-screener.md
- **Developed by:** [Kyle Maloney](https://apify.com/malonestar) (community)
- **Categories:** Real estate, Developer tools, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## FEMA NFIP Repetitive Loss & Flood Insurance Market Screener

Give it a US coordinate. It resolves that point to the **NFIP community** whose
published FEMA boundary contains it, then returns that community's repetitive-loss
property profile, its Community Rating System class and premium discounts, its NFIP
participation status, and the county's flood-insurance market penetration - four FEMA
OpenFEMA datasets joined in one call.

Nobody publishes these four together. FEMA's repetitive-loss list was historically
FOIA-restricted; it went public as an API in February 2024, the community boundary
layer in February 2024, and the county penetration rates in November 2024.

### Why there is no radius search, and why that is the honest answer

The obvious build is "repetitive-loss properties within N miles". **That product cannot
be built from this data, and anyone selling it is selling a fabricated number.**

FEMA redacts the coordinates. Its own data dictionary says so:

> "Approximate latitude of the structure **redacted to 1 decimal place**. The precision
> has been lessened to ensure individual privacy. This redaction as well as the inherent
> error in geocoding addresses **may result in a point location that exists in an
> incorrect community, county or state**."

Measured on the live file 2026-08-19: of Colorado's 113 records, 84 carry one decimal
place, **23 carry zero decimal places**, and 6 have no coordinate at all. On a 4,000-row
Louisiana page it is 2,909 / 1,068 / 23. Zero decimals of latitude is roughly +/- 55 km.

So this actor answers at the scope the data actually supports: **point -> NFIP community
-> community and county rollup**. Every row carries `multiple_loss_coordinates_redacted`,
`radius_screening_supported: false`, and the decimal precision measured on that run.

### Who it is for

- **Phase I ESA and environmental due-diligence firms** adding a flood-loss and
  flood-insurance-market section to a site report.
- **Commercial real-estate acquisition and underwriting teams** screening a portfolio
  for communities with concentrated repetitive-loss exposure and thin insurance take-up.
- **P\&C and flood underwriters / MGAs** pricing against the CRS discount schedule and
  the county SFHA penetration rate.
- **Floodplain managers and mitigation consultants** benchmarking their community's
  repetitive-loss count, mitigation rate and CRS class against the county.

### Example input

```json
{
  "assets": [
    { "lat": 39.7392, "lon": -104.9903, "label": "Denver City Hall, CO" },
    { "lat": 39.7047, "lon": -105.0814, "label": "Lakewood, CO (city inside Jefferson County)" },
    { "lat": 29.9511, "lon": -90.0715, "label": "New Orleans, LA" }
  ],
  "includeCountyCommunity": true,
  "includeTribalEtjLayer": true,
  "includeLossProperties": false
}
```

### What comes back

Three row types, distinguished by `record_type`:

| `record_type` | One per | What it carries |
| --- | --- | --- |
| `asset_summary` | site you supplied | The governing NFIP community, how many communities contain the point, boundary-read diagnostics, and the worst screen level across them. |
| `community_profile` | NFIP community containing the site | The full profile: Status Book, CRS, repetitive-loss rollup, county penetration, screen verdict. |
| `loss_property` | repetitive-loss property (opt-in) | Designation, flood zone, occupancy, loss count, insured and mitigated status, and the redacted coordinate with its measured precision. |

A site inside an incorporated place usually returns **two** communities: the municipality
(which governs, because FEMA defines a community as "the lowest level of government with
land use authority") and the county community covering unincorporated areas. Both are
emitted, with `is_governing_community` and `governing_community_basis` saying which is
which and why. Measured example: Lakewood CO resolves to **CID 085075 (Lakewood, City of)**
as the governing community and **CID 080087 (Jefferson County \*)** as the broader one -
two different CRS classes and two different loss rollups.

### What this actor refuses to do

- It will not publish a distance to a repetitive-loss property. See above.
- It will not report "not participating in the NFIP" for a community whose Status Book
  record it never read. Unchecked is `null`; checked-and-negative is `false`.
- It will not derive a CRS premium discount from the class rating. FEMA's own file
  contradicts the textbook rule: Colorado carries class-10 communities published with a
  10% and a 15% SFHA discount alongside class-10 communities with none. Discounts are
  transcribed verbatim, with the raw FEMA text beside the parsed number.
- It will not recompute or clamp a penetration rate. FEMA publishes 593 counties with
  zero SFHA residential structures alongside a non-zero SFHA policy count, and 27
  counties with an SFHA penetration rate above 100%. Those figures ship as published,
  with `penetration_data_quality_flags` naming the inconsistency.
- It will not coerce a corrupted census block group. On a live Louisiana page **96.1% of
  block groups arrive as Excel scientific notation** ("2.2055E+11") and have irrecoverably
  lost seven of twelve GEOID digits. Those are emitted as `null` with an explicit reason.
- It will not produce a screen level while any contributing FEMA dataset was unavailable.
  It reads `INCONCLUSIVE` instead.
- If it cannot answer at all, it **fails the run and bills nothing**.

### Live drift gate

Nine probes run before a single billable row is produced, each with its own error
boundary and a three-valued outcome (`pass` / `fail` / `unavailable`):

| Probe | Role | What it proves |
| --- | --- | --- |
| `catalog` | load-bearing | All four datasets are still listed and API-enabled in FEMA's own catalog - and FEMA's own `depDate` field is read, so an announced end-of-life is surfaced on every row before it becomes a 404. |
| `schema` | load-bearing | Every column this actor reads is still published, so a rename fails loudly instead of becoming a column of nulls. |
| `community_layer_canary` | load-bearing | Denver City Hall still resolves to NFIP Community 080046. Point-to-community resolution is the whole product. |
| `multiple_loss_canary` | load-bearing | The national row count is in band, a community filter strictly narrows it, and every returned row really is that community. |
| `status_book_canary` | load-bearing | Denver still reads participating, CRS class 6. |
| `penetration_canary` | load-bearing | Denver County still reports residential contracts in force in band. |
| `coordinate_redaction` | corroborating | The redaction that makes radius screening impossible is re-measured every run rather than assumed. |
| `negative_control` | corroborating | A state code that does not exist returns zero rows. |
| `filter_rejects_unknown_column` | corroborating | OpenFEMA still rejects a filter on a non-existent column instead of silently returning the national table. |

A **load-bearing** probe that cannot complete fails the run. A **corroborating** probe
that cannot complete lets the run proceed and says so (`drift_gate_status:
verified_degraded`). A probe that completes and measures wrong always fails the run.

### Use as an MCP tool

This actor is callable by AI agents over Apify's MCP server.

```json
{
  "mcpServers": {
    "apify": {
      "command": "npx",
      "args": ["-y", "@apify/actors-mcp-server", "--actors", "malonestar/fema-repetitive-loss-flood-market-screener"],
      "env": { "APIFY_TOKEN": "<your Apify token>" }
    }
  }
}
```

Worked agent prompt:

> For 1600 Broadway, Denver CO and 900 Camp St, New Orleans LA, tell me which NFIP
> community each sits in, how many repetitive-loss properties that community has, what
> its CRS class and SFHA premium discount are, and what share of the county's SFHA
> homes carry flood insurance.

Billing is unchanged when called as a tool, and a run that cannot answer fails without
billing.

### Sources

| Dataset | Endpoint | Records |
| --- | --- | --- |
| NFIP Multiple Loss Properties | `fema.gov/api/open/v1/NfipMultipleLossProperties` | 240,651 |
| NFIP Community Layer (Comprehensive) | `fema.gov/api/open/v1/NfipCommunityLayerComprehensive` | 51,943 polygons |
| NFIP Community Status Book | `fema.gov/api/open/v1/NfipCommunityStatusBook` | 32,436 |
| NFIP Residential Penetration Rates | `fema.gov/api/open/v1/NfipResidentialPenetrationRates` | 3,159 counties |
| County resolution | FCC Census Block API, with Census TIGERweb as fallback | - |

All keyless. Counts measured 2026-08-19.

### Output fields (196 declared)

#### Every row: site, sources and provenance

| Field | Type | Description |
| --- | --- | --- |
| `record_type` | string | Row type: asset\_summary (one per site), community\_profile (one per NFIP community containing the site), or loss\_property (one per repetitive-loss property, only when that option is on). |
| `asset_label` | string | The label you supplied for this site. |
| `asset_latitude` | number | The latitude you supplied for this site. |
| `asset_longitude` | number | The longitude you supplied for this site. |
| `asset_state_fips` | string | Two-digit state FIPS code resolved from the site coordinate. |
| `asset_state_abbreviation` | string | Two-letter state abbreviation resolved from the site coordinate. Null when the fallback resolver answered, because it does not publish one. |
| `asset_county_fips` | string | Five-digit county FIPS code resolved from the site coordinate. This is the join key to the county residential penetration rates. |
| `asset_county_name` | string | County, parish or borough name resolved from the site coordinate. |
| `geo_resolver` | string | Which resolver answered: fcc\_census\_block\_api or census\_tigerweb. |
| `geo_status` | string | ok when the site was resolved to a county, unavailable when both resolvers failed. |
| `community_layer_status` | string | Per-source outcome for FEMA NfipCommunityLayerComprehensive: ok or unavailable. |
| `community_status_book_status` | string | Per-source outcome for the FEMA NFIP Community Status Book: ok, unavailable or not\_applicable. |
| `penetration_status` | string | Per-source outcome for FEMA NfipResidentialPenetrationRates: ok, unavailable or not\_applicable. |
| `multiple_loss_status` | string | Per-source outcome for FEMA NfipMultipleLossProperties: ok, partial, unavailable or not\_applicable. |
| `tribal_etj_layer_status` | string | Per-source outcome for the tribal / extraterritorial-jurisdiction boundary pass: ok, unavailable or not\_requested. |
| `sources_unavailable` | string | JSON array of the source status fields that were not ok on this row. Null when every source answered. |
| `all_sources_ok` | boolean | True only when every contributing FEMA dataset answered for this row. When false, no clean screen level is asserted. |
| `data_as_of_multiple_loss` | string | FEMA asOfDate for the multiple-loss property file, when published on the rows read. |
| `data_as_of_penetration` | string | FEMA asOfDate for the residential penetration rates. |
| `community_status_book_last_refresh` | string | FEMA lastRefresh timestamp on the Community Status Book record. |
| `community_layer_last_refresh` | string | FEMA lastRefresh timestamp for the community boundary layer, when published. |
| `multiple_loss_record_count_published` | number | National record count FEMA publishes for NfipMultipleLossProperties in its own dataset catalog. |
| `openfema_deprecation_notice` | string | JSON array of deprecation notices FEMA publishes for the datasets this actor reads, taken from the depDate and depNewURL fields on its own catalog endpoint. Null when none is announced. |
| `drift_gate_status` | string | verified when every drift probe passed, verified\_degraded when a corroborating probe could not complete and the run proceeded and disclosed it. A run whose gate failed emits no rows at all. |
| `drift_gate_probes_passed` | number | How many drift probes passed before any billable row was produced. |
| `drift_gate_probes_unavailable` | string | JSON array of drift probes that could not complete. Null when all completed. |
| `drift_gate_note` | string | Plain-language summary of the drift gate outcome. |
| `multiple_loss_coordinates_redacted` | boolean | Always true. FEMA redacts repetitive-loss property coordinates to one decimal place for privacy. |
| `radius_screening_supported` | boolean | Always false. The redacted coordinates cannot support a radius or nearest-property distance, so none is published. |
| `loss_property_coordinate_precision_note` | string | Why this product answers at community scope rather than by radius, with the measured coordinate precision behind that decision. |
| `retrieved_at` | string | UTC timestamp at which this run read FEMA. |

#### NFIP community identity and boundary

| Field | Type | Description |
| --- | --- | --- |
| `community_id_number` | string | FEMA NFIP Community ID Number (CID) of the community this row describes. |
| `community_name` | string | FEMA community name, verbatim. A trailing asterisk is FEMA notation for a community covering unincorporated areas only. |
| `community_layer_type` | string | FEMA layerTypeCode of the matched polygon: Place, Place (multi-county), County, County Subdivision, Consolidated City, Maine Town/Township, SLUA, TRIBE, ETJ or Statistical Area. |
| `community_jurisdiction_tier` | number | Jurisdiction rank used to choose the governing community: 1 municipal, 2 tribal, 3 extraterritorial, 4 county, 5 statistical, 6 unrecognised. |
| `community_jurisdiction_tier_label` | string | Human-readable label for the jurisdiction tier. |
| `is_governing_community` | boolean | True on the community with land-use authority over the site. Other matched communities are still emitted so the alternative is visible. |
| `governing_community_basis` | string | Why this community was chosen as the governing one, and how many broader communities also contain the site. |
| `governing_community_ambiguous` | boolean | True when two or more communities of equal jurisdictional rank contain the site. |
| `matched_community_count` | number | How many distinct NFIP communities contain this site. |
| `matched_community_ids` | string | JSON array of every NFIP Community ID containing this site. |
| `community_polygons_tested` | number | How many NFIP community polygons were read and tested against this site. |
| `community_polygons_unreadable` | number | How many polygons could not be parsed as GeoJSON. An unreadable boundary is recorded, never counted as a miss. |
| `statistical_area_hits` | number | How many containing polygons carry no Community ID and are therefore not NFIP communities. |
| `unrecognised_layer_types` | string | JSON array of layer types FEMA served that are outside its own documented vocabulary. |
| `tribal_etj_layer_checked` | boolean | True when the tribal and extraterritorial-jurisdiction boundary pass ran for this site. |
| `tribal_etj_layer_row_count` | number | How many tribal / extraterritorial polygons were read for this state. Null when the pass did not run. |
| `in_nfip_community` | boolean | True when at least one NFIP community boundary contains the site, false when the boundaries were read and none does, null when they could not be read. |
| `no_community_basis` | string | Why no NFIP community was matched, including how many polygons were tested. |
| `community_profile_rows_emitted` | number | How many community\_profile rows this site produced. |
| `community_name_short` | string | FEMA short community name with the suffix stripped. |
| `community_layer_types_matched` | string | JSON array of every layer type whose polygon carried this Community ID and contained the site. |
| `community_polygons_matched` | number | How many published polygons carrying this Community ID contain the site. |
| `community_layer_type_recognised` | boolean | False when FEMA served a layer type outside its own documented vocabulary. The row is still emitted, never dropped. |
| `community_unincorporated_areas_only` | boolean | True when FEMA marks the community name with a trailing asterisk, meaning it covers unincorporated areas only. |
| `community_state_code` | string | Two-digit state FIPS code on the community polygon. Null on tribal and extraterritorial polygons, which FEMA publishes without one. |
| `community_county_fips` | string | Five-digit county FIPS code on the community polygon. Null on tribal and extraterritorial polygons. |
| `community_county_name` | string | County name on the community polygon. |
| `community_census_geoid` | string | Census GEOID FEMA associates with the community polygon. |
| `community_census_year` | number | Census vintage FEMA used for the population and housing counts. |
| `community_census_population` | number | Census population of the entire community. |
| `community_census_housing_units` | number | Census housing units in the entire community. |
| `community_land_area_sq_km` | number | Land area of the entire community in square kilometres. |
| `community_cis_type` | string | FEMA Community Information System government-unit type. |
| `community_cis_source` | string | Source of the FEMA Community Information System data, typically PIVOT. |
| `community_geometry_source` | string | Where FEMA sourced the boundary: a Census layer, the NFHL, or another source. |
| `community_alternate_name` | string | Alternate non-census community name FEMA publishes. |
| `community_layer_creation_notes` | string | FEMA notes on how the boundary was constructed. |
| `community_census_class_code` | string | Census class code for the place or subdivision. |
| `community_census_functional_status_code` | string | Census functional status code. |

#### NFIP Community Status Book: participation, FIRM dates and CRS

| Field | Type | Description |
| --- | --- | --- |
| `community_status_book_matched` | boolean | True when a FEMA NFIP Community Status Book record exists for this Community ID. |
| `community_status_book_record_count` | number | How many Community Status Book records matched this Community ID. Anything but 1 means the join is ambiguous. |
| `participating_in_nfip` | boolean | True or false when checked against the Community Status Book, null when no record was read. Null is not a finding of non-participation. |
| `nfip_participation_basis` | string | Where the participation answer came from, or why it was not determined. |
| `tribal_community` | boolean | FEMA tribal indicator on the Community Status Book record. |
| `initial_flood_hazard_boundary_map_date` | string | Date of the first Flood Hazard Boundary Map, ISO. Null when the community never received one. |
| `initial_firm_date` | string | Date of the first Flood Insurance Rate Map, ISO. This is the pre-FIRM / post-FIRM dividing line. |
| `currently_effective_map_date_raw` | string | Verbatim FEMA value for the current effective map. FEMA declares this a date but serves MM/DD/YY strings, suffixed status tokens, and bare status tokens such as (NSFHA). |
| `currently_effective_map_date` | string | Current effective FIRM date in ISO form, with the two-digit year resolved. Null when FEMA published a status token instead of a date. |
| `currently_effective_map_status_code` | string | Status token FEMA appended to, or published instead of, the current effective map date: M, L, >, NSFHA, ALL ZONE D and similar. |
| `currently_effective_map_status_label` | string | What that status token means. |
| `currently_effective_map_unparsed_reason` | string | Why no ISO date could be produced, when none could. |
| `regular_emergency_program_date_raw` | string | Verbatim FEMA value for the date the community joined the NFIP, including any (E), (S) or (W) status token. |
| `regular_emergency_program_date` | string | Date the community joined the NFIP, ISO, with the two-digit year resolved. |
| `regular_emergency_program_status_code` | string | Status token on the programme date: E emergency programme, S suspended, W withdrawn. |
| `nfip_program_phase` | string | regular\_program, emergency\_program, suspended, withdrawn, or null when not determined. |
| `crs_participating` | boolean | True when FEMA publishes a Community Rating System class for this community, false when it publishes none, null when the Status Book was not read. |
| `crs_class_rating` | number | FEMA Community Rating System class, 1 (best) to 10. |
| `crs_class_rating_effective_date` | string | Date the CRS class took effect. |
| `crs_original_entry_date` | string | Date the community first entered the CRS. |
| `crs_sfha_discount_raw` | string | Verbatim FEMA text for the Special Flood Hazard Area premium discount, including its zero padding and percent sign. |
| `crs_sfha_discount_pct` | number | SFHA premium discount as a number of percent, parsed from the FEMA text. Never derived from the class rating. |
| `crs_nonsfha_discount_raw` | string | Verbatim FEMA text for the non-SFHA premium discount. |
| `crs_nonsfha_discount_pct` | number | Non-SFHA premium discount as a number of percent, parsed from the FEMA text. |
| `crs_discount_basis` | string | How the discounts were obtained, and why they are transcribed rather than derived from the class rating. |

#### Repetitive-loss rollup for the community

| Field | Type | Description |
| --- | --- | --- |
| `multiple_loss_properties_total` | number | Exact number of repetitive-loss and severe-repetitive-loss properties FEMA publishes for this community, read from the API row count rather than from the page returned. |
| `severe_repetitive_loss_count` | number | Properties carrying either severe-repetitive-loss designation. |
| `currently_insured_count` | number | Properties FEMA records as currently insured by the NFIP. |
| `mitigated_count` | number | Properties FEMA records as mitigated as of the file date. |
| `multiple_loss_properties_analysed` | number | How many of those properties this run actually read and rolled up. |
| `multiple_loss_rollup_complete` | boolean | True when every published property was read. |
| `multiple_loss_results_truncated` | boolean | True when the read stopped before every published property was retrieved. |
| `nfip_rl_count` | number | Properties carrying the NFIP insurance-related Repetitive Loss designation. |
| `nfip_srl_count` | number | Properties carrying the NFIP insurance-related Severe Repetitive Loss designation. |
| `fma_rl_count` | number | Properties carrying the Flood Mitigation Assistance grant-related Repetitive Loss designation. |
| `fma_srl_count` | number | Properties carrying the Flood Mitigation Assistance grant-related Severe Repetitive Loss designation. These four designations are independent flags, not a hierarchy. |
| `designation_none_count` | number | Properties in the file carrying none of the four designations. |
| `total_losses_sum` | number | Sum of paid NFIP claims over $1,000 since 1978 across the properties analysed. Null when no property published a count. |
| `total_losses_mean` | number | Mean paid-claim count per property. |
| `total_losses_max` | number | Highest paid-claim count on any single property. |
| `properties_with_4_or_more_losses` | number | Properties with four or more paid claims. |
| `currently_uninsured_count` | number | Properties FEMA records as not currently insured. |
| `insured_status_unknown_count` | number | Properties where FEMA published no insured indicator. |
| `currently_insured_share` | number | Currently insured properties as a share of those analysed. |
| `unmitigated_count` | number | Properties FEMA records as not mitigated. |
| `mitigated_status_unknown_count` | number | Properties where FEMA published no mitigation indicator. |
| `mitigated_share` | number | Mitigated properties as a share of those analysed. |
| `primary_residence_count` | number | Properties recorded as the insured party primary residence. |
| `post_firm_construction_count` | number | Properties built after the community first Flood Insurance Rate Map. |
| `pre_firm_construction_count` | number | Properties built before the community first Flood Insurance Rate Map. |
| `firm_era_unknown_count` | number | Properties where FEMA published no pre/post-FIRM indicator. |
| `residential_property_count` | number | Properties whose occupancy code is residential, decoded scheme-aware. |
| `non_residential_property_count` | number | Properties whose occupancy code is non-residential. |
| `unclassified_occupancy_count` | number | Properties whose occupancy code FEMA did not publish or does not document. |
| `occupancy_legacy_scheme_count` | number | Properties coded in the legacy 1-6 occupancy scheme. |
| `occupancy_modern_scheme_count` | number | Properties coded in the modern 11-19 occupancy scheme. Both schemes live in one FEMA column and mean different things. |
| `unrecognised_occupancy_codes` | string | JSON array of occupancy codes outside FEMA published vocabulary, surfaced rather than silently bucketed. |
| `sfha_zone_property_count` | number | Properties whose FEMA-rated flood zone is a Special Flood Hazard Area. |
| `non_sfha_zone_property_count` | number | Properties in zones B, C or X. |
| `undetermined_zone_property_count` | number | Properties in Zone D, an area of possible but undetermined flood hazard. Not a low-risk finding. |
| `unknown_zone_property_count` | number | Properties whose flood zone FEMA did not publish or does not document. |
| `unrecognised_flood_zones` | string | JSON array of flood zones outside FEMA published vocabulary. |
| `flood_zone_distribution` | string | JSON object counting the properties analysed by FEMA-rated flood zone. |
| `occupancy_type_distribution` | string | JSON object counting the properties analysed by FEMA occupancy code. |
| `most_recent_loss_date` | string | Most recent closed-claim loss date across the properties analysed. |
| `oldest_recorded_loss_date` | string | Oldest most-recent-loss date across the properties analysed. |
| `loss_property_zip_codes` | string | JSON array of the ten most common ZIP codes among the properties analysed. |
| `census_block_group_usable_count` | number | Properties whose census block group arrived as a usable 12-digit GEOID. |
| `census_block_group_scientific_notation_count` | number | Properties whose census block group arrived as Excel scientific notation and has irrecoverably lost digits. |
| `census_block_group_absent_count` | number | Properties where FEMA published no census block group. |
| `census_block_group_other_unusable_count` | number | Properties whose census block group was unusable for another reason. |
| `census_block_group_note` | string | Explanation when block groups in this community were unusable. Null when none were. |
| `loss_property_lat_decimals_max` | number | Highest number of decimal places seen on the redacted latitudes in this community, measured on this run. |
| `loss_property_lat_decimals_min` | number | Lowest number of decimal places seen on the redacted latitudes in this community. Zero decimals is roughly plus or minus 55 km. |
| `loss_property_no_coordinate_count` | number | Properties for which FEMA published no usable coordinate at all. |

#### County flood-insurance market penetration

| Field | Type | Description |
| --- | --- | --- |
| `penetration_matched` | boolean | True when FEMA publishes a residential penetration record for this county. |
| `penetration_record_count` | number | How many penetration records matched this county FIPS. |
| `penetration_county_fips` | string | County FIPS used for the penetration join. |
| `penetration_county_name` | string | County name on the FEMA penetration record. |
| `penetration_state_name` | string | State name on the FEMA penetration record. |
| `res_penetration_rate` | number | FEMA countywide residential flood-insurance penetration rate: policy contracts in force divided by residential structures. Published verbatim. |
| `res_penetration_rate_sfha` | number | FEMA residential penetration rate inside the Special Flood Hazard Area. Published verbatim and never recomputed, including where FEMA publishes a value above 1. |
| `res_contracts_in_force` | number | NFIP residential policy contracts in force countywide. |
| `res_contracts_in_force_sfha` | number | NFIP residential policy contracts in force inside the SFHA. |
| `total_res_structures` | number | Total residential structures in the county, from the 2022 National Structure Inventory. |
| `total_res_structures_sfha` | number | Total residential structures inside the county SFHA. FEMA publishes zero here for 593 of 3,159 counties, including some with policies in force. |
| `penetration_data_quality_flags` | string | JSON array of internal inconsistencies in FEMA published penetration figures for this county. |
| `penetration_note` | string | How the penetration figures were obtained and what the flags mean. |

#### Screen verdict

| Field | Type | Description |
| --- | --- | --- |
| `flood_market_screen_level` | string | LOW, MODERATE, ELEVATED, HIGH, INCONCLUSIVE when a contributing source was unavailable, or NO\_NFIP\_COMMUNITY when the boundaries were read and no community contains the site. |
| `flood_market_screen_flags` | string | JSON array of the specific conditions behind the screen level. |
| `flood_market_screen_basis` | string | How the screen level was reached, including the thresholds used. |

#### Per-property rows (opt-in)

| Field | Type | Description |
| --- | --- | --- |
| `loss_property_rows_emitted` | number | How many loss\_property rows this site produced. |
| `loss_property_id` | string | FEMA record identifier for this repetitive-loss property. |
| `loss_property_zip_code` | string | ZIP code as reported to FEMA on the property address. |
| `loss_property_reported_city` | string | City as reported to FEMA on the property address. |
| `loss_property_county` | string | County name FEMA derives from the county FIPS. |
| `loss_property_county_fips` | string | County FIPS FEMA derives from the geocoded address. |
| `loss_property_state_abbreviation` | string | State abbreviation on the FEMA record. |
| `loss_property_flood_zone` | string | FEMA-rated flood zone for this property, upper-cased. |
| `loss_property_flood_zone_class` | string | Flood-zone class: sfha\_riverine, sfha\_coastal\_velocity, sfha\_protection\_system, sfha\_decertified\_system, moderate\_or\_minimal, minimal or undetermined. |
| `loss_property_in_sfha` | boolean | True when the rated zone is a Special Flood Hazard Area, false for B, C and X, null for Zone D and for any zone FEMA did not publish. |
| `loss_property_flood_zone_note` | string | Why the zone could not be classified as SFHA or non-SFHA, when it could not. |
| `loss_property_occupancy_type` | number | FEMA occupancy code. |
| `loss_property_occupancy_label` | string | What FEMA occupancy code means, decoded scheme-aware. |
| `loss_property_occupancy_scheme` | string | legacy for codes 1-6, modern for codes 11-19. |
| `loss_property_is_residential` | boolean | True or false when the occupancy code is documented, null when it is not. |
| `loss_property_total_losses` | number | Paid NFIP claims over $1,000 since 1978 on this property. FEMA notes this can be inflated where structures were incorrectly linked. |
| `loss_property_most_recent_loss_date` | string | Most recent closed-claim loss date on this property. |
| `loss_property_original_construction_date` | string | Original construction date of the building. |
| `loss_property_original_policy_date` | string | Original flood policy date. |
| `loss_property_post_firm_construction` | boolean | True when construction started after the community first FIRM. |
| `loss_property_primary_residence` | boolean | True when the insured building is the insured party primary residence. |
| `loss_property_currently_insured` | boolean | True when FEMA records the property as currently insured by the NFIP. |
| `loss_property_mitigated` | boolean | True when FEMA records the property as mitigated as of the file date. |
| `loss_property_nfip_rl` | boolean | NFIP insurance-related Repetitive Loss designation. |
| `loss_property_nfip_srl` | boolean | NFIP insurance-related Severe Repetitive Loss designation. |
| `loss_property_fma_rl` | boolean | Flood Mitigation Assistance grant-related Repetitive Loss designation. |
| `loss_property_fma_srl` | boolean | Flood Mitigation Assistance grant-related Severe Repetitive Loss designation. |
| `loss_property_designations` | string | JSON array of every designation carried by this property. |
| `loss_property_latitude_redacted` | number | Latitude FEMA publishes, redacted for privacy. Not usable for distance. |
| `loss_property_longitude_redacted` | number | Longitude FEMA publishes, redacted for privacy. Not usable for distance. |
| `loss_property_latitude_decimals` | number | Decimal places actually present on the redacted latitude. Zero means roughly plus or minus 55 km. |
| `loss_property_longitude_decimals` | number | Decimal places actually present on the redacted longitude. |
| `loss_property_census_block_group` | string | Twelve-digit 2020 Census block group, or null where FEMA published a value that has lost digits. |
| `loss_property_census_block_group_status` | string | ok, absent, unusable\_scientific\_notation, unusable\_wrong\_length or unusable\_unrecognised. |
| `loss_property_census_block_group_reason` | string | Why the block group is unusable, when it is. |

### FAQ

**Can it tell me how many repetitive-loss properties are within a mile of my site?**
No, and neither can anything else built on this file. FEMA redacts the coordinates to
one decimal place, and 20-27% of records carry zero decimals. See the section above.

**What is the difference between NFIP RL and FMA RL?**
They are four independent flags, not a hierarchy. `nfipRl` / `nfipSrl` are insurance-side
designations driven by claim history; `fmaRl` / `fmaSrl` are grant-side designations that
drive Flood Mitigation Assistance eligibility. A property can carry any combination, and
the live file contains FMA-only severe designations - so counting the NFIP flag alone
understates severity. All four are counted separately.

**Why do I get two rows for one address?**
Because the address is inside a municipality that is an NFIP community AND inside a
county that is a separate NFIP community. Both have their own CRS class and their own
repetitive-loss rollup. Set `includeCountyCommunity: false` to receive only the
governing one.

**Why is `res_penetration_rate_sfha` null for my county?**
Because FEMA published it as null, usually alongside a `totalResStructuresSfha` of zero.
It is not recomputed from the underlying counts, because dividing by FEMA's zero would
invent a rate. The counts are on the row so you can see exactly what FEMA published.

**Does a CRS class of 10 mean no discount?**
Usually, but not always in FEMA's own file. Colorado carries class-10 communities
published with a 10% and a 15% SFHA discount. The discount is read from the file, never
derived from the class.

**What happens if FEMA takes one of these datasets offline?**
The run fails with a message naming the dataset, and nothing is billed. FEMA publishes
machine-readable deprecation dates on its catalog endpoint and this actor reads them, so
an announced end-of-life shows up in `openfema_deprecation_notice` on every row before
anything breaks.

### Related actors

- `nfip-flood-loss-risk-screener` - paid NFIP claim history by location.
- `fema-nri-county-risk-profile` - FEMA National Risk Index perils by county and tract.
- `epa-contaminated-site-screener` - Phase I ESA contamination screen for the same site.
- `site-due-diligence-bundle` - 20-layer site screen in one call.

### Pricing

Pay per result. One row = one billable result. A run that fails the drift gate, or that
cannot resolve any site, emits nothing and bills nothing.

# Actor input Schema

## `assets` (type: `array`):

Sites to screen. Each item is {"lat": <number>, "lon": <number>, "label": "<your reference>"}. Each site is resolved to the NFIP community whose published boundary contains it, then answered at community and county scope. FEMA redacts repetitive-loss property coordinates to one decimal place (roughly +/-5 to +/-55 km), so no radius or nearest-property distance is derivable from this data and none is offered. Maximum 25 sites per run; each distinct state costs one community-boundary download.

## `includeCountyCommunity` (type: `boolean`):

When a site sits inside an incorporated place, the county or parish is usually ALSO an NFIP community covering unincorporated areas, with its own CRS class and its own repetitive-loss rollup. Leave on to receive a profile row for both. Turn off to receive only the governing municipal community. Defaults to on when omitted.

## `includeTribalEtjLayer` (type: `boolean`):

FEMA publishes 608 tribal nation, extraterritorial-jurisdiction and special land-use-authority community polygons with no state or county code, so a state-scoped boundary read is structurally blind to them. Leave on to include them (one extra request per state). When off, tribal/ETJ coverage is reported as not checked rather than as a negative. Defaults to on when omitted.

## `includeLossProperties` (type: `boolean`):

Off by default. When on, every repetitive-loss and severe-repetitive-loss property FEMA publishes for each matched community is emitted as its own row, with designation, flood zone, occupancy, loss count, insured and mitigated status, and the redacted coordinate together with its measured decimal precision. This multiplies the billable row count, so a per-community cap applies.

## `maxLossPropertiesPerCommunity` (type: `integer`):

Caps how many individual repetitive-loss property rows are emitted per community when 'Also emit one row per repetitive-loss property' is on. The community rollup is always computed over every property FEMA publishes, not over this capped subset. Range 0 to 2000; 100 when omitted.

## `simulateOutage` (type: `string`):

Diagnostic seam for verifying that this actor fails loudly rather than publishing an unverified answer. Leave as 'none' for normal use. Any other value forces the named source or drift probe to fail so the failure path can be re-proved on demand instead of only during a real outage.

## Actor input object example

```json
{
  "assets": [
    {
      "lat": 39.7392,
      "lon": -104.9903,
      "label": "Denver City Hall, CO"
    },
    {
      "lat": 39.7047,
      "lon": -105.0814,
      "label": "Lakewood, CO (city inside Jefferson County)"
    },
    {
      "lat": 40.015,
      "lon": -105.2705,
      "label": "Boulder, CO"
    },
    {
      "lat": 40.53,
      "lon": -104.3,
      "label": "Rural Weld County, CO (unincorporated)"
    },
    {
      "lat": 29.9511,
      "lon": -90.0715,
      "label": "New Orleans, LA"
    }
  ],
  "includeCountyCommunity": true,
  "includeTribalEtjLayer": true,
  "maxLossPropertiesPerCommunity": 100,
  "simulateOutage": "none"
}
```

# Actor output Schema

## `results` (type: `string`):

The default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "assets": [
        {
            "lat": 39.7392,
            "lon": -104.9903,
            "label": "Denver City Hall, CO"
        },
        {
            "lat": 39.7047,
            "lon": -105.0814,
            "label": "Lakewood, CO (city inside Jefferson County)"
        },
        {
            "lat": 40.015,
            "lon": -105.2705,
            "label": "Boulder, CO"
        },
        {
            "lat": 40.53,
            "lon": -104.3,
            "label": "Rural Weld County, CO (unincorporated)"
        },
        {
            "lat": 29.9511,
            "lon": -90.0715,
            "label": "New Orleans, LA"
        }
    ],
    "includeCountyCommunity": true,
    "includeTribalEtjLayer": true,
    "includeLossProperties": false,
    "maxLossPropertiesPerCommunity": 100,
    "simulateOutage": "none"
};

// Run the Actor and wait for it to finish
const run = await client.actor("malonestar/fema-repetitive-loss-flood-market-screener").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "assets": [
        {
            "lat": 39.7392,
            "lon": -104.9903,
            "label": "Denver City Hall, CO",
        },
        {
            "lat": 39.7047,
            "lon": -105.0814,
            "label": "Lakewood, CO (city inside Jefferson County)",
        },
        {
            "lat": 40.015,
            "lon": -105.2705,
            "label": "Boulder, CO",
        },
        {
            "lat": 40.53,
            "lon": -104.3,
            "label": "Rural Weld County, CO (unincorporated)",
        },
        {
            "lat": 29.9511,
            "lon": -90.0715,
            "label": "New Orleans, LA",
        },
    ],
    "includeCountyCommunity": True,
    "includeTribalEtjLayer": True,
    "includeLossProperties": False,
    "maxLossPropertiesPerCommunity": 100,
    "simulateOutage": "none",
}

# Run the Actor and wait for it to finish
run = client.actor("malonestar/fema-repetitive-loss-flood-market-screener").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "assets": [
    {
      "lat": 39.7392,
      "lon": -104.9903,
      "label": "Denver City Hall, CO"
    },
    {
      "lat": 39.7047,
      "lon": -105.0814,
      "label": "Lakewood, CO (city inside Jefferson County)"
    },
    {
      "lat": 40.015,
      "lon": -105.2705,
      "label": "Boulder, CO"
    },
    {
      "lat": 40.53,
      "lon": -104.3,
      "label": "Rural Weld County, CO (unincorporated)"
    },
    {
      "lat": 29.9511,
      "lon": -90.0715,
      "label": "New Orleans, LA"
    }
  ],
  "includeCountyCommunity": true,
  "includeTribalEtjLayer": true,
  "includeLossProperties": false,
  "maxLossPropertiesPerCommunity": 100,
  "simulateOutage": "none"
}' |
apify call malonestar/fema-repetitive-loss-flood-market-screener --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,malonestar/fema-repetitive-loss-flood-market-screener"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/kdbVTxHMD6ANBeg6E/builds/QfxjseDe95fC3jiYh/openapi.json
