# FUDS Formerly Used Defense Sites Screener - UXO & Contamination (`malonestar/fuds-defense-site-screener`) Actor

Screen any US coordinate against the USACE Formerly Used Defense Sites inventory: on-property boundary intersect, nearest FUDS property, munitions response sites (MMRP/UXO) and contamination projects (IRP), split by hazard.

- **URL**: https://apify.com/malonestar/fuds-defense-site-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 screened sites

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

## FUDS Formerly Used Defense Sites Screener - UXO & Contamination

Screen any US coordinate against the **USACE Formerly Used Defense Sites (FUDS)**
inventory: 10,123 properties the Department of Defense once owned or controlled and
later released, 2,999 published boundary polygons, 1,656 munitions response sites and
5,584 environmental restoration projects.

FUDS is named in **ASTM E1527-21** as a standard environmental record source, and it is
one of the few in that standard with no Apify actor behind it. This one is built around
the two things a screening tool usually gets wrong on this dataset.

### The two defects this actor exists to prevent

**1. Only 29.6% of FUDS properties have a published boundary.** Screen by polygon
intersect alone and you miss 70% of the inventory. Screen by point proximity alone and
you miss the large properties entirely - which are exactly the former ranges.

Measured live at **39.603223, -104.631551** (an Aurora, Colorado parcel):

| Question | Answer |
|---|---|
| FUDS property **points** within 1 mile | **0** |
| Inside a published FUDS **boundary**? | **Yes - B08CO0021, BUCKLEY FIELD** |
| Inside a **munitions response site**? | **Yes - "Multi-Use Range", MMRP, status Investigation** |

A point-only screener answers *"no FUDS property within 1 mile"* for a parcel sitting
inside a former bombing and gunnery range with an open munitions investigation. This
actor runs the boundary intersect **and** the munitions-site intersect on every site, and
when the boundary evidence is incomplete it returns `null` rather than a confident `false`.

**2. MMRP and IRP are different hazards.** MMRP (Military Munitions Response Program) is
unexploded ordnance and munitions constituents - it stops trenching and drives an
anomaly-avoidance plan. IRP (Installation Restoration Program) is chemical contamination -
a recognised environmental condition on a Phase I. They are counted separately on every
row and never merged into "has a cleanup project".

### Who it is for

- **Phase I ESA consultants** - the FUDS record check, with the historical-use narrative
  USACE publishes, the eligibility determination and a link to the official fact sheet.
- **Land and industrial buyers / lenders** - portfolio screening before an offer.
- **Solar, BESS and data-centre siting teams** - a former range is a trenching problem
  long before it is a permitting problem.
- **Geotech and civil contractors** - MMRP exposure before intrusive work.
- **AI agents** - clean, chainable field descriptions; see the MCP section below.

### Example input

```json
{
  "assets": [
    { "lat": 39.603223, "lon": -104.631551, "label": "Aurora CO parcel", "radiusMiles": 1 },
    { "lat": 39.7392, "lon": -104.9903, "label": "Denver CO downtown site", "radiusMiles": 5 },
    { "lat": 43.2, "lon": -96.1, "label": "NW Iowa farmland - clear control", "radiusMiles": 25 }
  ],
  "includePropertyDetail": true,
  "includeMunitionsSiteDetail": true,
  "maxPropertiesPerAsset": 25
}
```

`assets` is required. A site with a missing or out-of-range coordinate is reported as an
error row that asserts nothing, rather than being silently screened.

### Output

Three record types, all in one flat, CSV-safe dataset:

- **`asset_summary`** - one per input site. Always emitted.
- **`fuds_property`** - one per FUDS property inside the radius, with its joined project
  and munitions-site roll-up. Optional (`includePropertyDetail`).
- **`munitions_response_site`** - one per MRS boundary intersecting the radius, flagging
  whether it actually **contains** your point. Optional (`includeMunitionsSiteDetail`).

#### How to read a `null`

