Historic Land Use Screener - Contaminating SIC/NAICS Sites avatar

Historic Land Use Screener - Contaminating SIC/NAICS Sites

Pricing

from $6.60 / 1,000 results

Go to Apify Store
Historic Land Use Screener - Contaminating SIC/NAICS Sites

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

Kyle Maloney

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

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.

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:

LocationContaminating facilities found hereOf those, invisible to a federal ECHO radius search
Newark, NJ (Ironbound), 0.5 mi3821 (55%)
Van Nuys, CA, 0.5 mi1510 (67%)
Denver, CO (CBD), 0.25 mi91

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 with record_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, and none is 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:

AcronymActually the agency system ofShare of its national records in that state
MERI-FISNew Jersey (not Maine)100.00% of 436
USTTennessee (reads federal)100.00% of 772
FISNew York100.00% of 131,231
ACESIllinois100.00% of 95,511
AZURITEArizona100.00% of 40,447
CIMUtah100.00% of 8,547
CEDSVirginia100.00% of 5,780
PDSArkansas99.99% of 26,087
DENDelaware99.95% of 9,871
PERMIT TRACKINGAlabama99.97% of 7,144
CNFRSOklahoma100.00% of 87
ISDWyoming100.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:

  1. 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.
  2. Positive canary (load-bearing) - NJ-NJEMS returns a count inside its measured band and strictly less than the whole layer, because an ignored WHERE on this service returns the national table and would sail past a band check.
  3. 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.
  4. Negative control (corroborating) - a bogus PGM_SYS_ACRNM returns 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.

  • maxFacilitiesPerAsset caps the facility rows for one property. When it bites, that property's results_truncated reads true and a would-be negative verdict is downgraded to inconclusive.
  • maxResults caps the rows for the whole run. It never drops an asset_summary row. 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 read asset_screen_status: "partial", results_truncated_global: true, and facility_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)

FieldTypeWhat it means
row_typestring | null"facility" for one contaminating land use, or "asset_summary" for the one-per-property rollup.
asset_labelstring | nullThe label you supplied for this property, echoed back on every row.
asset_addressstring | nullThe address you supplied, or null when the property was given as a coordinate.
asset_latnumber | nullLatitude actually screened (WGS84), after geocoding if an address was supplied.
asset_lonnumber | nullLongitude actually screened (WGS84), after geocoding if an address was supplied.
asset_statestring | nullTwo-letter state the query coordinate falls in, resolved from the US Census geocoder. Null when the geocoder was unavailable.
asset_state_namestring | nullFull state name of the query coordinate from the US Census geocoder.
asset_county_fipsstring | null5-digit county FIPS of the query coordinate from the US Census geocoder.
asset_county_namestring | nullCounty name of the query coordinate from the US Census geocoder.
radius_milesnumber | nullRadius screened around the property.

Facility identity and location

FieldTypeWhat it means
facility_idstring | nullStable identity for the facility - the EPA FRS REGISTRY_ID, or the FRS KEY_FIELD when EPA publishes no registry id.
facility_id_basisstring | null"registry_id" or "key_field" - which identifier facility_id came from.
registry_idstring | nullEPA Facility Registry Service REGISTRY_ID. Null when EPA publishes none for this record.
facility_namestring | nullPRIMARY_NAME as EPA FRS publishes it.
facility_addressstring | nullLOCATION_ADDRESS as EPA FRS publishes it. Note this can be the operator mailing address - see location_confidence.
facility_citystring | nullCITY_NAME as EPA FRS publishes it.
facility_statestring | nullTwo-letter STATE_CODE the FRS record is filed under.
facility_zipstring | nullPOSTAL_CODE as EPA FRS publishes it.
facility_county_namestring | nullCOUNTY_NAME as EPA FRS publishes it.
facility_county_fipsstring | null5-digit county FIPS normalised from the FRS FIPS_CODE column. Null when the published value could not be resolved without guessing.
facility_county_fips_rawstring | nullThe FIPS_CODE value exactly as EPA published it. Measured spellings include "08031", "CO031", "8031" and null in a single page.
facility_latnumber | nullLATITUDE83 as EPA FRS publishes it (NAD83).
facility_lonnumber | nullLONGITUDE83 as EPA FRS publishes it (NAD83).
distance_milesnumber | nullGreat-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_urlstring | nullEPA's own facility detail page for this record.

