NHD Surface Water & Section 404 Wetland Screener avatar

NHD Surface Water & Section 404 Wetland Screener

Pricing

from $6.60 / 1,000 results

Go to Apify Store
NHD Surface Water & Section 404 Wetland Screener

NHD Surface Water & Section 404 Wetland Screener

Screen any lat/lon against USGS NHDPlus HR surface water. 94 fields: exact distance to the nearest perennial, intermittent and ephemeral reach, waterbody type and purpose, mean annual flow, stream order, HUC-8/10/12, a jurisdictional-likelihood call with its reasoning, and a Section 404/WOTUS flag.

Pricing

from $6.60 / 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

a day ago

Last modified

Share

NHD Surface Water & Section 404 Screener

Give it a list of site coordinates. Get back, per site, the answer that drives a Clean Water Act call: how far is the nearest perennial stream, versus the nearest intermittent one, versus the nearest ephemeral wash — plus the mean annual flow on that reach, the nearest lake, reservoir or swamp/marsh, the stream order and drainage area of the receiving water, the HUC8/10/12 the site drains through, and a HIGH / MEDIUM / LOW Section 404 review flag that tells you which feature drove it and why.

Data comes from the USGS NHDPlus HR MapServer (hydro.nationalmap.gov/arcgis/rest/services/NHDPlus_HR/MapServer) — keyless, public-domain, no login, no scraping of a rendered page.


Why the perennial / intermittent / ephemeral split matters

Most surface-water tools dump every NHD flowline within a buffer and leave you to sort it out. After Sackett v. EPA (2023) the jurisdictional question turns on relatively permanent flow with a continuous surface connection, so this actor does the sorting — and reports the evidence.

FCodeRegimeRaises the 404 flag?
46006Perennial streamYes
46003Intermittent streamYes
46000Stream/river, unspecifiedYes
55800Artificial path (mapped centerline of a river or lake)Yes
46007Ephemeral washNo
33600 / 33601 / 33603Canal / ditch / aqueduct / stormwaterNo
42800–42824PipelineNo
42000–42003Underground conduitNo
46800DrainagewayNo

Polygons are treated the same way. Lakes, ponds, reservoirs, swamp/marsh, estuaries, bays, foreshore, rapids and submerged streams raise the flag. Washes (FType 484), playas, ice masses, ditch polygons and engineered structures — levees, bridges, dams, spillways, lock chambers, flumes, water intake/outflow, mapped inundation areas — do not. They are still reported, in their own columns, so you can see what was excluded and why.

Flag bands: HIGH = a jurisdictional feature within 100 ft (30.48 m). MEDIUM = within 300 ft (91.44 m). LOW = everything else.

A site genuinely far from mapped water is a legitimate result: you get a row with null distances, LOW, and jurisdictional_likelihood: UNLIKELY — not an error and not a missing row.

The flag can also be null, and that is the point

section_404_review_flag is null whenever a contributing NHD layer did not answer for that site. A LOW or MEDIUM verdict asserts that nothing jurisdictional lies within 100 ft; if the waterbody layer never responded, that negative was never verified, and shipping it as LOW would be a confident wrong answer on a determination that carries liability. A HIGH is different — a positive finding cannot be reversed by missing data — so a HIGH stands and is marked positive_despite_partial_coverage.

Every row carries screening_status, layers_ok, layers_unavailable, a layer_*_status per NHD layer, and section_404_flag_reason in plain English. Filter on screening_status = "complete" before acting on any negative finding. If the load-bearing flowline layer is down for every site, the run fails rather than emitting rows — nothing is emitted and nothing is billed.