`null` means **not checked**. `false` means **checked, and the answer is negative.** They
are never collapsed.

- `on_fuds_property` is `null` whenever a property inside the radius has no published
  boundary, so its true extent could never be tested against your point. Read
  `on_fuds_property_basis` and `properties_without_published_boundary` for the reason.
- Any `*_source_status` other than `ok` nulls `screening_level` and sets
  `screening_result` to `source_unavailable`. A partial read never produces a "clear".
- If **every** layer fails, the run FAILS and nothing is emitted or billed.

#### Three things that are not findings

- **`has_dod_funded_project: false` does not mean the property is clean.** It means DoD
  never funded a response project there. 7,248 of 10,123 properties are in that state.
- **`eligibility_state: not_stated`** (463 properties) is not "ineligible". USACE
  published no determination.
- **Everything here is a screening tool, not a determination.** FUDS is an annual
  snapshot (`data_vintage_fiscal_year`), the property point is a USACE representative
  coordinate rather than a parcel boundary, and a records search is not a site inspection.

### Output fields

All 128 declared fields. Every one is nullable: a dataset-schema type mismatch silently drops the
entire batch while the run still reports SUCCEEDED.

#### Shared - on every row

| Field | Type | Description |
|---|---|---|
| `record_type` | string | Row type: asset\_summary (one per input asset), fuds\_property (one per FUDS property inside the radius) or munitions\_response\_site (one per MRS boundary intersecting the radius). |
| `asset_label` | string | The label you supplied for this asset, or asset\_N if you did not supply one. |
| `asset_lat` | number | Latitude of the screened point, WGS84 decimal degrees, echoed back exactly as supplied. |
| `asset_lon` | number | Longitude of the screened point, WGS84 decimal degrees, echoed back exactly as supplied. |
| `search_radius_miles` | number | Radius actually used for this asset in statute miles, after clamping to 0-50. |
| `data_source` | string | The upstream this row was screened against. |
| `data_vintage_fiscal_year` | string | USACE fiscal-year vintage of the FUDS snapshot (the FISCALYEAR field). FUDS is an ANNUAL snapshot, not a live feed. |
| `checked_at` | string | UTC timestamp when this run queried the service. |
| `error` | string | Per-source error detail when something failed, otherwise null. A null here on a healthy run is good news, not a dead column. |

#### asset\_summary - verdict

| Field | Type | Description |
|---|---|---|
| `screening_result` | string | on\_fuds\_property | fuds\_within\_radius | no\_fuds\_within\_radius | source\_unavailable. source\_unavailable means at least one of the four FUDS layers did not answer, so NO determination was made. |
| `screening_level` | string | low | moderate | elevated | high, or null when any contributing layer did not answer. Never reads low while a source was unavailable. |
| `screening_reason` | string | Plain-language reason for screening\_level, generated from the counters on this row. |

#### asset\_summary - on-property and boundary coverage

| Field | Type | Description |
|---|---|---|
| `on_fuds_property` | boolean | true = the point falls inside a published FUDS property boundary polygon. false = every property inside the radius has a published boundary and none contains the point. null = NOT CHECKABLE, because at least one nearby property has no published boundary (only 29.6% of FUDS properties do) or a layer was unavailable. Never false on unverified evidence. |
| `on_fuds_property_basis` | string | Why on\_fuds\_property holds the value it does. Read this before acting on a null or a false. |
| `on_fuds_property_ids` | string | Semicolon-separated USACE property IDs whose boundary contains the point. |
| `on_fuds_property_names` | string | Semicolon-separated names of the FUDS properties whose boundary contains the point. |
| `on_munitions_response_site` | boolean | true = the point falls inside a published Munitions Response Site (MRS) boundary - the MEC/UXO footprint. null = the MRS layer did not answer. The single highest-value field for intrusive work. |
| `on_munitions_response_site_names` | string | Semicolon-separated names of the munitions response sites containing the point. |
| `fuds_properties_within_radius` | number | Count of FUDS property POINTS whose coordinate lies within the radius. Null when the property layer did not answer. |
| `properties_with_published_boundary` | number | How many of those properties have a boundary polygon published in the FUDS polygon layer. |
| `properties_without_published_boundary` | number | How many have NO published boundary. Every one of these is a property whose true extent could not be tested against your point. This is why on\_fuds\_property is often null. |
| `boundary_polygon_coverage_complete_in_radius` | boolean | true when every property inside the radius has a published boundary, so a false on\_fuds\_property is a fully verified negative. |