Location reliability (the mailing-address geocode guard)

FieldTypeWhat it means
coordinate_accuracy_metersnumber | nullEPA ACCURACY_VALUE - the accuracy EPA claims for the published coordinate, in metres.
coordinate_collection_methodstring | nullEPA COLLECT_MTH_DESC, e.g. "ADDRESS MATCHING-HOUSE NUMBER".
coordinate_reference_pointstring | nullEPA REF_POINT_DESC, e.g. "CENTER OF A FACILITY OR STATION".
colocated_facility_countnumber | nullHow 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_confidencestring | 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_stateboolean | nulltrue / false / null. null means the check was not performed, never that it passed.
location_confidence_reasonstring | nullPlain-language explanation of why this coordinate was classified the way it was. Null when confidence is "consistent".
counts_toward_verdictboolean | nullWhether 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

FieldTypeWhat it means
program_systemsstring | nullSemicolon-separated EPA/state program systems this facility is registered in (PGM_SYS_ACRNM), e.g. "AIR; AIRS/AFS" or "NJ-NJEMS".
program_system_countnumber | nullHow many distinct program systems carry this facility.
program_idsstring | nullSemicolon-separated program-specific identifiers (PGM_SYS_ID).
interest_typesstring | nullSemicolon-separated FRS INTEREST_TYPE values, e.g. "AIR MINOR", "SQG", "STATE MASTER".
key_fieldsstring | nullSemicolon-separated FRS KEY_FIELD values (PGM_SYS_ACRNM + PGM_SYS_ID) - the keys the SIC and NAICS classification tables join on.
federal_agency_namestring | nullFEDERAL_AGENCY_NAME when the facility is a federal installation.
epa_region_codestring | nullEPA region code (01-10).

Operational status and record age (the former-use signal)

FieldTypeWhat it means
operational_statusstring | 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_basisstring | 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_rawstring | nullThe ACTIVE_STATUS value exactly as EPA published it.
record_created_datestring | nullFRS CREATE_DATE as YYYY-MM-DD.
record_updated_datestring | nullFRS UPDATE_DATE as YYYY-MM-DD.
record_last_reported_datestring | nullFRS LAST_REPORTED_DATE as YYYY-MM-DD - how recently the program system reported this facility.

Contaminating land-use verdict

FieldTypeWhat it means
classification_availableboolean | nullWhether 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_matchboolean | nulltrue 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_classesstring | nullSemicolon-separated contaminating land-use class IDs matched on this facility.
land_use_class_labelsstring | nullHuman-readable labels for land_use_classes.
primary_land_use_classstring | nullThe 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_labelstring | nullHuman-readable label for primary_land_use_class.
primary_land_use_class_basisstring | nullHow 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_tierstring | null"high" | "moderate" | "low" - the highest tier across the matched classes, from the vocabulary.
contaminants_of_concernstring | nullSemicolon-separated contaminant groups the cited authorities associate with the matched land uses. These are the constituents typically investigated, not measured concentrations.
contaminants_of_concern_countnumber | nullHow many distinct contaminant groups are listed.

SIC classification detail

FieldTypeWhat it means
sic_codes_allstring | nullEvery SIC_CODE value EPA publishes for this facility, exactly as stored, including malformed ones.
sic_codes_matchedstring | nullThe SIC codes that matched the contaminating land-use vocabulary.
sic_titles_matchedstring | nullOfficial OSHA SIC Manual titles for the matched SIC codes.
sic_primary_codesstring | nullSIC codes EPA marks PRIMARY_INDICATOR = PRIMARY for this facility.
sic_secondary_codesstring | nullSIC codes EPA marks SECONDARY. A secondary code is not the facility's principal business.
sic_unknown_indicator_codesstring | nullSIC codes EPA marks UNKNOWN - EPA itself does not say whether the code is the facility's primary business.
sic_row_countnumber | nullHow many FRS_SIC rows joined to this facility.

