USFWS Wetlands Proximity Screener - Section 404 Site Risk API avatar

USFWS Wetlands Proximity Screener - Section 404 Site Risk API

Pricing

from $4.40 / 1,000 results

Go to Apify Store
USFWS Wetlands Proximity Screener - Section 404 Site Risk API

USFWS Wetlands Proximity Screener - Section 404 Site Risk API

Wetland due-diligence API for site selection: per lat/lon site, wetland presence within radius, Cowardin classification codes/systems, wetland types, total acreage nearby and a Section 404 dredge-and-fill screening flag. USFWS National Wetlands Inventory open data.

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

10 days ago

Last modified

Share

Screen any list of US coordinates against the USFWS National Wetlands Inventory (NWI) and get back, per site: whether a mapped wetland sits on the site, whether one sits within your radius, the measured distance and bearing to the nearest one, the full Cowardin classification decoded into system / subsystem / class / subclass / water regime / special modifiers, acreage by type and by system, and a gated Clean Water Act Section 404 screening verdict with the reasoning attached.

One dataset row per site. Keyless, national coverage, no API key to obtain.

Screening tool. NWI mapping is not a wetland delineation and is not an approved jurisdictional determination. It tells you where to look and where the risk is.

What changed in v1.1 (2026-07-30)

v1.0 shipped four defects that produced plausible wrong answers while the run reported SUCCESS. All four are fixed, and each is now covered by a regression test that was mutation-verified.

Defect in v1.0Measured impactv1.1
One unpaginated query; exceededTransferLimit never readAt 47.5,-99.0 r=5000 the true count is 1,582 polygons; the actor returned 1,000 and summed acreage over that arbitrary 63.2% subsetFull pagination, exceededTransferLimit honoured, and results_truncated published. Acreage is nulled rather than summed over a subset
Screened a bounding box, not a circleEnvelope reaches sqrt(2)xR at its corners. Live: 29.55,-90.55 r=5000 -> circle 357, envelope 518 (+45.1%)True point + distance circle. The envelope builder remains only as a documented fallback
PAGE_SIZE set to 2000The service caps at 1000. The actor asked for a page it could never receive and never noticed the shortfallPAGE_SIZE = 1000, asserted live against the layer's own maxRecordCount
nearest_wetland_* was the largest-acreage polygon, not the nearestA proxy reported as a measurement on a question where the number is the whole pointMeasured distance + bearing, with distance_method, a tolerance, and a lower bound. The old semantic is preserved under primary_wetland_*_by_acreage

Also new: the joined NWI_Wetland_Codes table (35 authoritative decode columns) was fetched by nobody in v1.0 - the actor read three columns and hand-decoded the system letter from a five-entry map. v1.1 reads the join. Output went from 16 to 79 fields, append-only: every v1.0 field is still present with its original name.

Who this is for

  • Phase I ESA consultants - a wetlands line item on every report. wetland_on_site, nearest_wetland_distance_m and jurisdictional_likelihood answer it for a portfolio in one call. Pairs with the tank/spill and contaminated-site screeners below.
  • Wetland delineators and environmental planners - cowardin_class_names, cowardin_subclass_names, cowardin_water_regime_names and cowardin_special_modifiers tell you what vegetation and hydrology to expect before you walk the site, and which features are Excavated, Farmed or Diked/Impounded.
  • Solar, BESS, wind and infrastructure siting teams - screen hundreds of candidate parcels for Section 404 exposure before spending money on any of them. delineation_recommended is the triage field.
  • Mitigation bankers and land trusts - acres_by_wetland_type, acres_by_system and the tidal / deepwater flags quantify what is actually on a tract.
  • AI agents - every field carries a description, so this reads cleanly as an MCP tool.

Example input

{
"assets": [
{ "lat": 36.3736, "lon": -89.385, "label": "Reelfoot Lake, TN - site inside a mapped lake" },
{ "lat": 35.2216, "lon": -75.6913, "label": "Cape Hatteras, NC - estuarine tidal marsh" },
{ "lat": 39.7392, "lon": -104.9903, "label": "Denver, CO - urban infill" },
{ "lat": 33.4484, "lon": -112.074, "label": "Phoenix, AZ - dry upland reference point" }
],
"radiusMeters": 500,
"computeNearestDistance": true,
"nearestSearchRadiusMeters": 1609,
"maxResults": 500
}