#### asset\_summary - nearest property

| Field | Type | Description |
|---|---|---|
| `nearest_property_id` | string | USACE DoD FUDS property ID of the closest property point inside the radius. |
| `nearest_property_name` | string | Name of the closest FUDS property inside the radius. |
| `nearest_property_distance_miles` | number | Great-circle distance from your point to that property point, in statute miles. The property POINT is a USACE representative coordinate, not the parcel boundary. |
| `nearest_property_state` | string | Two-letter state or territory code as USACE publishes it (lowercase). |
| `nearest_property_county` | string | County recorded by USACE for the nearest property. |
| `nearest_property_closest_city` | string | Closest city recorded by USACE for the nearest property. |
| `nearest_property_eligibility` | string | Raw USACE eligibility determination: Eligible, Ineligible, Categorical Exclusion, No Hazards, or null when USACE published none. |
| `nearest_property_eligibility_state` | string | Normalised eligibility: eligible, ineligible, categorical\_exclusion, no\_hazards, not\_stated or unrecognized. not\_stated is a real distinct state on 463 of 10,123 properties and is NOT ineligible. |
| `nearest_property_status` | string | USACE property status: Properties without projects, Properties with projects, or Properties with all projects at site closeout. |
| `nearest_property_has_dod_project` | boolean | Whether DoD ever FUNDED a response project here. false means no project was funded - it does NOT mean the property is clean. |
| `nearest_property_npl_status` | string | Whether the property is on the National Priorities List, as USACE states it. |
| `nearest_property_current_owner` | string | Raw USACE current-owner string for the nearest property, preserved verbatim. |
| `nearest_property_owner_categories` | string | Owner categories parsed from that string: federal, state, local, private, tribal or unclassified. |
| `nearest_property_fact_sheet_url` | string | USACE FUDS portal page for the nearest property. |
| `nearest_property_description` | string | USACE narrative describing the historical defense use of the nearest property. |

#### asset\_summary - munitions response sites (MMRP / UXO)

| Field | Type | Description |
|---|---|---|
| `munitions_response_sites_within_radius` | number | Count of MRS boundary polygons intersecting the search radius. |
| `munitions_response_sites_open` | number | How many of those are in Investigation or Cleanup - an open munitions response. |
| `munitions_response_sites_investigation` | number | MRS in Investigation status. |
| `munitions_response_sites_cleanup` | number | MRS in Cleanup status. |
| `munitions_response_sites_response_complete` | number | MRS at Response Complete. Not the same as site closeout - land-use controls can still apply. |
| `munitions_response_sites_closed_out` | number | MRS at Response Complete AND Site Closeout. |
| `nearest_munitions_response_site_name` | string | Name of the first munitions response site intersecting the radius. |
| `nearest_munitions_response_site_status` | string | Its status: investigation, cleanup, responseComplete or responseCompleteSiteCloseout. |

#### asset\_summary - response projects