NAICS classification detail

FieldTypeWhat it means
naics_codes_allstring | nullEvery NAICS_CODE value EPA publishes for this facility, exactly as stored.
naics_codes_matchedstring | nullNAICS codes that matched the vocabulary, after leading-zero normalisation.
naics_stems_matchedstring | nullThe 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_matchedstring | nullOfficial Census NAICS titles for the matched stems.
naics_vintages_matchedstring | nullWhich NAICS vintage (2017 or 2022) each matched stem belongs to.
naics_leading_zero_codesstring | nullNAICS values EPA stored with a leading zero, which no valid NAICS code has. Reported so the normalisation is visible rather than silent.
naics_row_countnumber | nullHow many FRS_NAICS rows joined to this facility.

Match quality and data defects

FieldTypeWhat it means
match_count_primary_indicatornumber | nullHow many matching classifications EPA marks PRIMARY.
match_count_secondary_or_unknown_indicatornumber | nullHow many matching classifications EPA marks SECONDARY or UNKNOWN.
malformed_classification_codesstring | nullCodes 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_countnumber | nullHow many malformed codes this facility carries.
unmatched_sic_code_countnumber | nullWell-formed SIC codes that are simply not contaminating land uses.
unmatched_naics_code_countnumber | nullWell-formed NAICS codes that are simply not contaminating land uses.

Provenance of the contaminant mapping

FieldTypeWhat it means
contaminant_mapping_versionstring | nullVersion of the classification-to-contaminant vocabulary used for this row.
contaminant_mapping_authoritiesstring | nullThe published authorities that identify the matched industries as potential contaminant sources.
contaminant_mapping_citationstring | nullFull citation text for those authorities.
contaminant_mapping_urlstring | nullLink to the primary cited authority.
astm_referencestring | nullThe ASTM E1527-21 clause this screen supports.
temporal_basisstring | nullAlways "current_reported_classification". EPA FRS publishes the classification a facility CURRENTLY reports, not a historical land-use record.
temporal_basis_notestring | nullPlain-language statement of exactly what the classification does and does not tell you about historic use.

Per-source status (null vs false contract)

FieldTypeWhat it means
frs_interests_statusstring | null"ok" | "partial" | "unavailable" | "not_run" for the radius query behind this row.
frs_sic_statusstring | null"ok" | "partial" | "unavailable" | "not_run" for the SIC classification join.
frs_naics_statusstring | null"ok" | "partial" | "unavailable" | "not_run" for the NAICS classification join.
geocoder_statusstring | null"ok" | "unavailable" | "not_run" for the US Census geocoder used to resolve the query point's state.
frs_interests_errorstring | nullError text when the radius query did not fully succeed.
frs_sic_errorstring | nullError text when the SIC join did not fully succeed.
frs_naics_errorstring | nullError text when the NAICS join did not fully succeed.
geocoder_errorstring | nullError text when the Census geocoder did not answer.

Live drift gate disclosure

FieldTypeWhat it means
drift_gate_statusstring | 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_notestring | nullWhat the live drift gate measured on this run.
drift_probes_verifiedstring | nullSemicolon-separated ids of the drift probes that passed.
drift_probes_unavailablestring | nullSemicolon-separated ids of drift probes that could not complete. Only corroborating probes may be unavailable on an emitted row.
drift_negative_control_statusstring | nullOutcome of the corroborating negative control (a bogus SIC code must return zero rows).

State / tribal equivalent records - opt-in, facility rows

FieldTypeWhat it means
state_program_systemsstring | nullSemicolon-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_idsstring | nullThe 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_recordboolean | nulltrue 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_sharenumber | nullThe 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)

