US EPA - Facility Registry Service (via ECHO Exporter)
US industrial facilities - mining / utilities / manufacturing (~148K active)
Source
Feed (what to expect)
Weekly Sunday-refreshed ECHO Exporter ZIP (~442 MB CSV, no auth); live-fetched.
Quirks
Reconciliation
Schema
Feeds (axes)
Record kinds
Identifier schemes
Phase 1 desk landscape, written 2026-05-06. Reference document for the EPA FRS fetcher built against the v1 multi-dimensional Classification schema. Cross-references:
docs/adr/007-multi-dimensional-classification.md,docs/DATASOURCES.md,src/strata/fetchers/epa_frs/, ECHO Exporter schema reference athttps://echo.epa.gov/tools/data-downloads/echo-exporter-data-files.
Live-data observations (verified 2026-05-06 against the 2026-05-03 ECHO Exporter):
- Bulk URL is
https://echo.epa.gov/files/echodownloads/echo_exporter.zip(~442 MB compressed, ~2.0 GB CSV; weekly refresh). Thenational_combined.zipfromordsext.epa.govis the alternative raw FRS dump but is 3× larger and lacks ECHO's pre-joined cross-program identifier columns. We consume ECHO Exporter.- 3.14 M rows total. Aggressive filtering required. Most are drinking water systems, retail gas stations, dry cleaners, and similar non-FF-domain entries. The fetcher admits rows passing four cumulative filters: (a)
FAC_ACTIVE_FLAG = 'Y'(1.37 M), (b) lat + lon present (3.08 M), (c)FAC_ACCURACY_METERS ≤ 1000drops state/zip/county centroids (887 K), (d) industrial NAICS prefix in {21 mining, 22 utilities, 31-33 manufacturing} (~148 K). Final admitted ≈ 148,000 facilities.- Coordinate quality bimodal. 50th-percentile accuracy is 150 m (geocoded street address); 75th percentile is 17,477 m (state/zip/county centroid). The accuracy filter is load-bearing. Facilities with
FAC_COLLECTION_METHOD ∈ {ADDRESS MATCHING-HOUSE NUMBER, GDT-ADDRESS MATCHING, GPS}and accuracy ≤ 1 km are HIGH-confidence; ≤ 100 m additionally; coarser drops.- Cross-program identifiers are the key value-add. Each FRS facility carries up to six program-tier identifiers:
AIR_IDS(Clean Air Act / AIRS),NPDES_IDS(NPDES water permits),RCRA_IDS(hazardous waste handlers),TRI_IDS(Toxic Release Inventory),GHG_IDS(Greenhouse Gas Reporting),SDWA_IDS(Safe Drinking Water Act). FF emits one FacilityIdentifier per program ID, anchoring future cross-source matching against program-specific datasets.
This is the reference for the v1 EPA FRS fetcher: slim Facility +
multi-row Classification + FacilityIdentifier (per-program) +
FacilityAttribute (compliance metadata).
Publisher. US Environmental Protection Agency, Office of Enforcement and Compliance Assurance (OECA), via the ECHO program. ECHO ("Enforcement and Compliance History Online") is the consumer surface over the Facility Registry Service (FRS) - EPA's master registry of ~3 M facilities subject to environmental regulation.
License. US federal-government work - public domain
(17 U.S.C. § 105). No registration, attribution, or fees. Cite per the
canonical citation in release.py.
Coverage. All US facilities regulated by one or more EPA programs: Clean Air Act stationary sources, NPDES water dischargers, RCRA hazardous waste handlers, TRI reporters, GHGRP reporters, SDWA public water systems, federal facilities. Includes Indian Country, US-Mexico border zones, Chesapeake Bay watershed.
Vintage. The ZIP Last-Modified HTTP header dates the snapshot;
ECHO Exporter refreshes weekly.
Two artefact families. The first ships every facility row with pre-joined cross-program identifiers; the second carries the affiliation block ECHO Exporter omits.
ECHO_EXPORTER.csv (inside echo_exporter.zip, ~442 MB) - 133
columns, ~3.14 M rows, ~2 GB. Header row + double-quoted
comma-separated values (RFC 4180 compliant - unlike MSHA, EPA escapes
internal quotes properly). The fetcher's first parse pass.<STATE>_ORGANIZATION_FILE.CSV (inside per-state
state_combined_<state>.zip at ordsext.epa.gov, ~233 MB / state)REGISTRY_ID, AFFILIATION_TYPE (OWNER / OPERATOR /
PARENT COMPANY / etc.), ORG_NAME, ORG_TYPE (PRIVATE /
STATE / MUNICIPAL / FEDERAL / TRIBE / OTHER / UNKNOWN). Fetched
per-state best-effort (single-state failure logs a warning and
skips); the fetcher walks all 51 codes.The ECHO schema is documented at
https://echo.epa.gov/tools/data-downloads/echo-exporter-data-files.
The state-combined index is at
https://www.epa.gov/frs/epa-state-combined-csv-download-files.
For each admitted row the parser emits:
Facility - canonical_name = FAC_NAME, coords from
FAC_LAT / FAC_LONG, country_iso2 = "US",
region = FAC_STATE, locality = FAC_COUNTY + FAC_CITY,
status mapped from FAC_ACTIVE_FLAG. coordinate_confidence is
HIGH when FAC_ACCURACY_METERS ≤ 100, MEDIUM ≤ 1000, else the
row is dropped.FacilityIdentifier rows:
epa_registry_id (always present; the REGISTRY_ID column).epa_air_id (one per ID in the comma-separated AIR_IDS).epa_npdes_id (one per ID in NPDES_IDS).epa_rcra_id (one per ID in RCRA_IDS).epa_tri_id (one per ID in TRI_IDS).epa_ghg_id (one per ID in GHG_IDS).epa_sdwa_id (one per ID in SDWA_IDS).Classification rows:
naics (rev 2022) - one row per code in
FAC_NAICS_CODES, primary on the first code.isic (rev 5) - one row per the ff_naics_to_isic
derivation.ff_process_role - derived from NAICS
sector (extraction for 21, beneficiation for some 21+331,
fabrication/assembly for 33, etc.).FacilityAttribute rows:
coordinate_collection_method (FAC_COLLECTION_METHOD)coordinate_accuracy_meters (FAC_ACCURACY_METERS)coordinate_reference_point (FAC_REFERENCE_POINT)is_federal_facility (FAC_FEDERAL_FLG)is_indian_country (FAC_INDIAN_CNTRY_FLG)After the ECHO row stream completes, the parser walks each
<STATE>_ORGANIZATION_FILE.CSV and emits affiliation records for
admitted facilities (the second pass keys on the
REGISTRY_ID -> facility_id map built during the ECHO pass). For
each admitted ORGANIZATION row:
Entity - entity_id = epa_frs_organization:<sha1_first16>
keyed on the normalised ORG_NAME. The same corp operating five
sites collapses to one Entity. Confidence is MEDIUM for
structural-bucket rows (government / utility / tribal) and LOW
otherwise. entity_type = state_vehicle for structural-bucket,
corporation otherwise. jurisdiction = US-<state> from the per-
state file the row came from.OperatorReference - role mapped from AFFILIATION_TYPE:
OWNER → owner, OPERATOR → operator, OWNER/OPERATOR →
operator, PARENT COMPANY{,1,2} / PARENT OWNER →
parent_guarantor, TRANSMISSION OR DISTRIBUTION SYSTEM OWNER /
PART PARENT OWNER → owner. Confidence MEDIUM (EPA's regulatory
intake is stronger than name-block synthesis but weaker than a
CIK / LEI hard anchor, which EPA doesn't carry).The admit filter excludes sole-prop / fictitious-name rows (~70 % of
the 1.07 M CA OWNER / OPERATOR / PARENT rows). Keep iff ORG_NAME
carries a corporate suffix (Inc / LLC / Corp / Co. / Ltd / LP /
Holdings / Trust / Group / Industries / Partners / GmbH / SA / NV
etc.) or ORG_TYPE is a structural government / utility /
tribal bucket. ORG_TYPE = OTHER (762 K of CA's 1.07 M) is the
unhelpful catch-all; the corp-suffix gate carries the load there.
Not emitted (out of FF Phase 1 scope):
FAC_3YR_COMPLIANCE_HISTORY,
per-program *_COMPLIANCE_STATUS, penalty amounts, inspection
counts, etc.). These belong in a future EHS-attribute submodule.FAC_DATE_LAST_INSPECTION is enforcement metadata, not facility
history.<STATE>_CONTACT_FILE.CSV. That file carries individual contacts
(names + phones + emails) which don't fit the OperatorReference
contract; would need a separate Contact record kind.Why filter at all? 3.14 M rows × ~7 record types per row = ~22 M records - most of them irrelevant to FF's "industrial production facilities" remit.
The four filters:
FAC_ACTIVE_FLAG = 'Y'. Drops historical / decommissioned
facilities. Keeps 1.37 M of 3.14 M.FAC_LAT and FAC_LONG non-null.
Keeps 3.08 M.FAC_ACCURACY_METERS ≤ 1000. Drops state-centroid
(≈100 km), zip-centroid (≈10 km), county-centroid (≈30 km), and
sentinel 999999999 rows. Keeps 887 K - the geocoded subset.21 mining/oil-gas, 22 utilities, 31/32/33
manufacturing}. Keeps ~148 K.NAICS prefix filtering is the most opinionated choice. Specifically excludes:
11 Agriculture / Forestry / Fishing - out of FF's "industrial
production" remit.42-49 Wholesale / Retail / Transport - gas stations and
warehouses dominate; not facility-foundational.51-81 Information / FIRE / Education / Health / Other -
almost entirely non-industrial.92 Public Administration - government offices.Mining, utilities, and manufacturing capture the FF-relevant industrial production footprint cleanly.
FAC_ACCURACY_METERS | Bucket | FF coordinate_confidence |
|---|---|---|
| ≤ 100 m | Geocoded address | HIGH |
| 100 - 1000 m | Coarse geocode | MEDIUM |
| > 1000 m | Centroid / dropped | (admission filter blocks) |
null | Unknown - admission filter blocks (we don't admit unknown-accuracy rows) |
This is stricter than MRDS (which admits everything regardless of coord quality) and stricter than MSHA (which has no accuracy field). The strictness is intentional: EPA FRS is exactly where coordinate quality matters most for cross-source matching, since synthesis uses coord distance as 40 % of the composite score.
The expected wins from adding EPA FRS to the synthesis layer:
docs/SCOPE.md.msha_mine_id:0402542 AND epa_registry_id:110000123 AND
epa_tri_id:CAxxxx. Phase 2 cross-source matching against TRI
data (in a future fetcher) will pivot on these IDs without
re-resolving identity.The per-state <STATE>_ORGANIZATION_FILE.CSV adds owner / operator /
parent-company affiliations the ECHO Exporter row stream cannot.
National 51-state verification on synth_884450a21531; the CA-only
intermediate run was synth_299ca740a801 (kept here as a sanity
checkpoint).
| Metric | Pre-organization-leg | CA-only run | National | Δ vs Pre |
|---|---|---|---|---|
entity/LINEAGE total | 4,618,239 | 4,629,578 | 4,690,403 | +72,164 |
| EPA FRS distinct entities | 0 | 11,339 | 72,164 | new |
EPA FRS OperatorReference | 0 | 34,602 | 297,213 | new |
Facilities with OperatorRef | 119,209 (20.7 %) | 129,751 | 190,101 (33.0 %) | +70,892 |
HIGH same_entity_as to FRS | - | 371 | 2,897 | new |
MEDIUM same_entity_as to FRS | - | 1,890 | 13,370 | new |
LOW same_entity_as to FRS | - | 1,692 | 8,581 | new |
| ENTITY_ALIAS total edges | 426,622 | 430,570 | 451,403 | +24,781 |
Facility coverage from 20.7 % → 33.0 % (+12.3 percentage points; +70,892 facilities now have an operator reference). EPA FRS dominates the OperatorReference universe: 297,213 of 366,607 total = 81 % of all FF operator references. The matcher's name-block pass synthesises 2,897 HIGH bridges from EPA FRS organisations, with the counterpart distribution:
| EPA FRS bridge target | HIGH bridges |
|---|---|
gleif_lei: | 2,243 |
sec_cik: | 654 |
Sample HIGH bridges (verbatim from the resolved tier):
STAR CUTTER COMPANY (epa_frs, US-MI) ↔ STAR CUTTER CO. (GLEIF
LEI 549300ELKX5LQ6SKLC44).WOLF FAMILY LLC (epa_frs, US-NY) ↔ WOLF FAMILY LLC (GLEIF
LEI 549300A4LQ8CUSJHBS20).DYNOMAX INC (epa_frs, US-IL) ↔ DYNOMAX, INC. (GLEIF
LEI 549300RYR9SD5E3XFL95) - comma normalisation handles the punct.Largest CA operators by facility count (post-resolve):
| Operator (EPA FRS canonical name) | Facilities | Type |
|---|---|---|
| SOUTHERN CALIFORNIA EDISON CO. | 526 | corporation |
| PACIFIC GAS AND ELECTRIC COMPANY | 431 | corporation |
| PACIFIC GAS & ELECTRIC COMPANY | 378 | corporation † |
| CALIFORNIA WATER SERVICE COMPANY | 305 | corporation |
| CALIFORNIA WATER SERVICE CO | 190 | corporation † |
| SOUTHERN CALIFORNIA GAS COMPANY | 114 | corporation |
| EAST BAY MUNICIPAL UTILITY DISTRICT | 81 | state_vehicle |
† Name-fragmentation visible: ECHO ingests the same legal entity
under multiple casings ("AND" vs "&", "COMPANY" vs "CO"). The
synthesis name-block pass collapses these via same_entity_as at
matcher time; the underlying Entity store keeps both as distinct
nodes anchored on the verbatim ORG_NAME.
Filter rejection rate (national 5.81 M OWNER / OPERATOR / PARENT rows):
Cache contract. State zips + extracted ORGANIZATION_FILE CSVs
are cached at data/raw/epa_frs/<vintage>/state_files/. The
fetcher's per-state loop short-circuits before download when the CSV
is already on disk; re-running strata fetch epa_frs after
the initial sweep is a no-op for the network. On-disk footprint of
the state files: ~2.5 GB (zips + extracted CSVs).