NHD Surface Water & Section 404 Wetland Screener
Pricing
from $6.60 / 1,000 results
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
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.
| FCode | Regime | Raises the 404 flag? |
|---|---|---|
| 46006 | Perennial stream | Yes |
| 46003 | Intermittent stream | Yes |
| 46000 | Stream/river, unspecified | Yes |
| 55800 | Artificial path (mapped centerline of a river or lake) | Yes |
| 46007 | Ephemeral wash | No |
| 33600 / 33601 / 33603 | Canal / ditch / aqueduct / stormwater | No |
| 42800–42824 | Pipeline | No |
| 42000–42003 | Underground conduit | No |
| 46800 | Drainageway | No |
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 delineators —
nearest_swamp_marsh_dist_mis NHD's wetland proxy and the strongest single signal that a formal delineation is in scope; the per-regime feature census (perennial_features_in_radiusand 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_cfsis 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
| Field | Meaning |
|---|---|
asset_label | Your own label for the site, echoed verbatim so results join back to your parcel list |
lat | Site latitude in decimal degrees (WGS84/NAD83); null on a row whose input coordinate was unusable |
lon | Site longitude in decimal degrees (negative in the USA) |
search_radius_m | Radius in metres actually searched around the site for flowlines, waterbodies and water areas |
Verdict and audit trail
| Field | Meaning |
|---|---|
section_404_review_flag | HIGH / MEDIUM / LOW, or null when a contributing layer did not answer |
section_404_flag_status | complete, positive_despite_partial_coverage, indeterminate_partial_coverage, indeterminate_probe_failure, not_screened |
section_404_flag_reason | Why the flag was suppressed or qualified; null on a clean row |
jurisdictional_likelihood | LIKELY / POSSIBLE / UNLIKELY / INDETERMINATE — a screening opinion, not a determination |
jurisdiction_basis | Full reasoning: which feature, at what distance, with what flow, and what was excluded |
nearest_jurisdictional_dist_m | The distance the flag bands were actually applied to, in metres |
nearest_jurisdictional_dist_ft | The same distance in feet |
nearest_jurisdictional_source | Whether a flowline or a polygon drove the flag |
nearest_jurisdictional_name | Name of the feature that drove the flag |
nearest_jurisdictional_type | Type of the feature that drove the flag |
Nearest flowline
| Field | Meaning |
|---|---|
nearest_flowline_name | Nearest reach of any type; falls back to reach code — never blank |
nearest_flowline_ftype | Decoded NHD FType of that reach |
nearest_flowline_fcode | Raw numeric NHD FCode |
nearest_flowline_fcode_label | The verbatim USGS FCode description, straight from the layer's coded-value domain |
flow_regime | perennial / intermittent / ephemeral / artificial_path / canal_ditch / pipeline / underground_conduit / … |
nearest_flowline_is_jurisdictional | Whether that reach is of a type that can raise the flag |
nearest_flowline_dist_m | Distance to that reach in metres |
nearest_flowline_dist_ft | Distance to that reach in feet |
nearest_flowline_layer | 3 (network, carries NHDPlus VAA) or 4 (non-network, no flow/order/drainage data exists) |
mean_annual_flow_cfs | NHDPlus qama — the relative-permanence proxy |
mean_annual_velocity_fps | NHDPlus vama |
reach_slope | Smoothed NHDPlus slope for the reach |
stream_order | Strahler stream order |
drainage_area_sqkm | Total upstream drainage area |
total_upstream_length_km | Arbolate sum — total upstream network length |
is_headwater | Network start — nothing upstream |
reachcode | NHD reach code, to cite in a permit or delineation |
nearest_flowline_gnis_id | GNIS identifier of the named reach |
nearest_flowline_length_km | Length of the mapped reach |
nearest_flowline_data_date | Vintage of the mapped feature |
nhd_resolution | Source resolution of the mapped feature |
Flow-regime distances and census
| Field | Meaning |
|---|---|
nearest_perennial_dist_m / nearest_perennial_dist_ft | Nearest FCode 46006, metres and feet |
nearest_intermittent_dist_m / nearest_intermittent_dist_ft | Nearest FCode 46003, metres and feet |
nearest_ephemeral_dist_m / nearest_ephemeral_dist_ft | Nearest FCode 46007 — reported, never flagged |
nearest_canal_ditch_dist_m | Nearest ditch or canal — reported, never flagged |
perennial_features_in_radius | Perennial reaches within the radius |
intermittent_features_in_radius | Intermittent reaches within the radius |
ephemeral_features_in_radius | Ephemeral reaches within the radius |
canal_ditch_features_in_radius | Canals and ditches within the radius |
pipeline_conduit_features_in_radius | Pipelines and underground conduits within the radius |
flowline_features_in_radius | All flowlines within the radius |
waterbody_features_in_radius | All waterbody polygons within the radius |
surface_water_features_in_radius | Every surface-water feature within the radius — the density signal a delineation scope is priced from |
Waterbodies and wetlands
| Field | Meaning |
|---|---|
nearest_waterbody_name | Nearest polygon of any type — which on an arid site is often a wash |
nearest_waterbody_type | Decoded type of that polygon |
nearest_waterbody_dist_m / nearest_waterbody_dist_ft | Distance to it, metres and feet |
nearest_waterbody_area_sqkm | Mapped area of that polygon |
nearest_waterbody_fcode | Raw numeric NHD FCode of the polygon |
nearest_waterbody_fcode_label | Verbatim USGS FCode description for the polygon |
nearest_waterbody_purpose | NHDPlus purpose code (tailings, settling, sewage treatment, cooling, evaporator, disposal, …) |
nearest_waterbody_reachcode | Reach code of the polygon, where NHD carries one |
nearest_waterbody_data_date | Vintage of the polygon |
nearest_waterbody_layer | Which source layer the polygon came from (NHDWaterbody or NHDArea) |
nearest_waterbody_is_jurisdictional | Whether that polygon can raise the flag |
site_inside_waterbody | The site coordinate falls inside the polygon |
nearest_jurisdictional_waterbody_name | Nearest polygon that can raise the flag |
nearest_jurisdictional_waterbody_type | Its decoded type |
nearest_jurisdictional_waterbody_dist_m | Distance to it in metres |
nearest_swamp_marsh_dist_m | Nearest NHD Swamp/Marsh (FType 466) — the wetland-delineation trigger |
nearest_swamp_marsh_name | Name of that swamp or marsh, falling back to its NHD identifier |
nearest_lake_pond_dist_m | Nearest lake or pond |
nearest_reservoir_dist_m | Nearest reservoir |
nearest_reservoir_type | Reservoir type: tailings pond, settling pond, sewage treatment pond, cooling pond, evaporator, disposal and so on |
nearest_wash_playa_dist_m | Nearest wash or playa — reported for transparency, deliberately excluded from the flag |
Watershed
| Field | Meaning |
|---|---|
huc8 | Subbasin — what most permit forms ask for |
huc10 | Watershed |
huc12 | Subwatershed |
huc12_name | Subwatershed name |
tohuc | The HUC12 this subwatershed drains into |
tohuc_is_terminal | Whether the outlet is terminal (OCEAN, CANADA, MEXICO) |
huc12_type | Standard, Closed Basin, Frontal, Multiple Outlet, Water, Island, Urban, Indeterminate |
huc12_area_sqkm | Subwatershed area |
huc12_noncontributing_area_sqkm | The part of it that does not drain to its outlet |
Coverage and QA
| Field | Meaning |
|---|---|
screening_status | complete / partial / failed |
layer_network_flowline_status | ok / unavailable / not_requested for NetworkNHDFlowline |
layer_nonnetwork_flowline_status | Same, for NonNetworkNHDFlowline |
layer_waterbody_status | Same, for NHDWaterbody |
layer_nhdarea_status | Same, for NHDArea |
layer_wbdhu12_status | Same, for WBDHU12 |
layers_ok | How many of the five layers answered |
layers_unavailable | Which ones did not |
distance_method | exact_geometry, ring_probe_bound, no_features_in_radius, unavailable |
unmapped_codes | Any NHD code USGS returned that this actor does not decode — surfaced, never dropped |
error | Null on a clean row; reason or PARTIAL: notice otherwise |
source_url | The exact query used |
retrieved_at | UTC 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:
- 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;
- 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;
- 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:
- every layer id still maps to its expected layer name (a USGS renumbering
would otherwise make the actor query
FlowDirectionand call it "flowlines"); - the flowline FCode subtype domain still carries 46003 / 46006 / 46007, the codes the whole perennial / intermittent / ephemeral split rests on;
- 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/totdasqkmsurfaces as a red run instead of a column that quietly renders null on every row; - 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
AbortControllertimeout and retries with exponential backoff on 408/425/429/5xx. - Missing or empty
assetsis 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, anullflag andscreening_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
exceededTransferLimitwithresultOffsetpagination.
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.
Related actors
Section 404 exposure is one layer of a site screen. These share the same
[{lat, lon, label}] input shape and join on asset_label:
| Actor | What it adds |
|---|---|
fws-wetlands-proximity-screener | USFWS 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-screener | Whether 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-screener | Superfund, RCRA, USTs, NPDES and enforcement history for the ASTM E1527-21 recognised-environmental-conditions section of the same Phase I. |
site-due-diligence-bundle | All 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. |