Live results from exactly that input:

SiteOn siteWithin 500 mNearestLikelihood404 flag
Reelfoot Lake, TNtruetrue (3)0 m (point in polygon)hightrue
Cape Hatteras, NCfalsetrue (26)2.4 m NNWhightrue
Denver, COfalsefalse (0)560.8 m WSWlowfalse
Phoenix, AZfalsefalse (0)1,390.9 m Nlowfalse

Note Denver and Phoenix: section_404_flag is false for the stated radius, and the row still tells you exactly how far the nearest wetland is and in which direction. That is the difference between "clear" and "clear at 500 m".

Input fields

FieldTypeDefaultNotes
assetsarrayrequired{ "lat", "lon", "label" } objects, "lat,lon" strings, or [lat, lon] arrays. One billed row per asset.
radiusMetersinteger30010-5000. Screened as a true circle. The Console prefill sends this same 300 m, so the demo and an API caller who omits the field get the identical screen.
computeNearestDistancebooleantrueMeasures the real distance/bearing to the nearest wetland (up to ~10 extra small requests per site). Off -> nearest_wetland_* falls back to the largest-acreage feature and nearest_basis says largest_acreage_proxy.
nearestSearchRadiusMetersinteger1609How far out to look for the nearest wetland. Independent of radiusMeters, capped at 8000, never below radiusMeters.
maxResultsinteger5001-2000 assets per run.

Output fields (all 79)

Every field the actor emits is listed. Nothing is abbreviated - buyers pick off this table.

Site + v1.0 core contract

FieldTypeDescription
asset_labelstringLabel of the screened site, as supplied, or "lat,lon" when none was given.
asset_latnumberLatitude of the screened site (WGS84 decimal degrees).
asset_lonnumberLongitude of the screened site (WGS84 decimal degrees).
radius_metersintegerRadius in metres used for the wetland presence check around this site. v1.1 screens a TRUE circle; v1.0 used a bounding box that reached sqrt(2)*R at its corners and over-reported by 26.7-45.1 percent at the sites measured live.
wetland_within_radiusbooleanTrue when at least one NWI-mapped wetland polygon intersects the circular screening radius. False only when the radius query succeeded and returned nothing. NULL when the radius query was unavailable - null means NOT CHECKED, never "clear".
wetland_countintegerNumber of distinct NWI wetland polygons intersecting the screening radius. This is the exact server-side count when the count query succeeded, so it stays correct even if the feature pages were truncated.
cowardin_codesarrayUnique NWI Cowardin classification codes (ATTRIBUTE) within the radius, e.g. L1UBH, PEM1C, PFO1/2C.
cowardin_systemsarrayDecoded Cowardin system names in the verbose v1.0 wording, kept unchanged for pipelines keyed to it. Prefer cowardin_system_names, which comes from the authoritative NWI code table.
wetland_typesarrayUnique plain-English NWI wetland types (WETLAND_TYPE) within the radius, e.g. Lake, Freshwater Emergent Wetland, Estuarine and Marine Wetland.
nearest_wetland_typestringPlain-English NWI type of the TRUE nearest wetland polygon. In v1.0 this field held the largest-acreage feature instead; v1.1 measures the nearest and preserves the old meaning in primary_wetland_type_by_acreage. See distance_method for how it was resolved.
nearest_wetland_codestringCowardin classification code of the TRUE nearest wetland polygon.
total_acres_within_radiusnumberSum of NWI ACRES across every wetland polygon intersecting the radius. NULL when the feature set was truncated - a sum over an arbitrary subset is a wrong answer, not a partial one.
section_404_flagbooleanTrue when a mapped wetland or deepwater habitat is present within the radius, indicating the site may trigger Clean Water Act Section 404 permitting and a formal wetland delineation. NULL when any contributing NWI query was unavailable. Screening indicator only - NOT a jurisdictional determination.
errorstringError message on an ERROR row (bad coordinates, or every NWI query failing for this site). Null on a successful row.
checked_atstringISO 8601 UTC timestamp of the screening run.
source_urlstringUSFWS National Wetlands Inventory MapServer layer the wetland data came from.