Who buys this

  • Phase I ESA consultants — the surface-water and adjacent-waters section of an ASTM E1527-21 report, with a citable reach code, the NHD feature date, and a date-of-source stamp for every row.
  • Wetland delineatorsnearest_swamp_marsh_dist_m is NHD's wetland proxy and the strongest single signal that a formal delineation is in scope; the per-regime feature census (perennial_features_in_radius and friends) is what you price the field effort from.
  • §404 / Clean Water Act permitting teams — first-pass triage of which parcels need a delineation and an approved jurisdictional determination before a Nationwide vs Individual Permit path is chosen. mean_annual_flow_cfs is the number a relative-permanence argument is actually built on.
  • Solar, BESS and data-center siting teams — rank hundreds of candidate parcels by 404 exposure before spending money on field work. The wash and ditch exclusions matter enormously in the arid south-west, where washes are the most common mapped NHDArea feature.
  • Land developers and title / diligence shops — flag creek-adjacent parcels across an acquisition pipeline in one run.

Example input

{
"assets": [
{ "lat": 40.0143, "lon": -105.2829, "label": "Boulder CO - creekside redevelopment parcel" },
{ "lat": 29.99091, "lon": -89.93323, "label": "New Orleans East LA - swamp/marsh adjacent site" },
{ "lat": 33.42931, "lon": -111.98414, "label": "Tempe AZ - parcel inside a mapped desert wash" },
{ "lat": 35.2, "lon": -115.9, "label": "Mojave NP CA - upland solar reference site" }
],
"radiusMeters": 1000,
"maxResults": 100,
"includeNonNetworkFlowlines": true
}

assets is required — the run is rejected before it starts if it is missing, not an array, or empty, so nothing is consumed. lat/lon are decimal degrees (latitude/longitude and lng are accepted as aliases). radiusMeters is clamped to 50–8000, default 1600.

Those four prefilled sites deliberately cover the range of outcomes: a creekside parcel 5.2 m from a perennial reach carrying 102.7 cfs (HIGH, LIKELY); a Louisiana site sitting inside an NHD swamp/marsh (HIGH, wetland-driven); an Arizona parcel sitting inside a 2.54 km² mapped desert wash, which comes back LOW because washes are reported but are not jurisdictional after Sackett (the nearest actually-jurisdictional feature is the Salt River at 101 m, just outside the 300 ft band); and an upland Mojave parcel whose only nearby feature is an ephemeral reach 258 m away (LOW, UNLIKELY).

Example output row (trimmed)

{
"asset_label": "Boulder CO - creekside redevelopment parcel",
"lat": 40.0143,
"lon": -105.2829,
"search_radius_m": 1000,
"section_404_review_flag": "HIGH",
"section_404_flag_status": "complete",
"jurisdictional_likelihood": "LIKELY",
"jurisdiction_basis": "A perennial reach lies 5.2 m (17.2 ft) from the site, inside the 100 ft band. NHDPlus reports a mean annual flow of 102.69 cfs on that reach, which supports a relatively permanent flow characterisation under Sackett v. EPA. A canal or ditch lies 364.4 m away and was excluded from the flag.",
"nearest_jurisdictional_source": "flowline",
"nearest_jurisdictional_name": "Boulder Creek",
"nearest_jurisdictional_dist_m": 5.2,
"nearest_jurisdictional_dist_ft": 17.2,
"nearest_flowline_name": "Boulder Creek",
"flow_regime": "perennial",
"nearest_flowline_fcode_label": "Stream/River: Hydrographic Category = Perennial",
"nearest_flowline_dist_m": 5.2,
"mean_annual_flow_cfs": 102.689,
"mean_annual_velocity_fps": 1.6366,
"stream_order": 6,
"drainage_area_sqkm": 336.052,
"total_upstream_length_km": 705.632,
"reachcode": "10190005000085",
"nearest_flowline_data_date": "2012-02-18",
"nearest_perennial_dist_m": 5.2,
"nearest_intermittent_dist_m": 412.6,
"nearest_ephemeral_dist_m": null,
"perennial_features_in_radius": 4,
"intermittent_features_in_radius": 2,
"canal_ditch_features_in_radius": 6,
"nearest_waterbody_name": "Varsity Lake",
"nearest_waterbody_type": "Lake/Pond (perennial, closed lake)",
"nearest_waterbody_dist_m": 839.6,
"nearest_waterbody_is_jurisdictional": true,
"nearest_swamp_marsh_dist_m": null,
"huc8": "10190005",
"huc10": "1019000504",
"huc12": "101900050406",
"huc12_name": "City of Boulder-Boulder Creek",
"huc12_type": "Standard",
"tohuc": "101900050601",
"screening_status": "complete",
"layers_ok": 5,
"layers_unavailable": null,
"distance_method": "exact_geometry",
"error": null,
"source_url": "https://hydro.nationalmap.gov/.../MapServer/3/query?...",
"retrieved_at": "2026-07-28T18:24:57.974Z"
}