| Field | Type | Description |
|---|---|---|
| `response_projects_in_scope` | number | Response projects in scope: project points inside the radius PLUS every project attached to a FUDS property found in the radius or containing your point. |
| `response_project_points_within_radius` | number | The stricter subset - response projects whose own published point falls inside the radius. |
| `mmrp_munitions_projects` | number | MMRP (Military Munitions Response Program) projects in scope: unexploded ordnance and munitions constituents. A different hazard from IRP and never merged with it. |
| `mmrp_munitions_projects_open` | number | MMRP projects still in Investigation or Cleanup. |
| `irp_contamination_projects` | number | IRP (Installation Restoration Program) projects in scope: chemical contamination, the classic Phase I recognised environmental condition. |
| `irp_contamination_projects_open` | number | IRP projects still in Investigation or Cleanup. |
| `other_program_projects` | number | Projects under another recognised DERP programme code (bddr or tbd). |
| `projects_investigation` | number | Projects in Investigation. |
| `projects_cleanup` | number | Projects in Cleanup. |
| `projects_response_complete` | number | Projects at Response Complete but NOT yet at site closeout. |
| `projects_response_complete_and_site_closeout` | number | Projects at Response Complete and Site Closeout. |
| `cost_to_complete_total_usd` | number | Sum of USACE cost-to-complete over projects that PUBLISHED a figure. Null when none did - never a fabricated zero. |
| `cost_to_complete_reported_projects` | number | How many in-scope projects published a cost-to-complete figure. |
| `cost_to_complete_unreported_projects` | number | How many did not. The total above covers only the reported ones. |

#### asset\_summary - evidence flags and per-source status

| Field | Type | Description |
|---|---|---|
| `mmrp_munitions_evidence` | boolean | true when the point is inside an MRS, an MRS intersects the radius, or an MMRP project is in scope. Null when the MRS or project layer did not answer. |
| `irp_contamination_evidence` | boolean | true when at least one IRP contamination project is in scope. Null when the project layer did not answer. false means no IRP project is recorded, NOT that the site is clean. |
| `properties_with_no_dod_project_funded` | number | How many properties in the radius have HAS\_PROJECTS = no. DoD never funded a response there; that is a funding fact, not a cleanliness finding. |
| `properties_source_status` | string | ok, unavailable or not\_attempted for the FUDS property point layer. |
| `boundary_polygon_source_status` | string | ok, unavailable or not\_attempted for the FUDS property boundary polygon layer. |
| `munitions_site_source_status` | string | ok, unavailable or not\_attempted for the munitions response site layer. |
| `response_project_source_status` | string | ok, unavailable or not\_attempted for the response project layer. |
| `sources_answered` | number | How many of the four FUDS layers answered. Anything below 4 nulls the screening level. |
| `sources_failed` | string | Semicolon-separated names of the layers that did not answer. |
| `query_complete` | boolean | true when the property read retrieved exactly the feature count the service reported - i.e. no silent truncation. |

#### fuds\_property rows

