EPA ECHO Compliance Diff API — CAA, CWA, RCRA, SDWA Enforcement
Pricing
Pay per usage
EPA ECHO Compliance Diff API — CAA, CWA, RCRA, SDWA Enforcement
Daily diff feed for EPA ECHO. Emits JSONL records for every change to facility compliance status, violations, inspections, federal enforcement cases, or CAA/CWA/RCRA/SDWA permit listings. Replaces $30-200k/yr enterprise EHS-watch (Enhesa, Enviance) at $20-500/mo. For ESG analysts and EJ litigators.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
ChangeWire
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
13 hours ago
Last modified
Share
EPA ECHO API — Daily Facility Compliance Diff & Enforcement Case Tracker
Daily diff of every EPA Enforcement and Compliance History Online (ECHO) facility for environmental-justice litigators, ESG screening desks, facility-siting due-diligence teams, plaintiffs-bar trade press, and state-AG / tribal-environmental enforcement offices. Watches ECHO for compliance-status flips, new violations, new inspections, new and resolved federal enforcement cases, and permit additions across CAA / CWA / RCRA / SDWA programs — emits one JSONL change record per detected change.
What this does
- Tracks ~840k facilities across all four big federal programs (CAA stationary sources, CWA NPDES discharge permits, RCRA hazardous-waste handlers, SDWA public-water systems) with full diff coverage on six dimensions (compliance status / violations / inspections / enforcement cases / case resolutions / permits).
- Cuts polluter-watchlist latency from quarter to one day so environmental-justice litigators, ESG analysts, and trade-press reporters surface new violations and federal cases the same day ECHO refreshes rather than waiting for the next quarterly catch-all bulletin.
- Replaces $30-200k/yr Enhesa / Enviance / Intelex enterprise EHS-watch tiers with a metered pay-per-result Apify actor at $0.005 per change record (typically $20-500/month depending on watchlist size and violation activity).
Use cases
EPA ECHO API for environmental-justice litigators
A community-law nonprofit watches the 50 highest-emission CAA
facilities in its service area on registry_ids: [<50 ids>],
runs daily at 06:00 UTC, and routes the JSONL diff stream into
its case-intake queue. Any violation_added or
enforcement_case_added record routes straight to the staff
attorney with the facility name + before/after snapshot fields
- ECHO source URL. Cost: roughly 5-30 diff records/day across the 50-facility watchlist × $0.005 = $0.75-4.50/day = $20-135/mo. Replaces a $30-80k/yr Enhesa watch tier with same-day fidelity rather than next-business-day digest emails.
EPA enforcement compliance feed for ESG screening desks
An ESG portfolio-screening desk feeds the REGISTRY_IDs of 800 portfolio-company industrial facilities into the watchlist and runs daily. Each diff record becomes a structured event the screening committee's quarterly-flag pipeline can route per- holding into the firm's stewardship-engagement queue. The desk saves the engineering cost of building ECHO scraping in-house (~3-month FTE project at $200k+ loaded) and gets per-event semantics (compliance flip vs new violation vs new case vs case resolved) the desk doesn't have to derive from ECHO HTML reports.
EPA facility violation tracker for due diligence
A pre-acquisition diligence team filters this actor on a
specific state + programs combination (e.g. Texas + RCRA),
runs once at engagement kickoff to baseline against a known
target site's neighbors, then re-runs against the same input
30 days later and diffs the two snapshots. New violations or
enforcement cases against neighboring facilities surface
hidden remediation-cost exposure that title search and Phase I
ESA don't catch.
CAA CWA RCRA compliance API for plaintiffs-bar trade press
An Inside EPA / E&E News / Environmental Forum reporter
filters this actor with programs: ["CAA","CWA","RCRA","SDWA"]
only_in_violation: trueand runs daily. Newenforcement_case_addedrecords surface federal cases before the EPA press-release cycle catches up, giving the reporter 24-72 hours of beat advantage on the trade-press wire. The structuredchange_typefield lets the reporter tag each event by category for editorial prioritization without manual ECHO- report re-parsing.
EPA polluter watch tool for state-AG and tribal-environmental offices
A state-AG environmental enforcement unit filters on its state
code + program subset and watches for enforcement_case_added
records on facilities the unit cooperates with EPA on. The
structured event stream lets the unit's case-prioritization
desk react to federal cases faster and avoid duplicate-effort
filings against facilities EPA just hit. Tribal-environmental
offices similarly track federal enforcement against facilities
in or adjacent to reservation lands.
Input
See .actor/input_schema.json for the full schema. Key fields:
| Field | Type | Default | Description |
|---|---|---|---|
registry_ids | array of strings | [] | Specific EPA Facility Registry Service IDs (e.g. ["110000334761"]). Empty triggers state + program search. |
state | string | "" | Two-letter US state code; empty applies no state filter. |
programs | array of strings | ["CAA","CWA"] | Subset of {CAA, CWA, RCRA, SDWA}. |
only_in_violation | bool | false | Drop in-compliance facilities before diff. |
enable_enforcement_cases | bool | true | Walk per-facility federal enforcement-case detail. |
change_types | array of strings | all six | Subset of {compliance_status_change, violation_added, inspection_added, enforcement_case_added, enforcement_case_resolved, permit_change}. |
max_pages | int | 1 | Cross-program get_facilities pagination ceiling (1-25). |
page_size | int | 200 | Rows per page (50-500). |
snapshot_key | string | echo-snapshot-latest | Apify Key-Value Store key for previous snapshot. |
echo_base_url | string | https://echo.epa.gov/efservice | Override for offline test mirrors. |
rate_limit_rps | int | 2 | Polite RPS for ECHO GETs. EPA throttles aggressive callers. |
Realistic example input (50-facility environmental-justice litigator watchlist):
{"registry_ids": ["110000334761", "110000123456", "110000789012", "..."],"programs": ["CAA","CWA","RCRA"],"change_types": ["violation_added", "enforcement_case_added", "compliance_status_change"],"rate_limit_rps": 2}
Output
JSONL dataset; one record per detected change:
{"actor": "actor-7-epa-echo-compliance","schema_version": "1.0.0","extracted_at": "2026-05-22T06:00:00Z","registry_id": "110000334761","facility_name": "Acme Petroleum Refinery","program": "CAA","state": "TX","current_compliance_status": "Significant Violator","change_type": "enforcement_case_added","before": {"open_cases_count": 0},"after": {"open_cases_count": 1,"newest_case": {"case_number": "CAA-06-2026-1234","case_type": "Federal Civil Judicial","filed_date": "2026-05-20","statute": "Clean Air Act §113"}},"detected_at": "2026-05-22T06:00:00Z","source_url": "https://echo.epa.gov/detailed-facility-report?fid=110000334761"}
Apify Console preview shows an 8-column table view (registry id / facility / program / state / compliance / change type / detected at / ECHO URL) so analysts and non-engineers can sanity-check runs before piping into a screening pipeline.
Pricing & limits
- $0.005 per result (per detected diff record).
- $79/mo subscription tier for unlimited runs against a saved watchlist of up to 500 REGISTRY_IDs with daily refresh — better for buyers with high-violation watchlists.
- Free 7-day trial so you can verify diff fidelity against your own watchlist before committing.
- Recommended schedule: daily at 05:00–07:00 UTC (ECHO refreshes overnight; running this window catches the freshest changes).
- Estimated monthly cost:
- Environmental-justice litigator (~50 facilities, daily): $20-135/mo PPR or $79/mo subscription
- ESG portfolio screening (~800 facilities, daily): $120-350/mo PPR or $79/mo subscription if under 500 IDs
- Trade-press beat reporter (national-scope, in-violation only): $50-200/mo PPR
- Replaces Enhesa / Enviance / Intelex enterprise EHS tiers ($30-200k/yr) with metered per-event fidelity for the federal-environmental-data subset.
Data source & freshness
- Source: EPA ECHO REST service
(
https://echo.epa.gov/efservice) with optional per-facility detailed-facility-report enforcement walk. - Update cadence (source-side): ECHO's underlying database
refreshes daily for compliance-status flags + new violations +
inspections; federal enforcement-case data refreshes within
1-3 days of case-management-system entry. Quarterly ECHO
snapshots also publish to for bulk retrospective use.https://echo.epa.gov/tools/data- downloads
- Actor cadence (recommended): Daily 06:00 UTC. Running more often than ECHO refreshes is harmless but emits zero records.
- Public-records license: ECHO is published under the Clean
Air Act (42 USC §7414), Clean Water Act (33 USC §1318), RCRA
(42 USC §6927), and Safe Drinking Water Act (42 USC §300j-4)
public-disclosure mandates. 17 USC §105 removes copyright on
the underlying EPA records. EPA's robots.txt allows
/efservicepaths and asks for an identifying User-Agent. Actor sets a non-spoofed UA and defaults to 2 rps.
FAQ
What's the difference between ECHO and FRS?
ECHO (Enforcement and Compliance History Online) is the
buyer-facing report layer that aggregates 12-quarter rolling
compliance flags, violations, inspections, and enforcement
cases per facility. FRS (Facility Registry Service) is the
underlying registry-of-record that assigns each facility its
opaque REGISTRY_ID. ECHO records all carry a REGISTRY_ID; if
you have only a state + program search you don't need to
dereference FRS separately.
How does this compare to Enhesa or Enviance?
Enhesa / Enviance / Intelex / Sphera package ECHO watching as one feature in a $30-200k/yr enterprise EHS-management suite that also includes 50-state regulatory tracking, foreign- regulatory tracking, audit-management workflows, and human- curated weekly reports. This actor does only the federal- ECHO diff layer at $0.005 per change record. Pick this if your team already does its own multi-jurisdictional regulatory tracking and just needs a programmatic federal-ECHO feed; pick Enhesa if you need bundled global EHS + human-curated alerts
- audit workflows.
What's a REGISTRY_ID and how do I get a list?
REGISTRY_ID is EPA's opaque identifier for each facility in
the Facility Registry Service. It looks like a 12-digit
integer (e.g. 110000334761). Most buyers either (a) maintain
their own watchlist via prior ECHO searches, (b) get IDs from
a state-environmental-permit list, or (c) leave the field
empty and pass state + programs instead — the actor walks
EPA's get_facilities endpoint to build the watchlist on
the fly.
What change types does this detect?
Six dimensions: compliance_status_change (12-quarter
compliance label moves between buckets — In Compliance,
Significant Violator, etc.), violation_added (new violation
row), inspection_added (new inspection row),
enforcement_case_added (new federal case),
enforcement_case_resolved (open case got a settled_date
populated), permit_change (NPDES / Title V permit-IDs dict
gains or loses a key).
How does this handle the cross-program walk?
When registry_ids is empty, the actor walks
get_facilities once per program in the requested
programs subset, paginates up to max_pages per program
(default 1, max 25), then dereferences each unique
REGISTRY_ID through the detailed-facility-report endpoint.
The cross-program union is deduplicated on REGISTRY_ID before
diffing against the previous snapshot. Buyers tracking
specific portfolios should pass explicit registry_ids to
skip the listing-page round trip entirely (faster + cheaper).
Are there PII or attorney-client risks?
No. ECHO data describes regulated facilities and federal
enforcement actions — there is no individual-PII surface. The
actor still defaults to redacting any free-text contact-name
fields that occasionally appear in case-narrative blocks; set
redact_contact_names: false in the input schema only if your
buyer-cohort compliance posture clears full-text retention
(rare).
Can I watch by state-AG cooperation status?
Not directly — the actor exposes raw federal-enforcement-case data without secondary state-AG cooperation labels. State-AG units typically cross-reference the actor's federal-case output against their own state-case management system rather than asking the actor to filter for them. If state-AG cooperation labels become a frequent ask, file an issue and we'll add an enrichment dimension.
Does this cover SDWA public-water systems?
Yes — SDWA is fully supported in programs: ["SDWA"]. SDWA
records have a slightly different compliance-flag structure
than CAA / CWA / RCRA (water-system serious-violator vs
compliance-monitoring-only) — the actor maps SDWA buckets into
the same current_compliance_status field-shape as the other
programs to keep buyer-side schema clean.
Is there a rate-limit risk?
The actor self-limits to 2 rps and respects EPA's robots.txt
(allows /efservice paths). EPA throttles aggressive callers
above ~10 rps in practice; we stay well below. Bulk runs
against 1,000+ facilities take ~10-15 minutes wall time at
2 rps depending on per-facility detail walks.
Companion actors in this portfolio
changewire maintains a portfolio of federal-data diff actors. All
share the same daily-snapshot + JSONL change-record pattern, watchlist
filtering, and per-record change-type semantics. Pick the data domain
you need; mix and match across a single Apify account:
changewire/clinicaltrials-protocol-diff— NIH-registered trial protocol diffs.changewire/grantsgov-opportunity-alert— Daily diff of federal grant opportunities (status, deadline, award amount, eligibility).changewire/fda-orange-book-extraction— FDA Orange Book pharmaceutical applications + patent listings, daily diff. (currently hard-blocked at the Akamai WAF; awaiting routing fix)changewire/noaa-storm-events-diff— NOAA NCEI storm-event records (tornados, hail, floods) with daily incremental diff.changewire/uspto-ttab-docket-extractor— USPTO TTAB trademark docket records + filings + parties + deadlines, on-demand extraction.changewire/samgov-contracts-diff— SAM.gov federal contract opportunities, daily diff. (currently hard-blocked on identity-tied SAM.gov API key; awaiting user-machine key generation)
Running locally (for contributors)
cd actors/actor-7-epa-echo-complianceapify run --purge # uses .actor/input_schema.json defaults
State + program run:
$apify run --input '{"state": "TX", "programs": ["CAA","RCRA"], "max_pages": 3}'
Watchlist run with violation filter:
$apify run --input '{"registry_ids": ["110000334761","110000123456"], "only_in_violation": true}'
Legal
ECHO data is published by EPA under the Clean Air Act (42 USC §7414),
Clean Water Act (33 USC §1318), RCRA (42 USC §6927), and Safe Drinking
Water Act (42 USC §300j-4) public-disclosure mandates; 17 USC §105
removes copyright on the underlying records. Actor honors EPA's
robots.txt for /efservice paths, sets a non-spoofed identifying
User-Agent, and defaults to 2 rps to stay below ECHO's aggressive-
caller throttle. No PII in output: ECHO data describes regulated
facilities, not individuals. Free-text contact-name fields that
occasionally appear in case narratives are redacted on ingest by
default.