Output fields

All 94 fields are listed below — every field this actor declares, named in full. Distances are reported in metres and in feet; the _ft column is the exact same measurement, converted, so a permit form and a US survey can both be filled straight from the row.

Your site, echoed back

FieldMeaning
asset_labelYour own label for the site, echoed verbatim so results join back to your parcel list
latSite latitude in decimal degrees (WGS84/NAD83); null on a row whose input coordinate was unusable
lonSite longitude in decimal degrees (negative in the USA)
search_radius_mRadius in metres actually searched around the site for flowlines, waterbodies and water areas

Verdict and audit trail

FieldMeaning
section_404_review_flagHIGH / MEDIUM / LOW, or null when a contributing layer did not answer
section_404_flag_statuscomplete, positive_despite_partial_coverage, indeterminate_partial_coverage, indeterminate_probe_failure, not_screened
section_404_flag_reasonWhy the flag was suppressed or qualified; null on a clean row
jurisdictional_likelihoodLIKELY / POSSIBLE / UNLIKELY / INDETERMINATE — a screening opinion, not a determination
jurisdiction_basisFull reasoning: which feature, at what distance, with what flow, and what was excluded
nearest_jurisdictional_dist_mThe distance the flag bands were actually applied to, in metres
nearest_jurisdictional_dist_ftThe same distance in feet
nearest_jurisdictional_sourceWhether a flowline or a polygon drove the flag
nearest_jurisdictional_nameName of the feature that drove the flag
nearest_jurisdictional_typeType of the feature that drove the flag

Nearest flowline

FieldMeaning
nearest_flowline_nameNearest reach of any type; falls back to reach code — never blank
nearest_flowline_ftypeDecoded NHD FType of that reach
nearest_flowline_fcodeRaw numeric NHD FCode
nearest_flowline_fcode_labelThe verbatim USGS FCode description, straight from the layer's coded-value domain
flow_regimeperennial / intermittent / ephemeral / artificial_path / canal_ditch / pipeline / underground_conduit / …
nearest_flowline_is_jurisdictionalWhether that reach is of a type that can raise the flag
nearest_flowline_dist_mDistance to that reach in metres
nearest_flowline_dist_ftDistance to that reach in feet
nearest_flowline_layer3 (network, carries NHDPlus VAA) or 4 (non-network, no flow/order/drainage data exists)
mean_annual_flow_cfsNHDPlus qama — the relative-permanence proxy
mean_annual_velocity_fpsNHDPlus vama
reach_slopeSmoothed NHDPlus slope for the reach
stream_orderStrahler stream order
drainage_area_sqkmTotal upstream drainage area
total_upstream_length_kmArbolate sum — total upstream network length
is_headwaterNetwork start — nothing upstream
reachcodeNHD reach code, to cite in a permit or delineation
nearest_flowline_gnis_idGNIS identifier of the named reach
nearest_flowline_length_kmLength of the mapped reach
nearest_flowline_data_dateVintage of the mapped feature
nhd_resolutionSource resolution of the mapped feature

Flow-regime distances and census