| Field | Type | Description |
|---|---|---|
| `property_rank_by_distance` | number | 1 = nearest FUDS property to your point, ascending by distance. |
| `property_id` | string | USACE DoD FUDS property ID - the join key to projects and munitions response sites. |
| `property_unique_number` | string | USACE FUDS unique property number. |
| `installation_id` | string | USACE FUDS installation ID, which can span several properties. |
| `property_name` | string | USACE property name. |
| `property_description` | string | USACE narrative of the historical defense use - the raw material for a Phase I historical-use section. |
| `property_latitude` | number | USACE representative latitude for the property, WGS84. |
| `property_longitude` | number | USACE representative longitude for the property, WGS84. |
| `distance_miles` | number | Great-circle distance from your point to the property point, in statute miles. |
| `property_state` | string | Two-letter state or territory code, lowercase as USACE publishes it. |
| `property_county` | string | County recorded by USACE. |
| `property_closest_city` | string | Closest city recorded by USACE. |
| `property_congressional_district` | string | Congressional district recorded by USACE. |
| `property_epa_region` | string | EPA region recorded by USACE. |
| `eligibility` | string | Raw USACE eligibility determination, or null where USACE published none. |
| `eligibility_state` | string | Normalised eligibility state, including not\_stated for the 463 properties USACE leaves blank. |
| `property_status` | string | USACE property status string. |
| `property_status_recognized` | boolean | false when USACE published a status value this actor does not have in its closed vocabulary. |
| `has_dod_funded_project` | boolean | Whether DoD ever funded a response project here. false is a funding fact, not a cleanliness determination. |
| `npl_status` | string | National Priorities List status as USACE states it. |
| `current_owner` | string | Raw USACE current-owner string, preserved verbatim. |
| `current_owner_list` | string | Individual owners parsed out of that string and semicolon-joined. |
| `current_owner_categories` | string | Owner categories: federal, state, local, private, tribal or unclassified. |
| `usace_district` | string | USACE district code. |
| `usace_division` | string | USACE division code. |
| `property_fact_sheet_url` | string | USACE FUDS portal page for this property. |
| `has_published_boundary_polygon` | boolean | Whether USACE publishes a boundary polygon for this property. Only 2,999 of 10,123 properties (29.6%) have one; where this is false, the property extent could not be tested against your point. |
| `boundary_polygon_status` | string | Status carried on the boundary polygon record: allCloseout, hasProjects or noProjects. Note this layer uses camelCase codes while the point layer uses prose. |
| `boundary_polygon_owner` | string | Current-owner string from the boundary polygon. This layer uses PLAIN CATEGORY NAMES, a different vocabulary from the point layer prefixes. |
| `boundary_polygon_owner_categories` | string | Owner categories parsed from the polygon-layer vocabulary. |
| `boundary_polygon_area_square_degrees` | number | Shape\_\_Area as USACE publishes it, in SQUARE DEGREES on a WGS84 layer. Deliberately not converted to acres - a degree of longitude is not a constant length. |
| `response_projects` | number | Response projects attached to this property. |
| `project_statuses` | string | Distinct project statuses on this property, semicolon-joined. |
| `project_names` | string | Project names on this property, semicolon-joined. |
| `project_restoration_categories` | string | Distinct USACE environmental restoration categories on this property. |
| `project_cost_to_complete_total_usd` | number | Cost-to-complete summed over this property projects that published a figure. |
| `earliest_response_complete_date` | string | Earliest response-complete date across this property projects, YYYY-MM-DD. |
| `latest_site_closeout_date` | string | Latest site-closeout date across this property projects, YYYY-MM-DD. |
| `munitions_response_sites` | number | Munitions response sites attached to this property that intersect your radius. |
| `munitions_response_site_names` | string | Their names, semicolon-joined. |

#### munitions\_response\_site rows

| Field | Type | Description |
|---|---|---|
| `site_rank` | number | 1 = first munitions response site returned for this asset. |
| `mrs_object_id` | number | ArcGIS OBJECTID of the munitions response site feature. |
| `mrs_name` | string | USACE name of the munitions response site. |
| `mrs_official_site_name` | string | Official site name where USACE publishes one. |
| `mrs_description` | string | USACE description of the munitions response site. |
| `mrs_project_number` | string | USACE project number for the munitions response. |
| `mrs_restoration_site_id` | string | USACE environmental restoration site / munitions response area ID. |
| `mrs_contains_asset_point` | boolean | true when THIS munitions response site polygon contains your point, as opposed to merely intersecting the radius. |
| `derp_program` | string | DERP programme code. Every munitions response site is mmrp by definition. |
| `derp_program_recognized` | boolean | false when USACE published a programme code outside the service own declared domain. |
| `mrs_project_category` | string | USACE project category (mmrp, mmrpCwm and similar). Null on 1,502 of 1,656 sites. |
| `mrs_status` | string | MRS status as a camelCase code: investigation, cleanup, responseComplete or responseCompleteSiteCloseout. |
| `mrs_status_recognized` | boolean | false when USACE published an MRS status outside the closed vocabulary. |
| `mrs_response_open` | boolean | true when the munitions response is still in Investigation or Cleanup. Null when the status was not recognised. |
| `mrs_relative_priority` | string | USACE relative priority code where published. Null on most sites. |
| `mrs_area_square_degrees` | number | Shape\_\_Area in SQUARE DEGREES on a WGS84 layer, published as-is and never converted to acres. |
| `mrs_state` | string | Two-letter state or territory code, lowercase. |
| `property_distance_miles` | number | Distance from your point to the parent property point, where that property is inside the radius. |
| `property_in_search_radius` | boolean | true when the parent FUDS property point was itself found inside the radius. false is common and expected: an MRS boundary can reach your parcel while the property representative point sits miles away. |