Per-source outcome contract (read these before trusting anything else)

FieldTypeDescription
nwi_statusstringOverall outcome of the NWI reads for this site: ok, partial (some data retrieved, some missing or truncated), or unavailable.
nwi_errorstringConcatenated per-query failure messages when anything went wrong. Null on a fully clean row.
onsite_query_statusstringOutcome of the point-in-polygon query: ok or unavailable.
radius_query_statusstringOutcome of the circular radius query: ok, partial (truncated at the page cap) or unavailable.
nearest_query_statusstringOutcome of the nearest-wetland search: ok, none_within_search_radius, skipped (turned off via computeNearestDistance) or unavailable.
data_partialbooleanTrue when this row was built from an incomplete set of NWI reads. Read it before trusting any count or acreage on the row.
results_truncatedbooleanTrue when the NWI service reported exceededTransferLimit and the page cap was reached, so not every polygon in the radius was retrieved. Acreage and composition fields are nulled out when this is true.
query_geometry_methodstringWhich geometry was sent to the service: circle_buffer (a true point + distance query, the v1.1 default) or bbox_envelope (the v1.0 fallback, which over-reports).
wetland_count_reported_by_serverintegerExact polygon count returned by a returnCountOnly query against the same circle. Compare against the number of retrieved features to detect truncation independently.

On-site point-in-polygon

FieldTypeDescription
wetland_on_sitebooleanTrue when the site coordinate itself falls inside a mapped NWI wetland polygon (a true point-in-polygon test, distance parameters omitted - distance=0 returns nothing on this service). NULL when the point-in-polygon query was unavailable.
on_site_wetland_codestringCowardin classification code of the wetland polygon containing the site coordinate. Null when the site is not inside one.
on_site_wetland_typestringPlain-English NWI type of the wetland polygon containing the site coordinate.
on_site_wetland_acresnumberNWI-reported acreage of the wetland polygon containing the site coordinate.
on_site_system_namestringCowardin system of the on-site polygon (Palustrine, Lacustrine, Riverine, Estuarine, Marine) from the NWI code table.
on_site_class_namestringCowardin class of the on-site polygon, e.g. Emergent, Forested, Scrub-Shrub, Unconsolidated Bottom.
on_site_water_regime_namestringCowardin water regime of the on-site polygon, e.g. Seasonally Flooded, Permanently Flooded, Irregularly Flooded.
on_site_objectidintegerNWI OBJECTID of the polygon containing the site coordinate, for cross-reference against the Wetlands Mapper.

Measured nearest wetland

FieldTypeDescription
nearest_wetland_distance_mnumberMeasured distance in metres from the site coordinate to the boundary of the nearest NWI wetland polygon. 0 when the site is inside one. Null when no wetland lies within the nearest-search radius or the search was skipped. Always read distance_method with this value.
nearest_wetland_distance_lower_bound_mnumberLower bound established by the server-side distance bisection. The true distance lies between this and the reported value plus the tolerance.
nearest_wetland_distance_tolerance_mnumberAccuracy envelope of the reported distance, in metres: the polygon generalization tolerance for a geometry_measured value, or the bisection bracket width for a ring_bisection value.
nearest_wetland_bearing_degnumberCompass bearing in degrees (0-360, 0 = north) from the site to the closest point on the nearest wetland. Null when the distance came from the bisection only.
nearest_wetland_directionstring16-point compass label for nearest_wetland_bearing_deg, e.g. N, ENE, SSW.
nearest_wetland_acresnumberNWI-reported acreage of the nearest wetland polygon.
nearest_wetland_objectidintegerNWI OBJECTID of the nearest wetland polygon.
nearest_wetland_system_namestringCowardin system of the nearest wetland polygon.
nearest_wetland_subsystem_namestringCowardin subsystem of the nearest polygon, e.g. Limnetic, Littoral, Intertidal, Lower Perennial. Blank for Palustrine, which has no subsystem.
nearest_wetland_class_namestringCowardin class of the nearest wetland polygon.
nearest_wetland_subclass_namestringCowardin subclass of the nearest polygon, e.g. Persistent, Broad-Leaved Deciduous, Needle-Leaved Evergreen.
nearest_wetland_water_regime_namestringCowardin water regime of the nearest wetland polygon.
nearest_wetland_water_regime_subgroupstringNontidal, Saltwater Tidal or Freshwater Tidal for the nearest polygon. Tidal waters are categorically waters of the United States.
nearest_wetland_modifiersarrayCowardin special modifiers on the nearest polygon, e.g. Excavated, Diked/Impounded, Farmed, Partially Drained/Ditched, Beaver.
nearest_wetland_within_search_radiusbooleanTrue when a wetland was found inside nearest_search_radius_m, false when the search completed and found none, null when the search did not run.
nearest_search_radius_mintegerRadius in metres searched for the nearest wetland. Independent of radius_meters, so a site can read "no wetland within 300 m" and still report the closest one 1,391 m away.
distance_methodstringHow nearest_wetland_distance_m was produced: point_in_polygon (exact, site is inside), geometry_measured (measured against the polygon boundary in WGS84), ring_bisection (bracketed by server-side distance queries, upper bound reported), none_within_search_radius, skipped or unavailable. A proxy is never reported as a measurement.
nearest_basisstringOne sentence explaining exactly how the nearest wetland was resolved, for the audit trail.