FieldMeaning
nearest_perennial_dist_m / nearest_perennial_dist_ftNearest FCode 46006, metres and feet
nearest_intermittent_dist_m / nearest_intermittent_dist_ftNearest FCode 46003, metres and feet
nearest_ephemeral_dist_m / nearest_ephemeral_dist_ftNearest FCode 46007 — reported, never flagged
nearest_canal_ditch_dist_mNearest ditch or canal — reported, never flagged
perennial_features_in_radiusPerennial reaches within the radius
intermittent_features_in_radiusIntermittent reaches within the radius
ephemeral_features_in_radiusEphemeral reaches within the radius
canal_ditch_features_in_radiusCanals and ditches within the radius
pipeline_conduit_features_in_radiusPipelines and underground conduits within the radius
flowline_features_in_radiusAll flowlines within the radius
waterbody_features_in_radiusAll waterbody polygons within the radius
surface_water_features_in_radiusEvery surface-water feature within the radius — the density signal a delineation scope is priced from

Waterbodies and wetlands

FieldMeaning
nearest_waterbody_nameNearest polygon of any type — which on an arid site is often a wash
nearest_waterbody_typeDecoded type of that polygon
nearest_waterbody_dist_m / nearest_waterbody_dist_ftDistance to it, metres and feet
nearest_waterbody_area_sqkmMapped area of that polygon
nearest_waterbody_fcodeRaw numeric NHD FCode of the polygon
nearest_waterbody_fcode_labelVerbatim USGS FCode description for the polygon
nearest_waterbody_purposeNHDPlus purpose code (tailings, settling, sewage treatment, cooling, evaporator, disposal, …)
nearest_waterbody_reachcodeReach code of the polygon, where NHD carries one
nearest_waterbody_data_dateVintage of the polygon
nearest_waterbody_layerWhich source layer the polygon came from (NHDWaterbody or NHDArea)
nearest_waterbody_is_jurisdictionalWhether that polygon can raise the flag
site_inside_waterbodyThe site coordinate falls inside the polygon
nearest_jurisdictional_waterbody_nameNearest polygon that can raise the flag
nearest_jurisdictional_waterbody_typeIts decoded type
nearest_jurisdictional_waterbody_dist_mDistance to it in metres
nearest_swamp_marsh_dist_mNearest NHD Swamp/Marsh (FType 466) — the wetland-delineation trigger
nearest_swamp_marsh_nameName of that swamp or marsh, falling back to its NHD identifier
nearest_lake_pond_dist_mNearest lake or pond
nearest_reservoir_dist_mNearest reservoir
nearest_reservoir_typeReservoir type: tailings pond, settling pond, sewage treatment pond, cooling pond, evaporator, disposal and so on
nearest_wash_playa_dist_mNearest wash or playa — reported for transparency, deliberately excluded from the flag

Watershed

FieldMeaning
huc8Subbasin — what most permit forms ask for
huc10Watershed
huc12Subwatershed
huc12_nameSubwatershed name
tohucThe HUC12 this subwatershed drains into
tohuc_is_terminalWhether the outlet is terminal (OCEAN, CANADA, MEXICO)
huc12_typeStandard, Closed Basin, Frontal, Multiple Outlet, Water, Island, Urban, Indeterminate
huc12_area_sqkmSubwatershed area
huc12_noncontributing_area_sqkmThe part of it that does not drain to its outlet

Coverage and QA

FieldMeaning
screening_statuscomplete / partial / failed
layer_network_flowline_statusok / unavailable / not_requested for NetworkNHDFlowline
layer_nonnetwork_flowline_statusSame, for NonNetworkNHDFlowline
layer_waterbody_statusSame, for NHDWaterbody
layer_nhdarea_statusSame, for NHDArea
layer_wbdhu12_statusSame, for WBDHU12
layers_okHow many of the five layers answered
layers_unavailableWhich ones did not
distance_methodexact_geometry, ring_probe_bound, no_features_in_radius, unavailable
unmapped_codesAny NHD code USGS returned that this actor does not decode — surfaced, never dropped
errorNull on a clean row; reason or PARTIAL: notice otherwise
source_urlThe exact query used
retrieved_atUTC run timestamp

How the distances are computed

Exact point-to-polyline and point-to-polygon distance from the geometry USGS returns, in WGS84, with an equirectangular projection anchored at your site (sub-metre accurate over kilometres). A site inside a polygon is distance 0.