### How it works

Per site, six reads against the USACE FUDS FeatureServer:

1. **Property points** within the radius (`FUDS Property Points`), post-filtered by haversine.
2. **Boundary intersect** - point-in-polygon against `FUDS Property Polygon`, with
   `distance`/`units` absent entirely (`distance=0` is *not* a PIP on ArcGIS).
3. **Boundary coverage** - an id-scoped read establishing which properties in the radius
   actually have a published boundary. Without it, a clean intersect would be mistaken
   for "not on a FUDS property".
4. **Munitions response sites** within the radius, plus a second intersect asking whether
   one *contains* your point.
5. **Response projects** whose own point is in the radius.
6. **Response projects joined by property id** to every property or munitions site found -
   which is how the Buckley canary returns 5 MMRP projects with no property point nearby.

Layer IDs are resolved from the service's own metadata **by name**. They are
non-contiguous (1, 2, 3, 4, 6, 7, 8, 9, 10 - no layer 0, no layer 5), and layers 6-8 are
Interim Risk Management, a different programme that is never counted as FUDS.

#### Live drift gate

Before any billable row, every run verifies against the live service and **fails without
billing** if anything regresses: layer identity and field sets, row-count bands
(10,123 / 5,584 / 1,656 / 2,999 as measured 2026-08-11), boundary-coverage ratio, closed
vocabularies (an unknown `ELIGIBILITY`, `DERPPROGRAM` or `PROJECTSTATUS` code fails the
run rather than being guessed at), declared spatial reference plus a coordinate-magnitude
check, circle fidelity against a padded query, a **positive canary** (the Buckley Field
point above must still return B08CO0021, an `mmrp` site and at least 3 projects) and a
**negative control** (43.2, -96.1 must still return nothing on all three probes). Every
measured value is logged on every run.

Reads are truncation-guarded against the service's own `returnCountOnly` answer and paged
by keyset on OBJECTID. This matters: `maxRecordCount` is 9,000 on the property layer
against 10,123 rows, and 2,000 on the polygon layer against 2,999 - an unpaginated read
returns 2,000 rows, sets `exceededTransferLimit`, and looks completely successful.

### Use as an MCP tool

This actor is callable by AI agents over `mcp.apify.com`. Add it to Claude Desktop,
Claude Code or Cursor:

```json
{
  "mcpServers": {
    "apify": {
      "command": "npx",
      "args": ["-y", "@apify/actors-mcp-server", "--actors", "malonestar/fuds-defense-site-screener"],
      "env": { "APIFY_TOKEN": "your-apify-token" }
    }
  }
}
```

Worked agent prompt:

> "Screen 39.603223, -104.631551 and 30.2672, -97.7431 against the FUDS inventory at a
> 2-mile radius. For each, tell me whether the point is inside a former defense property
> boundary or a munitions response site, and split any response projects into munitions
> (MMRP) versus contamination (IRP)."

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

### Pricing

Pay per result: **$10 per 1,000 rows** (one row = one `asset_summary`, `fuds_property` or
`munitions_response_site` record), with graduated discounts on paid Apify plans. A run
that fails its drift gate or loses every source emits nothing and bills nothing.

Set `includePropertyDetail` and `includeMunitionsSiteDetail` to `false` for one row per
site - the `asset_summary` counts are complete either way.

### FAQ

**What is a Formerly Used Defense Site?** A property DoD owned, leased or otherwise
controlled and released before October 1986 - training ranges, depots, airfields, plants,
laundries. USACE runs the cleanup programme; the property itself is usually in private,
municipal or other federal hands today.