FieldTypeWhat it means
state_leg_requestedboolean | nullWhether 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_statusstring | 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_coveragestring | 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_reasonstring | nullPlain-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_notestring | nullStanding 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_checkedstring | nullThe 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_countnumber | nullHow 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_statestring | nullEvery 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_countnumber | nullHow 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_indeterminatestring | nullProgram 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_countnumber | nullHow many program systems in this jurisdiction fell into the indeterminate confinement band. Any value above zero downgrades state_coverage to "partial".
state_program_universe_sizenumber | nullHow 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_thresholdnumber | nullThe 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_countnumber | nullHow 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_verdictnumber | nullThe 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_countnumber | nullFacilities 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_verdictstring | 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_referencestring | nullThe 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_basisstring | nullStates 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

FieldTypeWhat it means
astm_prior_use_verdictstring | 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_reasonstring | nullWhy the verdict reads the way it does, including how many facilities published no classification at all.
highest_contaminant_risk_tierstring | nullHighest contaminant risk tier among the facilities that counted toward the verdict.
nearest_contaminating_use_namestring | nullName of the nearest facility that counted toward the verdict.
nearest_contaminating_use_classstring | nullLand-use class of the nearest counted facility.
nearest_contaminating_use_distance_milesnumber | nullDistance to the nearest facility that counted toward the verdict.
frs_interest_records_in_radiusnumber | nullRaw FRS_INTERESTS rows returned. One facility usually carries several interest records, one per program system.
frs_facilities_in_radiusnumber | nullDistinct facilities after deduplicating interest records.
facilities_with_classificationnumber | nullHow many of those facilities EPA publishes any SIC or NAICS code for.
facilities_without_any_classificationnumber | nullHow many publish none. These are NOT evidence of no contaminating use - EPA simply does not classify them.
classification_coverage_pctnumber | nullShare of in-radius facilities that carry any industrial classification. Read the negative verdict against this number.
contaminating_use_facility_countnumber | nullFacilities in radius carrying a contaminating classification, before location filtering.
contaminating_use_facility_count_counted_toward_verdictnumber | nullOf those, how many had a reliable location and so counted toward the verdict.
facilities_emittednumber | nullHow many facility rows this property produced after the per-property cap.
results_truncatedboolean | nullWhether 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_assetnumber | nullThe per-property cap in force for this run.
mailing_address_geocode_facility_countnumber | nullContaminating facilities excluded from the verdict because the FRS record is filed in a different state than the query point.
coordinate_stack_facility_countnumber | nullContaminating facilities excluded from the verdict because many facilities share one identical coordinate.
unknown_location_confidence_facility_countnumber | nullContaminating facilities whose location could not be cross-checked, usually because the geocoder was unavailable.
cross_state_records_modestring | nullHow out-of-state FRS records were handled on this run: flag, exclude or include.
coordinate_stack_thresholdnumber | nullThe threshold in force for classifying a shared coordinate as a stack.
land_use_classes_requestedstring | nullWhich classes this run screened for, or ALL.
include_secondary_classificationsboolean | nullWhether SECONDARY and UNKNOWN indicator codes counted as hits on this run.
classification_coverage_notestring | nullMeasured 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

FieldTypeWhat it means
data_sourcestring | nullThe upstream datasets behind this row.
source_urlstring | nullEPA Facility Registry Service homepage.
checked_atstring | nullUTC timestamp of the run that produced this row.
disclaimerstring | nullScope statement: this is a screening aid, not a determination that a release has occurred.

Other fields

FieldTypeWhat it means
asset_screen_statusstring | 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_reasonstring | nullWhen 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_capnumber | nullHow 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_globalboolean | nullWhether 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_requestednumber | nullHow 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_completenumber | nullHow many of the requested properties were screened with every facility row emitted.
assets_screened_partialnumber | nullHow 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_reachednumber | nullHow 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_resultsnumber | nullThe 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.