If NHD ever returns features without geometry, no exact distance exists. The actor then falls back to attribute-only ring probes at exactly 30.48 m and 91.44 m to decide the band honestly, sets distance_method to ring_probe_bound, and leaves every *_dist_m field null — because a probe gives you a bound, not a distance, and reporting a bound as a distance would be a fabricated number.

The projection trap, and the live assertion that guards it

NHDPlus HR answers in Web Mercator (wkid 102100) by default. Without an explicit outSR=4326 every coordinate comes back as metres-from-Greenwich, and every distance derived from it is wrong by orders of magnitude while looking entirely plausible. An offline test cannot catch that, because the fixture would have been shaped from the bad data.

So every geometry-bearing response is checked at runtime, on three independent signals. If any of them fails the run fails loudly rather than emitting distances:

  1. the declared spatial reference is 4326 — the real signal, and the only one of the three that also catches a near-identical datum swap such as NAD83 / 4269, where every coordinate still looks correct;
  2. every vertex is a possible WGS84 coordinate by magnitude (longitude within ±180, latitude within ±90). Web Mercator is metres, so an x of ≈ −11,721,894 fails this instantly and unambiguously;
  3. each returned feature's own bounding envelope is within a metre allowance (3× the search radius, 5 km floor) of the queried point — which catches a response describing the wrong place.

Coastal note (fixed 2026-07-28, build 1.1.7). Signal 3 used to be "every returned vertex must be within about a degree of the site", and that is simply false on an open coast. NHDArea layer 8 models the Gulf of Mexico as a single 364,494-vertex polygon spanning lon −89.861 … −88.013 / lat 29.250 … 30.433 (10,021 km²), so a perfectly valid WGS84 response at a Biloxi MS waterfront parcel contained the real vertex [−89, 29.25] — 130 km south of the site — and the run hard-failed with a false "projection drift". Every open-coast, bay, sound and large-lake site was unscreenable. A large polygon legitimately has distant vertices; what it may not do is have its entire extent sit far from the point the buffer was drawn around, which is what the envelope test now asserts. The Mercator case is caught by magnitude, where it always belonged.

Four more live checks run once, before any site is screened, and fail the run if they trip:

  1. every layer id still maps to its expected layer name (a USGS renumbering would otherwise make the actor query FlowDirection and call it "flowlines");
  2. the flowline FCode subtype domain still carries 46003 / 46006 / 46007, the codes the whole perennial / intermittent / ephemeral split rests on;
  3. a fixed canary query at Boulder Creek still returns features, in 4326, near the canary point, with NHDPlus value-added attributes attached — so a silent loss of qama / streamorde / totdasqkm surfaces as a red run instead of a column that quietly renders null on every row;
  4. NHDArea FType 484 (Wash) still exists, since the non-jurisdictional wash handling depends on it.

Use as an MCP tool

This actor is available over the Apify MCP server, so an AI agent (Claude Desktop, Claude Code, Cursor, or any MCP client) can call it directly. Point your MCP client at https://mcp.apify.com and expose the actor malonestar/nhd-surface-water-404-screener. A prompt like "screen these twelve parcel coordinates for Section 404 exposure and tell me which need a wetland delineation" becomes one tool call returning structured rows. Field-level descriptions in the output schema are written for an agent to read, and jurisdiction_basis gives the agent the reasoning to quote back.


Reliability

  • Every request has a 45 s AbortController timeout and retries with exponential backoff on 408/425/429/5xx.
  • Missing or empty assets is rejected by the input schema before the run starts, so nothing is consumed.
  • Per-layer failures are recorded on the row, not just in the log, and a negative verdict is suppressed rather than asserted over missing data.
  • If some assets resolve and others fail, the failures come back as rows carrying an error, a null flag and screening_status: "failed" — good rows are never discarded, and a failed site never reads as clear.
  • The run fails outright when nothing can be answered at all, and then nothing is emitted and nothing is billed.
  • The 2000-record page cap is handled by following exceededTransferLimit with resultOffset pagination.