**Is this the same as an active military base?** No. FUDS covers *released* property.
Active and BRAC installations are separate inventories.

**Does "no projects" mean the site is clean?** No. It means DoD never funded a response
project there. 7,248 of 10,123 properties are in that state.

**Why is `on_fuds_property` sometimes null?** Because only 29.6% of FUDS properties have a
published boundary polygon, so for the other 70% the property extent cannot be tested
against your point. `null` is the honest answer; `false` would be a guess.

**How current is the data?** FUDS is an annual snapshot. The vintage is published on
every row as `data_vintage_fiscal_year` (FY2024 at the time of writing).

**Can I search by property name or state instead of a coordinate?** Not in v1 - this is a
coordinate screener. Open an issue on the Apify Store page if you need a name/state mode.

### Related actors

- **`epa-contaminated-site-screener`** - Superfund, RCRA, USTs and ECHO enforcement at the
  same coordinate. The other half of a Phase I records search.
- **`site-due-diligence-bundle`** - 20 federal layers for one coordinate in one call.
- **`usgs-historical-topo-records-review`** - historical topographic coverage, the ASTM
  historical-use companion to the FUDS narrative.
- **`state-tank-spill-registry-screener`** - state tank and spill registries.

### Source

USACE FUDS public FeatureServer:
`https://services7.arcgis.com/n1YM8pTrFmm7L4hs/arcgis/rest/services/fuds/FeatureServer`

Keyless and public. This actor is not affiliated with or endorsed by the US Army Corps of
Engineers or the Department of Defense.

# Actor input Schema

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

One entry per site. Each needs lat and lon in WGS84 decimal degrees; label and radiusMiles are optional. Example: \[{"lat": 39.603223, "lon": -104.631551, "label": "Aurora CO parcel", "radiusMiles": 1}]. A site with a missing or out-of-range coordinate is reported as an error row rather than silently screened.

## `radiusMiles` (type: `integer`):

Radius applied to any site that does not carry its own radiusMiles. Statute miles, clamped to 1-50. When omitted entirely the actor uses 1 mile. Note that the boundary intersect is exact regardless of radius: a point inside a published FUDS boundary is flagged even at radius 1, which is how a parcel inside a former bombing range is caught when no property point is anywhere near it.

## `includePropertyDetail` (type: `boolean`):

Emit a fuds\_property detail row for each FUDS property inside the radius, carrying its eligibility, ownership, boundary availability and joined MMRP/IRP project roll-up. Defaults to true. Each row is a billable result.

## `includeMunitionsSiteDetail` (type: `boolean`):

Emit a munitions\_response\_site detail row for each MRS boundary intersecting the radius, flagging whether it actually contains your point. Defaults to true. Each row is a billable result.

## `maxPropertiesPerAsset` (type: `integer`):

Cap on fuds\_property detail rows emitted per site, nearest first. The asset\_summary counts always cover every property found, so a cap never distorts the totals. Defaults to 50.

## `maxSitesPerAsset` (type: `integer`):

Cap on munitions\_response\_site detail rows emitted per site. The asset\_summary counts always cover every site found. Defaults to 50.

## `maxAssets` (type: `integer`):

Safety cap on how many of the supplied sites are screened in one run, to bound both runtime and spend. Defaults to 250.

## `skipDriftChecks` (type: `boolean`):

Diagnostic only. The drift gate verifies layer identity, row-count bands, closed vocabularies, a positive canary and a negative control before any billable row is emitted. Turning it off means a silently changed upstream can produce a confident wrong answer. Leave it off (false).

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

Diagnostic seam that forces one or all FUDS layers to fail, so the null-vs-false contract can be re-proved on demand instead of only during a real outage. Use none for normal runs.

## Actor input object example