Largest-acreage feature (what v1.0 called "nearest")

FieldTypeDescription
primary_wetland_code_by_acreagestringCowardin code of the LARGEST-ACREAGE wetland within the radius. This is what v1.0 reported in nearest_wetland_code; it is preserved here under its true name.
primary_wetland_type_by_acreagestringPlain-English type of the largest-acreage wetland within the radius.
primary_wetland_acresnumberAcreage of the largest-acreage wetland within the radius.

Full Cowardin decode across the radius

FieldTypeDescription
cowardin_system_namesarrayAuthoritative Cowardin system names present within the radius, from the NWI code table join: Palustrine, Lacustrine, Riverine, Estuarine, Marine.
cowardin_subsystem_namesarrayCowardin subsystems present within the radius: Limnetic, Littoral, Subtidal, Intertidal, Tidal, Lower Perennial, Upper Perennial, Intermittent.
cowardin_class_namesarrayCowardin classes present within the radius: Emergent, Forested, Scrub-Shrub, Unconsolidated Bottom, Aquatic Bed, Unconsolidated Shore, Rocky Shore, Reef, Streambed, Rock Bottom, Moss-Lichen Wetland.
cowardin_subclass_namesarrayCowardin subclasses present within the radius, e.g. Persistent, Broad-Leaved Deciduous, Needle-Leaved Evergreen. This is the vegetation detail a delineator needs.
cowardin_split_class_namesarraySecond class of any split-class polygon (a code like PFO2/SS3C is Forested over Scrub-Shrub). Present on real mixed-vegetation mapping units.
cowardin_water_regime_namesarrayCowardin water regimes present within the radius, e.g. Temporary Flooded, Seasonally Flooded, Semipermanently Flooded, Permanently Flooded, Irregularly Flooded. This drives hydrology expectations on a delineation.
cowardin_water_regime_subgroupsarrayNontidal, Saltwater Tidal and/or Freshwater Tidal across the radius.
cowardin_special_modifiersarrayCowardin special modifiers present within the radius: Excavated, Diked/Impounded, Farmed, Partially Drained/Ditched, Artificial Substrate, Spoil, Beaver. These bear directly on whether a feature is jurisdictional.

Composition and acreage

FieldTypeDescription
acres_by_wetland_typearrayPer-type breakdown within the radius: [{ wetland_type, count, acres }], sorted by acreage. Empty when the feature set was truncated.
acres_by_systemarrayPer-system breakdown within the radius: [{ system_name, count, acres }], sorted by acreage. Empty when the feature set was truncated.
palustrine_acresnumberTotal Palustrine (marsh, swamp, bog, pond) acreage within the radius. Null when the feature set was truncated.
lacustrine_acresnumberTotal Lacustrine (lake and reservoir) acreage within the radius.
riverine_acresnumberTotal Riverine (river and stream channel) acreage within the radius.
estuarine_acresnumberTotal Estuarine (tidal, river-meets-sea) acreage within the radius.
marine_acresnumberTotal Marine (open ocean and coastline) acreage within the radius.
largest_wetland_acresnumberAcreage of the single largest wetland polygon within the radius.
smallest_wetland_acresnumberAcreage of the single smallest wetland polygon within the radius. Small isolated Palustrine features are the ones most likely to be contested post-Sackett.