FAQ

How do I find the nearest perennial stream to a property? Pass the property's latitude and longitude in assets. The row's nearest_perennial_dist_m is the distance in metres to the nearest NHD FCode 46006 reach, and nearest_flowline_name / reachcode identify it.

What is the difference between perennial, intermittent and ephemeral streams in NHD? NHD encodes it in the FCode: 46006 perennial (flows year-round), 46003 intermittent (flows seasonally), 46007 ephemeral (flows only in direct response to precipitation). This actor returns the distance to the nearest of each, and only the first two can raise the review flag.

Do I need a Section 404 permit for my project site? This actor gives you the screening inputs, not the legal determination. A HIGH flag means a relatively permanent water is within 100 ft and a wetland delineation plus an approved jurisdictional determination is the normal next step. Only the US Army Corps of Engineers can make the actual call.

Are ephemeral streams jurisdictional after Sackett v. EPA? Generally no — which is exactly why this actor reports ephemeral distances separately and does not let them raise the review flag. The same applies to ditches, washes and playas.

Why did a desert site come back LOW when it is sitting in a wash? Because a wash (NHD FType 484) is an ephemeral feature and is generally not a water of the United States after Sackett. The wash is still reported — see nearest_wash_playa_dist_m, nearest_waterbody_type and nearest_waterbody_is_jurisdictional — it just does not raise the flag.

What does mean_annual_flow_cfs tell me? It is NHDPlus's modelled mean annual flow for that reach in cubic feet per second, and it is the best openly available proxy for the relatively permanent flow test. A reach carrying 100 cfs supports a very different argument from one carrying 0.07 cfs. It is null when the nearest reach came from the non-network layer, which does not carry NHDPlus attributes at all.

Why is section_404_review_flag sometimes null? Because one of the NHD layers did not answer for that site, so a LOW or MEDIUM would be asserting a negative that was never verified. Check layers_unavailable and section_404_flag_reason, and re-run when the USGS service is healthy.

Which HUC12 watershed is my site in, and where does it drain? huc12 and huc12_name give the containing subwatershed from the Watershed Boundary Dataset; tohuc gives the HUC12 immediately downstream, and tohuc_is_terminal tells you when the outlet leaves the HUC network entirely. huc8 and huc10 are derived for the permit forms that ask for them.

How do I batch-screen a portfolio of parcels for wetland risk? Put all of them in assets in one run — one row comes back per parcel, including parcels with no nearby water. Sort by section_404_review_flag and nearest_swamp_marsh_dist_m, and filter to screening_status = "complete".

Is the USGS NHDPlus HR data free to use? Yes. It is US Government public-domain data served without an API key. This actor charges for the compute and the transform, and every row carries the exact source_url used so any number can be re-derived.


Pricing

Pay per result: $12 per 1,000 results. One result = one screened asset row. Rows emitted for assets that failed validation or could not be screened carry an error field and a null flag, so you can see exactly what was charged for. If nothing could be screened, the run fails and no result events are charged.


Section 404 exposure is one layer of a site screen. These share the same [{lat, lon, label}] input shape and join on asset_label:

ActorWhat it adds
fws-wetlands-proximity-screenerUSFWS National Wetlands Inventory polygons — the authoritative wetland mapping. NHD's Swamp/Marsh is a coarse proxy; NWI is what a delineation is scoped against. Run both.
epa-impaired-waters-303d-screenerWhether the receiving water you just identified is CWA §303(d) impaired, and for which pollutant — which drives TMDL and discharge-permit conditions.
epa-contaminated-site-screenerSuperfund, RCRA, USTs, NPDES and enforcement history for the ASTM E1527-21 recognised-environmental-conditions section of the same Phase I.
site-due-diligence-bundleAll twenty diligence layers for one coordinate in one call — contamination, wetlands, flood, seismic, habitat, historic, levee, karst and more — with a composite site score and a go / caution / no-go verdict.