```json
{
  "assets": [
    {
      "lat": 39.603223,
      "lon": -104.631551,
      "label": "Aurora CO parcel - inside the former Buckley Field range",
      "radiusMiles": 1
    },
    {
      "lat": 39.7392,
      "lon": -104.9903,
      "label": "Denver CO downtown site",
      "radiusMiles": 3
    },
    {
      "lat": 34.0709,
      "lon": -118.2903,
      "label": "Los Angeles CA infill site",
      "radiusMiles": 3
    },
    {
      "lat": 43.2,
      "lon": -96.1,
      "label": "NW Iowa farmland - clear control",
      "radiusMiles": 25
    }
  ],
  "radiusMiles": 1,
  "includePropertyDetail": true,
  "includeMunitionsSiteDetail": true,
  "maxPropertiesPerAsset": 50,
  "maxSitesPerAsset": 50,
  "maxAssets": 250,
  "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.603223,
            "lon": -104.631551,
            "label": "Aurora CO parcel - inside the former Buckley Field range",
            "radiusMiles": 1
        },
        {
            "lat": 39.7392,
            "lon": -104.9903,
            "label": "Denver CO downtown site",
            "radiusMiles": 3
        },
        {
            "lat": 34.0709,
            "lon": -118.2903,
            "label": "Los Angeles CA infill site",
            "radiusMiles": 3
        },
        {
            "lat": 43.2,
            "lon": -96.1,
            "label": "NW Iowa farmland - clear control",
            "radiusMiles": 25
        }
    ],
    "radiusMiles": 1,
    "includePropertyDetail": true,
    "includeMunitionsSiteDetail": true,
    "maxPropertiesPerAsset": 50,
    "maxSitesPerAsset": 50,
    "maxAssets": 250,
    "skipDriftChecks": false,
    "simulateOutage": "none"
};

// Run the Actor and wait for it to finish
const run = await client.actor("malonestar/fuds-defense-site-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.603223,
            "lon": -104.631551,
            "label": "Aurora CO parcel - inside the former Buckley Field range",
            "radiusMiles": 1,
        },
        {
            "lat": 39.7392,
            "lon": -104.9903,
            "label": "Denver CO downtown site",
            "radiusMiles": 3,
        },
        {
            "lat": 34.0709,
            "lon": -118.2903,
            "label": "Los Angeles CA infill site",
            "radiusMiles": 3,
        },
        {
            "lat": 43.2,
            "lon": -96.1,
            "label": "NW Iowa farmland - clear control",
            "radiusMiles": 25,
        },
    ],
    "radiusMiles": 1,
    "includePropertyDetail": True,
    "includeMunitionsSiteDetail": True,
    "maxPropertiesPerAsset": 50,
    "maxSitesPerAsset": 50,
    "maxAssets": 250,
    "skipDriftChecks": False,
    "simulateOutage": "none",
}

# Run the Actor and wait for it to finish
run = client.actor("malonestar/fuds-defense-site-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.603223,
      "lon": -104.631551,
      "label": "Aurora CO parcel - inside the former Buckley Field range",
      "radiusMiles": 1
    },
    {
      "lat": 39.7392,
      "lon": -104.9903,
      "label": "Denver CO downtown site",
      "radiusMiles": 3
    },
    {
      "lat": 34.0709,
      "lon": -118.2903,
      "label": "Los Angeles CA infill site",
      "radiusMiles": 3
    },
    {
      "lat": 43.2,
      "lon": -96.1,
      "label": "NW Iowa farmland - clear control",
      "radiusMiles": 25
    }
  ],
  "radiusMiles": 1,
  "includePropertyDetail": true,
  "includeMunitionsSiteDetail": true,
  "maxPropertiesPerAsset": 50,
  "maxSitesPerAsset": 50,
  "maxAssets": 250,
  "skipDriftChecks": false,
  "simulateOutage": "none"
}' |
apify call malonestar/fuds-defense-site-screener --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,malonestar/fuds-defense-site-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/mZlieQ935kCCXepbn/builds/juSIRdXUrafvrimMR/openapi.json