Jurisdictional screen

FieldTypeDescription
tidal_wetland_presentbooleanTrue when an Estuarine or Marine system, or any tidal water regime, is mapped within the radius. NULL when the radius query was unavailable.
deepwater_habitat_presentbooleanTrue when a Cowardin deepwater habitat (Lacustrine Limnetic, Marine or Estuarine Subtidal, or perennial Riverine channel) is mapped within the radius. Deepwater habitats are waters of the United States rather than wetlands, and carry a different Section 404 posture.
excavated_or_impounded_presentbooleanTrue when a mapped feature carries an Excavated, Diked/Impounded, Artificial Substrate, Spoil or Artificially Flooded modifier.
farmed_or_drained_presentbooleanTrue when a mapped feature carries a Farmed or Partially Drained/Ditched modifier. Prior-converted cropland may be excluded from Section 404 jurisdiction.
jurisdictional_likelihoodstringScreening-level likelihood that a Section 404 water is present at or beside the site: high, moderate, low, or none_mapped. NULL when any contributing query was unavailable. Read jurisdictional_basis for the reasoning. Not a jurisdictional determination.
jurisdictional_basisarrayThe specific facts that produced jurisdictional_likelihood, one sentence each - the audit trail a reviewer can check.
delineation_recommendedbooleanTrue when the screen indicates a formal wetland delineation is warranted before ground disturbance. NULL when the screen could not be completed.
section_404_basisarrayThe specific facts behind section_404_flag, including the caveat that a false flag applies only to the stated radius.

Every field is nullable. null means not checked; false means checked and negative.

How the answer is produced

  1. Layer health check (live, every run). The layer must still expose the fully-qualified Wetlands.* columns and at least 20 NWI_Wetland_Codes.* join columns. If the join is dropped, the Cowardin decode would silently render null on every row - so the run fails instead.
  2. Canary (live, every run). A point inside Reelfoot Lake, TN must read back a Cowardin code, over 100 acres, a populated SYSTEM_NAME, and a join whose SYSTEM agrees with the first letter of the code. This catches an emptied layer, a broken join, and a join keyed to the wrong column. It is exactly the assertion that would have caught the July 2026 NWI outage on the first run instead of after a month on hold.
  3. Point-in-polygon at the coordinate (with the distance parameter omitted - distance=0 returns objectIds: null on this service).
  4. Exact count for the circle, then every page of features, following exceededTransferLimit.
  5. Nearest wetland: 0 m if the site is inside a polygon; otherwise the buffer distance is bisected server-side to bracket the true edge, the winning polygon is identified, and its generalized boundary is fetched in WGS84 and measured. A failed geometry read degrades to the bracket and says so - it never becomes a guess.

Reliability, stated plainly

  • Every source records its own outcome on the row (onsite_query_status, radius_query_status, nearest_query_status, nwi_status).
  • section_404_flag, jurisdictional_likelihood, wetland_on_site and every presence flag are gated: they read null when a contributing query did not answer. A dead upstream can never render as "no wetland found".
  • A truncated fetch nulls total_acres_within_radius and the per-system acreage rather than publishing a sum over an arbitrary subset - while still reporting the exact server-side count.
  • If every screened site fails, the run fails and pushes nothing at all - not one error row - so nothing is billed. Rows are buffered in memory and the billing decision is made before the first pushData, because Apify charges for dataset items even on a run that ends FAILED. A partial failure is different: every row is still emitted, including the ones that failed, so you can see exactly which sites are missing and why.
  • An asset whose coordinates cannot be parsed is your input, not an outage: on an otherwise healthy run it comes back as a normal error row. If the upstream is dead as well, those rows are withheld too.
  • The geometry guard checks the declared spatial reference and coordinate magnitude (|lon| <= 180), bounded by each feature's own envelope. A legitimately enormous coastal polygon passes; Web Mercator metres do not.

Use as an MCP tool

