Historic Land Use Screener - Contaminating SIC/NAICS Sites
Pricing
from $6.60 / 1,000 results
Historic Land Use Screener - Contaminating SIC/NAICS Sites
Screens a coordinate or address radius against EPA FRS SIC and NAICS classifications to find dry cleaners, gas stations, plating shops, auto shops, printers and other recognised contaminating land uses, for ASTM E1527-21 Section 8.3 prior-use review.
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
2 days ago
Last modified
Categories
Share
Give it a coordinate or an address. It returns the dry cleaners, gas stations, plating shops, auto body shops, printers, wood treaters, scrap yards and other recognised contaminating businesses inside the radius - identified by their reported industrial classification, with the contaminants of concern each land use implies and the published authority that says so.
This is the ASTM E1527-21 Section 8.3 "prior uses of the property" line item: what kind of business is, or was, operating here? It is a different question from the records review in Section 8.2, and it is the part Phase I consultants most often assemble by hand.
Who it is for
- Phase I ESA consultants and environmental professionals completing the prior-use section of an AAI-compliant report.
- CRE acquisition and lender due-diligence teams who need a fast, defensible read on whether a target parcel sits next to a solvent user before ordering a full Phase I.
- Environmental engineers scoping a Phase II: the contaminant list per land-use class tells you what to analyse for.
- Brownfield and redevelopment teams triaging a pipeline of sites.
- AI agents doing site due diligence - the output is flat, typed, and every claim carries its own status field.
What makes it different from a regulatory-database search
Most environmental screens answer "is this address on a federal list?" This one answers "what industry is operating here?" The two overlap far less than you would expect.
Measured live on 2026-08-18, comparing the facilities this actor finds against the facilities EPA's ECHO radius search returns at the same point and radius:
| Location | Contaminating facilities found here | Of those, invisible to a federal ECHO radius search |
|---|---|---|
| Newark, NJ (Ironbound), 0.5 mi | 38 | 21 (55%) |
| Van Nuys, CA, 0.5 mi | 15 | 10 (67%) |
| Denver, CO (CBD), 0.25 mi | 9 | 1 |
The gap is state program systems. EPA's Facility Registry Service unifies 97 program systems, roughly 40 of which are state environmental agency registers - NJ-NJEMS, CA-ENVIROVIEW, TX-TCEQ ACR, PA-EFACTS, MO-DNR, WA-FSIS, OR-DEQ, OH-CORE and others. A neighbourhood laundromat or auto shop that holds only a state registration is simply not in the federal compliance database. Nationally, 15,596 of the 35,836 dry-cleaning (SIC 7216) records - 43.5% - come from non-federal program systems.
It pairs with, and does not replace, epa-contaminated-site-screener. That actor answers Section 8.2 - Superfund/SEMS, RCRA, UST/LUST, brownfields, ECHO enforcement, NPL proximity. This one answers Section 8.3. Run both on the same coordinate for a complete records-plus-prior-use picture.
Example input
{"assets": [{ "lat": 39.7392, "lon": -104.9903, "label": "Denver CBD parcel (CO)" },{ "lat": 40.7274, "lon": -74.1590, "label": "Newark Ironbound parcel (NJ)" },{ "address": "1438 Tremont Pl, Denver, CO 80202", "label": "Address input example" }],"radiusMiles": 0.25,"maxFacilitiesPerAsset": 100}
Every property produces one facility row per contaminating land use found, plus one asset_summary row carrying the verdict and the coverage statistics behind it.
Optional inputs: programs (opt into the state / tribal equivalent record leg - see below), landUseClasses (limit to specific classes), includeSecondaryClassifications, includeUnclassifiedFacilities, crossStateRecords, coordinateStackThreshold, maxFacilitiesPerAsset, maxResults, simulateOutage.
maxResults must be at least the number of properties in assets, because every property gets its own summary row. See Correctness guarantees below.
The 24 contaminating land-use classes
Dry cleaning and commercial laundry - Fuel dispensing, bulk petroleum storage and distribution - Petroleum refining and crude oil / natural gas production - Metal plating, coating, anodizing and heat treating - Metal fabrication, foundries, smelting and machine shops - Automotive repair, body shops and vehicle maintenance - Scrap, salvage and waste-material recycling - Wood preserving and treating - Sawmills, millwork and reconstituted wood products - Commercial printing, publishing and platemaking - Chemical, paint, resin and pesticide manufacturing - Explosives, ordnance and munitions - Refuse systems, landfills and sanitary services - Printed circuit board, semiconductor and electronic component manufacture - Storage and primary battery manufacture - Leather tanning, textile finishing and coated fabrics - Gas manufacture / distribution and electric utility operations - Truck and rail terminals and maintenance yards - Airports, aviation services and aircraft maintenance - Photofinishing and photographic processing - Pest control and disinfecting services - Plastics and rubber products manufacture - Pulp and paper mills - National security and defence installations.
Each class carries its contaminants of concern on the row. Dry cleaning, for example, returns tetrachloroethene (PCE), trichloroethene (TCE), 1,1,1-trichloroethane, petroleum dry-cleaning solvent and the chlorinated-solvent degradation products.
Where the mapping comes from, and what it is not
The classification-to-contaminant crosswalk is a curated, versioned vocabulary (contaminant_mapping_version ships on every row). It is not a verbatim reproduction of any single agency list, and it is not a determination that contamination exists.
Every entry names the published authority that identifies the industry as a potential contaminant source, and that authority ships on the row in contaminant_mapping_authorities, contaminant_mapping_citation and contaminant_mapping_url:
- U.S. EPA Office of Compliance, Sector Notebook Project - per-industry profiles of process operations, waste streams and pollutant releases, indexed by SIC code.
- NJDEP Industrial Site Recovery Act, N.J.A.C. 7:26B - New Jersey defines an "industrial establishment" by the industry classification codes listed in the chapter's Appendix C, i.e. the classifications the State identifies as having the potential for discharge of hazardous substances.
Code titles are verbatim from their own authorities: SIC titles from the OSHA SIC Manual (1987), NAICS titles from the U.S. Census Bureau 2022 NAICS file.
What "historic" does and does not mean here
Read this before quoting the output in a report. EPA FRS publishes the industrial classification a facility currently reports to each program system. Every row says so in temporal_basis and temporal_basis_note.
- It is evidence of the reported business type of a facility that appears in the federal registry today, or was last reported on
record_last_reported_date. - It is not a title-chain search, a city-directory search, or a historical aerial-photograph review, and it does not establish what occupied the parcel before the facility was registered.
- The strongest former-use signal this dataset carries is
operational_status- a record marked terminated, expired or permanently closed, together withrecord_last_reported_date, indicates a use that has ended.
Use it as the systematic first pass over the Section 8.3 question, then close the remaining gap with directories, aerials and interviews.
Opt-in: state and tribal equivalent record sources (ASTM E1527-21 Section 8.2)
ASTM E1527-21 requires a search of state and tribal agency record sources alongside the federal ones. EPA already normalises a set of state and tribal agency program systems into the very registry this actor queries, so those records are reachable in the same run at no extra row cost.
Add "programs": ["state"] to switch the leg on. Leave it out and this actor behaves exactly as it did before the leg existed - same rows, same values, same requests. The leg adds two requests per distinct state in your run (not per property) and no extra rows; state findings are additional columns on the rows you were already getting.
{"assets": [{ "lat": 40.7274, "lon": -74.1590, "label": "Newark Ironbound parcel (NJ)" }],"programs": ["state"],"radiusMiles": 0.25}
Coverage is uneven, and that is the whole point of the contract
Measured 2026-08-20 across all 56 STATE_CODE values: twelve jurisdictions have ZERO state or tribal agency program system in EPA FRS - Alaska, Colorado, the District of Columbia, Michigan, South Dakota, Vermont, West Virginia, and the territories American Samoa, Guam, Northern Mariana Islands, Puerto Rico and the US Virgin Islands.
If a screening tool simply filtered the radius on "state systems" and found none, a Colorado buyer would receive a clean, billable "no state agency records near this property" that in fact means "EPA normalises no Colorado state agency records at all". On an ASTM deliverable that is not a missing feature, it is a wrong answer.
So every asset_summary row carries:
state_coverage-complete/partial/none, andnoneis a first-class outcome meaning this record class could not be searched in this jurisdiction, not nothing was found.state_program_systems_available_for_state- what EPA actually publishes for that state, measured this run, with record counts.state_program_systems_checked- what this property was actually screened against.state_program_systems_indeterminate- systems that could not be classified either way, named rather than quietly sorted.
When state_coverage is none, every state count is null, never 0. Zero would be a claim that we looked. Facility rows in such a jurisdiction carry state_equivalent_record: null for the same reason.
Coverage reads partial when the radius read did not complete, or when a program system falls in the unclassifiable band - and a partial can never produce a clean negative verdict.
The inventory is measured live every run, never read from a list
A hard-coded table of "state" program acronyms rots into exactly the false clear above the first time EPA onboards or retires an agency. It is also simply wrong today, because the acronyms do not say what they are. Measured:
| Acronym | Actually the agency system of | Share of its national records in that state |
|---|---|---|
MERI-FIS | New Jersey (not Maine) | 100.00% of 436 |
UST | Tennessee (reads federal) | 100.00% of 772 |
FIS | New York | 100.00% of 131,231 |
ACES | Illinois | 100.00% of 95,511 |
AZURITE | Arizona | 100.00% of 40,447 |
CIM | Utah | 100.00% of 8,547 |
CEDS | Virginia | 100.00% of 5,780 |
PDS | Arkansas | 99.99% of 26,087 |
DEN | Delaware | 99.95% of 9,871 |
PERMIT TRACKING | Alabama | 99.97% of 7,144 |
CNFRS | Oklahoma | 100.00% of 87 |
ISD | Wyoming | 100.00% of 13 |
A two-letter-prefix heuristic would classify every one of those as federal and silently under-report the record class it is being paid to find.
Instead the inventory is derived from two live group-by reads on every run - one national, one for the property's state - and a program system counts as state or tribal equivalent when at least 90% of its national records sit in that state. That is a property of the data, so it cannot go stale.
The threshold is measured, not guessed. Across all 97 program systems: 57 sit between 96.05% and 100% (the state and tribal agency systems), three between 53% and 66% (CDAFLP in Idaho, FARR in Washington, NNEMS in Arizona), and 37 at 42.47% or below (RCRAINFO, NPDES, EIS and the rest of the federal programmes). 0.90 sits in the middle of a 30-point empty band. Anything landing in the 0.50-0.90 gap is reported as indeterminate and forces state_coverage to partial.
The measured per-state inventory, 2026-08-20, ranges from six systems in California (CA-ENVIROVIEW 221,506 · CA-CERS 36,851 · HWTS-DATAMART 17,734 · UORS 3,099 · DTSC-ENVIROSTOR 1,860 · CASWIS 126) and four in Maryland, through one in most states (NJ-NJEMS 263,315 · TX-TCEQ ACR 119,443 · NV-FP 4,866), down to none at all in the twelve jurisdictions listed above.
Four extra drift probes guard it
When the leg is on, four probes run against the live service before any billable row, each in its own error boundary and each reporting pass / fail / unavailable:
- Program-system universe (load-bearing) - the group-by is untruncated, returns a plausible number of systems, and its counts sum exactly to the layer's own row total, which is a free exact truncation guard.
- Positive canary (load-bearing) -
NJ-NJEMSreturns a count inside its measured band and strictly less than the whole layer, because an ignoredWHEREon this service returns the national table and would sail past a band check. - Confinement canary (load-bearing) - the canary state system is still confined to its own state above the threshold. If that stops being true, state and federal systems can no longer be told apart from the data and the run fails rather than guessing.
- Negative control (corroborating) - a bogus
PGM_SYS_ACRNMreturns exactly 0.
None of these run when the leg is off, so a default run makes exactly the same requests it always did.
What it is not
The state and tribal agency systems normalised into EPA FRS are a subset of any state agency's own record holdings. This leg tells you which state agency program systems EPA publishes for a jurisdiction, which of them a property appears in, and the program ID to quote when requesting the file. It does not replace a direct request to the state agency, and state_coverage: "none" is an instruction to make one.
Correctness guarantees, all measured
A negative is never asserted without verification. contaminating_use_match is true when a classification matched, false when classifications exist and none matched, and null when EPA publishes no classification at all. Nationally, FRS_SIC holds 2,051,024 rows and FRS_NAICS 2,937,686 against 6,983,618 interest records, so most FRS facilities carry no classification. Every summary row reports classification_coverage_pct and facilities_without_any_classification so a clean verdict can be read against how much was actually classifiable.
EPA geocodes many FRS records to the operator's mailing address, not the operating site. Measured 2026-08-18: of 188 FRS interests within 402 m of downtown Denver, 90 are Wyoming oil and gas well pads - SHIPROCK FEDERAL 28-1, WIND DANCER 34-28 PAD, HAYSTACK 30-4 - all filed under LOCATION_ADDRESS "1560 BROADWAY SUITE 2000" and all sharing one identical coordinate, the operator's Denver office. Reporting those as land uses 1,200 feet from a subject property would be a confident wrong answer on a liability-bearing report. Every row therefore carries location_confidence, location_state_matches_query_state and colocated_facility_count, and mailing-address geocodes and coordinate stacks are excluded from the verdict by default while still being emitted and counted.
A SECONDARY classification is never reported as the facility's business. EPA marks each code PRIMARY, SECONDARY or UNKNOWN, and primary_land_use_class_basis always says which one the verdict rests on.
Malformed codes are reported, never guessed. FRS_SIC is a 4-character text column holding real junk - OWNE on 19,018 rows nationally, UNK on 11,875, plus 2- and 3-digit truncations. A 3-digit value is genuinely ambiguous, so it is surfaced in malformed_classification_codes and never expanded into a match. FRS_NAICS holds 55,632 rows beginning with a leading zero, which no valid NAICS code has; those are normalised and the normalisation is disclosed in naics_leading_zero_codes.
Both NAICS vintages are screened. FRS stores 2017 and 2022 NAICS side by side. Gasoline stations measured 2026-08-18: 447110 = 24,008 plus 447190 = 16,439 plus 44711 = 14,841 in the 2017 family, against 457110 = 15,868 plus 457120 = 6,596 in the 2022 family. A vocabulary built on either vintage alone would silently miss the other, so matching is longest-prefix across both.
Live drift gate, before any billable row. Seven probes run against the live service (eleven when the opt-in state leg is requested) before a single row is emitted: the three layers publish the columns the join needs; FRS_SIC and FRS_NAICS are above their row-count floors; SIC 7216 and NAICS 812320 return counts inside their measured bands; the filtered count is strictly less than the unfiltered count (an ignored WHERE clause on this service would return the whole national table and sail past a floor); and a bogus code returns exactly zero. Each probe has its own error boundary and reports pass / fail / unavailable. A probe that measures the wrong answer fails the run; a load-bearing probe that cannot complete fails the run; only the corroborating negative control may be unavailable, in which case the run proceeds and says so in drift_gate_status.
No silent zero. A run that cannot answer fails loudly with 0 rows and 0 billed. assets is a required input, so a bare {} call is rejected before the run starts.
Every property you submit comes back, and a truncated answer can never be mistaken for a complete one. There are two separate caps and both are disclosed on the row.
maxFacilitiesPerAssetcaps the facility rows for one property. When it bites, that property'sresults_truncatedreadstrueand a would-be negative verdict is downgraded toinconclusive.maxResultscaps the rows for the whole run. It never drops anasset_summaryrow. The run reserves one summary slot per requested property and divides whatever budget is left over the facility detail on a max-min fair basis, so one busy downtown parcel cannot starve nine quiet ones. Where detail was trimmed, the rows readasset_screen_status: "partial",results_truncated_global: true, andfacility_rows_dropped_by_global_cap: <n>. The summary's counts and verdict are computed over every facility found, not just the rows emitted, so trimming costs you supporting detail and never the verdict.
The invariant: the dataset always holds exactly one asset_summary row per property you submitted, in the order you submitted them. assets_requested, assets_screened_complete, assets_screened_partial and assets_not_reached are stamped on every row and always add up. So a portfolio run can be reconciled against the input without inspecting the log, and there is no way for a property to be quietly missing.
A property that could not be screened at all — an address the US Census geocoder cannot resolve, for instance — still gets its asset_summary row, with astm_prior_use_verdict: "not_screened", a not_screened_reason naming the problem, and every count null rather than 0. Null means not checked; zero would be a claim that we looked and found none. That row is billable, because it is a per-property answer, and it is bounded by maxResults like any other.
If maxResults is lower than the number of properties submitted, the run fails before emitting anything and tells you the minimum to set. Returning four of your ten properties with nothing in the data saying which six were skipped is the one outcome this design refuses.
Output fields (156 fields)
Property (echoed on every row)
| Field | Type | What it means |
|---|---|---|
row_type | string | null | "facility" for one contaminating land use, or "asset_summary" for the one-per-property rollup. |
asset_label | string | null | The label you supplied for this property, echoed back on every row. |
asset_address | string | null | The address you supplied, or null when the property was given as a coordinate. |
asset_lat | number | null | Latitude actually screened (WGS84), after geocoding if an address was supplied. |
asset_lon | number | null | Longitude actually screened (WGS84), after geocoding if an address was supplied. |
asset_state | string | null | Two-letter state the query coordinate falls in, resolved from the US Census geocoder. Null when the geocoder was unavailable. |
asset_state_name | string | null | Full state name of the query coordinate from the US Census geocoder. |
asset_county_fips | string | null | 5-digit county FIPS of the query coordinate from the US Census geocoder. |
asset_county_name | string | null | County name of the query coordinate from the US Census geocoder. |
radius_miles | number | null | Radius screened around the property. |
Facility identity and location
| Field | Type | What it means |
|---|---|---|
facility_id | string | null | Stable identity for the facility - the EPA FRS REGISTRY_ID, or the FRS KEY_FIELD when EPA publishes no registry id. |
facility_id_basis | string | null | "registry_id" or "key_field" - which identifier facility_id came from. |
registry_id | string | null | EPA Facility Registry Service REGISTRY_ID. Null when EPA publishes none for this record. |
facility_name | string | null | PRIMARY_NAME as EPA FRS publishes it. |
facility_address | string | null | LOCATION_ADDRESS as EPA FRS publishes it. Note this can be the operator mailing address - see location_confidence. |
facility_city | string | null | CITY_NAME as EPA FRS publishes it. |
facility_state | string | null | Two-letter STATE_CODE the FRS record is filed under. |
facility_zip | string | null | POSTAL_CODE as EPA FRS publishes it. |
facility_county_name | string | null | COUNTY_NAME as EPA FRS publishes it. |
facility_county_fips | string | null | 5-digit county FIPS normalised from the FRS FIPS_CODE column. Null when the published value could not be resolved without guessing. |
facility_county_fips_raw | string | null | The FIPS_CODE value exactly as EPA published it. Measured spellings include "08031", "CO031", "8031" and null in a single page. |
facility_lat | number | null | LATITUDE83 as EPA FRS publishes it (NAD83). |
facility_lon | number | null | LONGITUDE83 as EPA FRS publishes it (NAD83). |
distance_miles | number | null | Great-circle distance from the property to the FRS coordinate. Read it together with location_confidence - a mailing-address geocode makes this distance meaningless. |
frs_facility_url | string | null | EPA's own facility detail page for this record. |
Location reliability (the mailing-address geocode guard)
| Field | Type | What it means |
|---|---|---|
coordinate_accuracy_meters | number | null | EPA ACCURACY_VALUE - the accuracy EPA claims for the published coordinate, in metres. |
coordinate_collection_method | string | null | EPA COLLECT_MTH_DESC, e.g. "ADDRESS MATCHING-HOUSE NUMBER". |
coordinate_reference_point | string | null | EPA REF_POINT_DESC, e.g. "CENTER OF A FACILITY OR STATION". |
colocated_facility_count | number | null | How many distinct facilities in this property's radius publish this exact coordinate. A high value indicates an address-level geocode shared by many registrations. |
location_confidence | string | null | "consistent" | "state_mismatch" (record filed in another state - almost certainly the operator mailing address) | "coordinate_stack" (many facilities on one coordinate) | "unknown" (state cross-check could not be performed). |
location_state_matches_query_state | boolean | null | true / false / null. null means the check was not performed, never that it passed. |
location_confidence_reason | string | null | Plain-language explanation of why this coordinate was classified the way it was. Null when confidence is "consistent". |
counts_toward_verdict | boolean | null | Whether this facility contributed to the property's ASTM prior-use verdict. Mailing-address geocodes and coordinate stacks do not, unless crossStateRecords is set to "include". |
EPA program registration
| Field | Type | What it means |
|---|---|---|
program_systems | string | null | Semicolon-separated EPA/state program systems this facility is registered in (PGM_SYS_ACRNM), e.g. "AIR; AIRS/AFS" or "NJ-NJEMS". |
program_system_count | number | null | How many distinct program systems carry this facility. |
program_ids | string | null | Semicolon-separated program-specific identifiers (PGM_SYS_ID). |
interest_types | string | null | Semicolon-separated FRS INTEREST_TYPE values, e.g. "AIR MINOR", "SQG", "STATE MASTER". |
key_fields | string | null | Semicolon-separated FRS KEY_FIELD values (PGM_SYS_ACRNM + PGM_SYS_ID) - the keys the SIC and NAICS classification tables join on. |
federal_agency_name | string | null | FEDERAL_AGENCY_NAME when the facility is a federal installation. |
epa_region_code | string | null | EPA region code (01-10). |
Operational status and record age (the former-use signal)
| Field | Type | What it means |
|---|---|---|
operational_status | string | null | "operating" | "closed_or_terminated" | "unknown". A closed or terminated record is the strongest signal in this dataset that the use is FORMER rather than current. |
operational_status_basis | string | null | "explicit_phrase" | "coded_flag" (a program-specific Y/N) | "uninterpretable_value" | "not_reported". EPA publishes 47 distinct ACTIVE_STATUS values across 97 program systems; ambiguous single letters are left unknown rather than guessed. |
operational_status_raw | string | null | The ACTIVE_STATUS value exactly as EPA published it. |
record_created_date | string | null | FRS CREATE_DATE as YYYY-MM-DD. |
record_updated_date | string | null | FRS UPDATE_DATE as YYYY-MM-DD. |
record_last_reported_date | string | null | FRS LAST_REPORTED_DATE as YYYY-MM-DD - how recently the program system reported this facility. |
Contaminating land-use verdict
| Field | Type | What it means |
|---|---|---|
classification_available | boolean | null | Whether EPA publishes ANY SIC or NAICS classification for this facility. false means EPA published none - it does NOT mean the facility has no contaminating use. |
contaminating_use_match | boolean | null | true when a classification matched the contaminating land-use vocabulary; false when classifications exist and none matched; null when no classification was published at all. |
land_use_classes | string | null | Semicolon-separated contaminating land-use class IDs matched on this facility. |
land_use_class_labels | string | null | Human-readable labels for land_use_classes. |
primary_land_use_class | string | null | The single class that best characterises the facility - taken from a PRIMARY-indicator code where one exists, otherwise the highest-risk match. |
primary_land_use_class_label | string | null | Human-readable label for primary_land_use_class. |
primary_land_use_class_basis | string | null | How primary_land_use_class was chosen, e.g. "sic_primary_indicator" or "naics_secondary_indicator" - so a secondary classification is never silently read as the facility's business type. |
contaminant_risk_tier | string | null | "high" | "moderate" | "low" - the highest tier across the matched classes, from the vocabulary. |
contaminants_of_concern | string | null | Semicolon-separated contaminant groups the cited authorities associate with the matched land uses. These are the constituents typically investigated, not measured concentrations. |
contaminants_of_concern_count | number | null | How many distinct contaminant groups are listed. |
SIC classification detail
| Field | Type | What it means |
|---|---|---|
sic_codes_all | string | null | Every SIC_CODE value EPA publishes for this facility, exactly as stored, including malformed ones. |
sic_codes_matched | string | null | The SIC codes that matched the contaminating land-use vocabulary. |
sic_titles_matched | string | null | Official OSHA SIC Manual titles for the matched SIC codes. |
sic_primary_codes | string | null | SIC codes EPA marks PRIMARY_INDICATOR = PRIMARY for this facility. |
sic_secondary_codes | string | null | SIC codes EPA marks SECONDARY. A secondary code is not the facility's principal business. |
sic_unknown_indicator_codes | string | null | SIC codes EPA marks UNKNOWN - EPA itself does not say whether the code is the facility's primary business. |
sic_row_count | number | null | How many FRS_SIC rows joined to this facility. |
NAICS classification detail
| Field | Type | What it means |
|---|---|---|
naics_codes_all | string | null | Every NAICS_CODE value EPA publishes for this facility, exactly as stored. |
naics_codes_matched | string | null | NAICS codes that matched the vocabulary, after leading-zero normalisation. |
naics_stems_matched | string | null | The vocabulary stems that matched. Matching is longest-prefix because FRS stores 5- and 6-digit codes from two NAICS vintages side by side. |
naics_titles_matched | string | null | Official Census NAICS titles for the matched stems. |
naics_vintages_matched | string | null | Which NAICS vintage (2017 or 2022) each matched stem belongs to. |
naics_leading_zero_codes | string | null | NAICS values EPA stored with a leading zero, which no valid NAICS code has. Reported so the normalisation is visible rather than silent. |
naics_row_count | number | null | How many FRS_NAICS rows joined to this facility. |
Match quality and data defects
| Field | Type | What it means |
|---|---|---|
match_count_primary_indicator | number | null | How many matching classifications EPA marks PRIMARY. |
match_count_secondary_or_unknown_indicator | number | null | How many matching classifications EPA marks SECONDARY or UNKNOWN. |
malformed_classification_codes | string | null | Codes EPA published that are not resolvable classification codes (e.g. SIC "OWNE", "UNK", or a 3-digit truncation). They are reported, never guessed at, and never counted as a match. |
malformed_classification_code_count | number | null | How many malformed codes this facility carries. |
unmatched_sic_code_count | number | null | Well-formed SIC codes that are simply not contaminating land uses. |
unmatched_naics_code_count | number | null | Well-formed NAICS codes that are simply not contaminating land uses. |
Provenance of the contaminant mapping
| Field | Type | What it means |
|---|---|---|
contaminant_mapping_version | string | null | Version of the classification-to-contaminant vocabulary used for this row. |
contaminant_mapping_authorities | string | null | The published authorities that identify the matched industries as potential contaminant sources. |
contaminant_mapping_citation | string | null | Full citation text for those authorities. |
contaminant_mapping_url | string | null | Link to the primary cited authority. |
astm_reference | string | null | The ASTM E1527-21 clause this screen supports. |
temporal_basis | string | null | Always "current_reported_classification". EPA FRS publishes the classification a facility CURRENTLY reports, not a historical land-use record. |
temporal_basis_note | string | null | Plain-language statement of exactly what the classification does and does not tell you about historic use. |
Per-source status (null vs false contract)
| Field | Type | What it means |
|---|---|---|
frs_interests_status | string | null | "ok" | "partial" | "unavailable" | "not_run" for the radius query behind this row. |
frs_sic_status | string | null | "ok" | "partial" | "unavailable" | "not_run" for the SIC classification join. |
frs_naics_status | string | null | "ok" | "partial" | "unavailable" | "not_run" for the NAICS classification join. |
geocoder_status | string | null | "ok" | "unavailable" | "not_run" for the US Census geocoder used to resolve the query point's state. |
frs_interests_error | string | null | Error text when the radius query did not fully succeed. |
frs_sic_error | string | null | Error text when the SIC join did not fully succeed. |
frs_naics_error | string | null | Error text when the NAICS join did not fully succeed. |
geocoder_error | string | null | Error text when the Census geocoder did not answer. |
Live drift gate disclosure
| Field | Type | What it means |
|---|---|---|
drift_gate_status | string | null | "verified" or "verified_degraded" on any emitted row. A failed or incomplete load-bearing gate fails the whole run before anything is emitted or billed. |
drift_gate_note | string | null | What the live drift gate measured on this run. |
drift_probes_verified | string | null | Semicolon-separated ids of the drift probes that passed. |
drift_probes_unavailable | string | null | Semicolon-separated ids of drift probes that could not complete. Only corroborating probes may be unavailable on an emitted row. |
drift_negative_control_status | string | null | Outcome of the corroborating negative control (a bogus SIC code must return zero rows). |
State / tribal equivalent records - opt-in, facility rows
| Field | Type | What it means |
|---|---|---|
state_program_systems | string | null | Semicolon-separated EPA FRS PGM_SYS_ACRNM values on this facility that were measured this run to be state or tribal agency program systems (at least 90% of their national records sit in this state). null when the opt-in state leg was not requested or could not run - null means NOT CHECKED, never "checked and none". |
state_program_ids | string | null | The facility's PGM_SYS_ID values in those state or tribal agency systems - the identifier to quote when requesting the file from the state agency. null when the state leg was not requested or could not run. |
state_equivalent_record | boolean | null | true when this facility carries at least one state or tribal agency program record - the ASTM E1527-21 Section 8.2 "state and tribal equivalent" record class. false is a VERIFIED negative for this facility. null means the state leg was not requested or could not run for this property. Read it together with the summary row's state_coverage: a false here inside a state whose state_coverage is "none" only means FRS holds no state system for that jurisdiction. |
state_equivalent_record_share | number | null | The highest measured in-state share of national records among this facility's matched state systems (1.0 = every record that system holds nationally is in this state). Published so the classification can be audited rather than trusted. null when not checked or when no state system matched. |
State / tribal equivalent records - opt-in, summary rows (the coverage contract)
| Field | Type | What it means |
|---|---|---|
state_leg_requested | boolean | null | Whether this run asked for the opt-in state and tribal equivalent record leg via programs: ["state"]. false means the leg never ran and every other state_* field on this row is null. |
state_leg_status | string | null | "not_requested" | "ok" | "unavailable" | "state_unknown" | "not_screened". Anything other than "ok" means no state-record conclusion was reached for this property and the counts are null rather than zero. |
state_coverage | string | null | "complete" | "partial" | "none" | null. THE LOAD-BEARING FIELD OF THIS LEG. "none" means EPA FRS normalises NO state or tribal agency program system for this jurisdiction at all, so this record class could not be searched here - it is NOT a searched-and-empty result, and the state counts are null so no downstream filter can read it as one. Measured 2026-08-20: AK, CO, DC, MI, SD, VT, WV and the US territories all read "none". "partial" means either the radius read did not complete or one or more program systems could not be classified from the data. null means the leg did not run. |
state_coverage_reason | string | null | Plain-language explanation of the state_coverage value, naming the jurisdiction, the systems searched and, when coverage is not complete, exactly what was not searched. |
state_coverage_note | string | null | Standing disclosure that the state and tribal agency systems normalised into EPA FRS are a SUBSET of any state agency's own record holdings, and that state_coverage="none" means the class could not be searched here rather than that nothing was found. |
state_program_systems_checked | string | null | The state or tribal agency program systems this property was actually screened against, with the count of records each holds in this state. null when the leg did not run or the radius read did not complete, in which case nothing was searched and nothing may be read as a negative. |
state_program_systems_checked_count | number | null | How many state or tribal agency program systems this property was actually screened against. null when the leg did not run. |
state_program_systems_available_for_state | string | null | Every state or tribal agency program system EPA FRS publishes for this jurisdiction, measured live this run, with each system's in-state record count. null when the leg did not run; null with state_coverage="none" means EPA publishes none at all. |
state_program_systems_available_for_state_count | number | null | How many state or tribal agency program systems EPA FRS publishes for this jurisdiction. 0 with state_coverage="none" is a fact about EPA's coverage of the state, not about this property. |
state_program_systems_indeterminate | string | null | Program systems holding between 50% and 90% of their national records in this state - too concentrated to call federal, too dispersed to call a state agency system. They are neither counted nor discarded, and their presence forces state_coverage to "partial". Measured 2026-08-20 this affects CDAFLP (ID), FARR (WA) and NNEMS (AZ). |
state_program_systems_indeterminate_count | number | null | How many program systems in this jurisdiction fell into the indeterminate confinement band. Any value above zero downgrades state_coverage to "partial". |
state_program_universe_size | number | null | How many distinct PGM_SYS_ACRNM values the whole FRS_INTERESTS layer published on this run (measured 97 on 2026-08-20). A drop below the floor fails the run rather than silently shrinking the record class. |
state_confinement_threshold | number | null | The in-state share of national records at or above which a program system was treated as a state or tribal agency system on this run (0.9). Measured basis: 57 systems sit at 96.05%-100%, three between 53% and 66%, and 37 at 42% or below, so 0.9 sits inside a 30-point empty band rather than on a cliff edge. |
state_equivalent_facility_count | number | null | How many FRS facilities within the radius carry at least one state or tribal agency program record. null when state_coverage is "none" - there was no record class to search, and zero would claim we looked. |
state_equivalent_facility_count_counted_toward_verdict | number | null | The subset of state-record facilities whose published coordinate passed the mailing-address and coordinate-stack checks. Only these drive astm_state_equivalent_verdict, for the same reason they drive the prior-use verdict. null when state_coverage is "none". |
state_equivalent_contaminating_use_count | number | null | Facilities carrying both a state or tribal agency record and a contaminating SIC/NAICS classification - the strongest single signal this leg produces. null when state_coverage is "none". |
astm_state_equivalent_verdict | string | null | "state_equivalent_record_identified" | "no_state_equivalent_record_found" | "state_equivalent_records_not_available_for_this_state" | "inconclusive" | "not_requested" | "not_screened". Deliberately SEPARATE from astm_prior_use_verdict, which is unchanged by this leg. It can never read as a clean negative while coverage is "partial" or "none". |
astm_state_equivalent_reference | string | null | The ASTM E1527-21 clause this leg addresses: Section 8.2 state and tribal equivalent record sources. Distinct from the Section 8.3 prior-use question the rest of the actor answers. |
state_program_inventory_basis | string | null | States plainly that the per-state program-system inventory is measured live from two FRS group-by reads on every run and that no hard-coded list of state agencies is used - because such a list rots into a false clear the first time EPA onboards or retires an agency system. |
Asset summary row only
| Field | Type | What it means |
|---|---|---|
astm_prior_use_verdict | string | null | "contaminating_use_identified" | "no_classified_contaminating_use_found" | "inconclusive" | "not_screened". It can never read as a negative while a source was unavailable or this property's result set was truncated by maxFacilitiesPerAsset, and a property that could not be screened reads "not_screened" rather than being omitted from the output. |
astm_prior_use_verdict_reason | string | null | Why the verdict reads the way it does, including how many facilities published no classification at all. |
highest_contaminant_risk_tier | string | null | Highest contaminant risk tier among the facilities that counted toward the verdict. |
nearest_contaminating_use_name | string | null | Name of the nearest facility that counted toward the verdict. |
nearest_contaminating_use_class | string | null | Land-use class of the nearest counted facility. |
nearest_contaminating_use_distance_miles | number | null | Distance to the nearest facility that counted toward the verdict. |
frs_interest_records_in_radius | number | null | Raw FRS_INTERESTS rows returned. One facility usually carries several interest records, one per program system. |
frs_facilities_in_radius | number | null | Distinct facilities after deduplicating interest records. |
facilities_with_classification | number | null | How many of those facilities EPA publishes any SIC or NAICS code for. |
facilities_without_any_classification | number | null | How many publish none. These are NOT evidence of no contaminating use - EPA simply does not classify them. |
classification_coverage_pct | number | null | Share of in-radius facilities that carry any industrial classification. Read the negative verdict against this number. |
contaminating_use_facility_count | number | null | Facilities in radius carrying a contaminating classification, before location filtering. |
contaminating_use_facility_count_counted_toward_verdict | number | null | Of those, how many had a reliable location and so counted toward the verdict. |
facilities_emitted | number | null | How many facility rows this property produced after the per-property cap. |
results_truncated | boolean | null | Whether the PER-ASSET maxFacilitiesPerAsset cap cut this property's result set. When true a negative verdict is downgraded to inconclusive. The separate run-level maxResults cap is reported by results_truncated_global and never drops an asset_summary row. Null on a property that was not screened. |
max_facilities_per_asset | number | null | The per-property cap in force for this run. |
mailing_address_geocode_facility_count | number | null | Contaminating facilities excluded from the verdict because the FRS record is filed in a different state than the query point. |
coordinate_stack_facility_count | number | null | Contaminating facilities excluded from the verdict because many facilities share one identical coordinate. |
unknown_location_confidence_facility_count | number | null | Contaminating facilities whose location could not be cross-checked, usually because the geocoder was unavailable. |
cross_state_records_mode | string | null | How out-of-state FRS records were handled on this run: flag, exclude or include. |
coordinate_stack_threshold | number | null | The threshold in force for classifying a shared coordinate as a stack. |
land_use_classes_requested | string | null | Which classes this run screened for, or ALL. |
include_secondary_classifications | boolean | null | Whether SECONDARY and UNKNOWN indicator codes counted as hits on this run. |
classification_coverage_note | string | null | Measured statement of how much of the FRS universe carries an industrial classification at all, and why absence is never reported as an absence of contaminating use. |
Provenance
| Field | Type | What it means |
|---|---|---|
data_source | string | null | The upstream datasets behind this row. |
source_url | string | null | EPA Facility Registry Service homepage. |
checked_at | string | null | UTC timestamp of the run that produced this row. |
disclaimer | string | null | Scope statement: this is a screening aid, not a determination that a release has occurred. |
Other fields
| Field | Type | What it means |
|---|---|---|
asset_screen_status | string | null | "complete" | "partial" | "not_screened". Whether this property was fully screened, screened but with some of its facility rows dropped by the run-level maxResults cap, or never screened at all. Every requested asset gets exactly one asset_summary row, so a property is never silently absent from the output. |
not_screened_reason | string | null | When asset_screen_status is "not_screened", why this property could not be screened (for example an address the US Census geocoder could not resolve). Null on any property that was screened. |
facility_rows_dropped_by_global_cap | number | null | How many of this property's facility rows the run-level maxResults cap dropped. The summary row's counts and verdict are computed over ALL facilities found, not just the rows emitted, so a non-zero value here means supporting detail is missing - never that the verdict is. |
results_truncated_global | boolean | null | Whether the run-level maxResults cap dropped any facility row anywhere in this run. This is a DIFFERENT cap from results_truncated, which reports the per-asset maxFacilitiesPerAsset cut. The run-level cap never drops an asset_summary row, so every property still carries its verdict. |
assets_requested | number | null | How many properties this run was asked to screen. Compare with the number of asset_summary rows in the dataset: they are always equal. |
assets_screened_complete | number | null | How many of the requested properties were screened with every facility row emitted. |
assets_screened_partial | number | null | How many of the requested properties were screened but had facility rows dropped by the run-level maxResults cap. Their verdicts are still complete. |
assets_not_reached | number | null | How many of the requested properties could not be screened at all. Each still appears as an asset_summary row with astm_prior_use_verdict "not_screened" and a not_screened_reason. |
max_results | number | null | The run-level row cap that was applied. It is a hard cap on rows and therefore a hard cap on the bill. A run whose maxResults is below the number of requested assets fails before emitting anything. |
Use as an MCP tool
This actor is callable by AI agents over Apify's hosted MCP endpoint. Billing is unchanged when it is called as a tool, and a run that cannot answer fails without billing.
Endpoint: https://mcp.apify.com/?actors=malonestar/historic-land-use-sic-contaminant-screener
Claude Desktop / Claude Code / Cursor config:
{"mcpServers": {"historic-land-use": {"url": "https://mcp.apify.com/?actors=malonestar/historic-land-use-sic-contaminant-screener","headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }}}}
Worked agent prompt:
"Screen 1438 Tremont Pl, Denver CO for prior contaminating land uses within a quarter mile. For each hit, tell me the business type, the contaminants of concern, and whether the location is reliable enough to count."
Chaining. For a full site workup, combine with the Section 8.2 records review and the physical-setting screens in one MCP session:
https://mcp.apify.com/?actors=malonestar/historic-land-use-sic-contaminant-screener,malonestar/epa-contaminated-site-screener,malonestar/fws-wetlands-proximity-screener,malonestar/nhd-surface-water-404-screener
Related actors: epa-contaminated-site-screener (ASTM Section 8.2 records review), site-due-diligence-bundle (20-layer one-call site screen), state-tank-spill-registry-screener (state tank and spill registers), epa-drinking-water-quality-screener.
Pricing
Pay per result: $12 per 1,000 rows, billed on the automatic Result event. One emitted row is one billable result. Graduated discounts apply on paid Apify plans. A failed run emits nothing and bills nothing.
maxResults is a hard cap on rows and therefore a hard cap on the bill. assets is required, so there is no accidental national run.
Because one asset_summary row is reserved per property, the floor on a run is one row per property submitted, and maxResults must be at least the number of properties — a run set lower fails before emitting anything rather than dropping properties silently. A property that could not be screened still costs one row, and carries the reason why.
FAQ
How do I find out if there was a dry cleaner next to my property?
Screen the coordinate at 0.25 mi. Any facility carrying SIC 7215/7216 or NAICS 81231/81232 is returned with primary_land_use_class = DRY_CLEANING and PCE/TCE listed in contaminants_of_concern.
Does this cover gas stations and underground tanks?
It covers gas stations as a land use (SIC 5541, NAICS 4471/4571). For tank registrations, releases and LUST cases, use epa-contaminated-site-screener, which reads EPA's UST Finder and LUST data directly.
Is this a historical land-use search? It is a systematic first pass over the Section 8.3 question using the classification EPA publishes today, plus each record's operational status and last-reported date. It is not a title-chain, city-directory or aerial-photograph review. See "What historic does and does not mean here".
Why did a facility come back with no classification?
EPA publishes SIC or NAICS for only a minority of FRS records. That case returns classification_available: false and contaminating_use_match: null - it is explicitly not evidence that the facility is harmless.
Why is a facility flagged state_mismatch?
Because EPA filed it under a different state than the one your coordinate falls in, which almost always means the published coordinate is the operator's mailing address rather than the site. It is emitted, flagged, and left out of the verdict.
Can I screen addresses instead of coordinates?
Yes - {"address": "..."}. Addresses are geocoded with the free US Census geocoder. A coordinate is faster and more precise, and an address that cannot be geocoded fails loudly rather than screening the wrong place.
What is the data source?
EPA's Facility Registry Service: the FRS_INTERESTS point layer joined to the FRS_SIC and FRS_NAICS classification tables on KEY_FIELD. Keyless and public.