This Actor is callable directly by any MCP-compatible AI agent through Apify's hosted MCP server. There is no server to run and no integration code to write - the tool schema an agent sees is generated from this Actor's own input and dataset schemas.

Endpoint

https://mcp.apify.com?tools=malonestar/fws-wetlands-proximity-screener

Claude Desktop, Claude Code or Cursor - add to claude_desktop_config.json, .mcp.json or .cursor/mcp.json respectively:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=malonestar/fws-wetlands-proximity-screener",
"headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }
}
}
}

Get a token at https://console.apify.com/settings/integrations. Claude Desktop can also authenticate interactively via OAuth against https://mcp.apify.com with no headers block. Full reference: https://docs.apify.com/platform/integrations/mcp

Try asking your agent

Are there NWI-mapped wetlands within 300 m of 39.7392,-104.9903, and how far is the nearest one?

Chains well with - expose these alongside it by comma-separating the tools parameter, and the agent can carry results from one into the next:

  • malonestar/nhd-surface-water-404-screener
  • malonestar/epa-contaminated-site-screener
  • malonestar/site-due-diligence-bundle
https://mcp.apify.com?tools=malonestar/fws-wetlands-proximity-screener,malonestar/nhd-surface-water-404-screener,malonestar/epa-contaminated-site-screener,malonestar/site-due-diligence-bundle

Billing is unchanged when called as an MCP tool: this Actor is Pay-Per-Event and an agent pays the same per-result price a human does. A run that cannot answer fails without billing rather than returning an unverified negative.

Pricing

$8 per 1,000 results (pay per event, Result only). One result = one screened site, whether or not a wetland is found - a verified "no wetland within 500 m, nearest is 1,391 m north" is the answer you paid for. Graduated discounts apply on paid Apify plans (Bronze -20% through Diamond -70%). There are no custom charge events.

ActorWhy you want it alongside this one
NHD Surface Water & Section 404 ScreenerThe surface-water half of the same question. This actor covers NWI wetlands; that one covers NHD streams, rivers, ponds and washes with relative-permanence proxies. Run both for a complete Section 404 picture - a site can be clear of mapped wetlands and still sit on a jurisdictional tributary.
EPA Impaired Waters (303d) ScreenerOnce you know a water is present, this tells you whether it is listed as impaired - which changes permitting conditions.
NOAA Essential Fish Habitat Consultation ScreenerThe marine/estuarine consultation trigger under Magnuson-Stevens 305(b)(2), for coastal sites this actor flags as Estuarine or Marine.
USFWS Critical Habitat ScreenerESA Section 7 exposure at the same coordinates.
EPA Contaminated Site ScreenerThe other standard Phase I ESA line item: Superfund, RCRA, USTs and enforcement history.
Site Due Diligence BundleTwenty layers including this one, for a single coordinate, with a composite site score.

FAQ

Is this a wetland delineation? No. NWI is a remote-sensing-derived inventory at roughly 1:12,000 to 1:24,000 scale. It is the accepted desktop screen and the starting point for a delineation - delineation_recommended is the field that tells you when to order one.

Why is section_404_flag false but nearest_wetland_distance_m only 600 m? Because the flag answers your radiusMeters question and nothing else. section_404_basis says so on the row. Widen radiusMeters if 600 m matters to you.

Why is a field null instead of false? null means the query that would have answered it did not complete. false means it completed and the answer was negative. The two are never interchangeable here.

What does distance_method tell me? How the distance was obtained: point_in_polygon (exact 0), geometry_measured (measured against the polygon boundary, tolerance published), ring_bisection (bracketed by server-side queries, upper bound reported), none_within_search_radius, skipped or unavailable. A proxy is never reported as a measurement.

Does it cover Alaska, Hawaii and the territories? NWI coverage is national including AK, HI, PR and the Pacific territories, though mapping vintage and detail vary by region. The actor reports what the service returns.

How current is the data? The NWI is updated continuously by USFWS as new mapping is published; there is no per-polygon date in the service, so the actor reports checked_at (when it asked) rather than implying a data vintage it cannot see.

Source: USFWS National Wetlands Inventory, fwspublicservices.wim.usgs.gov/wetlandsmapservice/rest/services/Wetlands/MapServer/0. Public domain, keyless.