EPA ECHO Scraper - Environmental Violations & Penalties
Pricing
from $2.10 / 1,000 facilities
EPA ECHO Scraper - Environmental Violations & Penalties
Scrape facilities with environmental violations or significant noncompliance under the Clean Water Act (CWA), Clean Air Act (CAA), or RCRA from EPA ECHO, with inspection history and 5-year penalties.
Pricing
from $2.10 / 1,000 facilities
Rating
0.0
(0)
Developer
Groundplane Labs
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
14 hours ago
Last modified
Categories
Share
Extract industrial, municipal, and commercial facilities with environmental violations or Significant Noncompliance (SNC / High Priority Violation) under the Clean Water Act (CWA), Clean Air Act (CAA), or Resource Conservation and Recovery Act (RCRA) directly from the U.S. Environmental Protection Agency (EPA) Enforcement and Compliance History Online (ECHO) web services.
What it does
EPA ECHO aggregates compliance evaluations, quarterly violation histories, and formal enforcement actions from state environmental agencies and EPA regional offices across the United States. Querying ECHO manually requires navigating separate statute-specific search forms (cwa_rest_services, air_rest_services, rcra_rest_services), handling short-lived session QueryID tokens, and mapping inconsistent column names across statutes.
This Actor:
- Queries EPA ECHO's official REST services (
cwa_rest_services,air_rest_services, orrcra_rest_services) one state at a time for facilities with noncompliance in the 12-quarter reporting window (p_qiv=GE1). - Paginates
get_qidimmediately before the sessionQueryIDexpires, respecting EPA rate limits (at most 2 requests/second with exponential backoff retries). - Normalizes statute-specific fields into a single consistent schema with facility address, NAICS/SIC codes, compliance status, quarters in violation (
quartersInViolationLast12),isSNCboolean flag, last inspection date, 5-year formal enforcement action count, 5-year total penalties in USD, last penalty date, and direct Detailed Facility Report URL (echoUrl). - Sorts results newest first by
lastPenaltyDatedescending, thenlastInspectionDatedescending before applyingmaxItems. Sort semantics, stated plainly: any row with alastPenaltyDateranks ahead of rows without one, even when itstotalPenalties5yrUsdis 0 (EPA ECHO can record a penalty date outside the 5-year penalty total window, or a penalty of $0). Rows are ordered first by how recent that penalty date is, and only then by inspection recency (lastInspectionDatedescending). So the top row is not necessarily the most recently inspected facility, and it is not necessarily a facility with a recent paid penalty.
Who it's for
- Environmental engineering & remediation firms identifying industrial facilities with active NPDES, Clean Air Act, or RCRA compliance issues.
- ESG, supply-chain & M&A due diligence teams screening manufacturing sites and suppliers for regulatory noncompliance and formal penalties.
- Industrial water treatment & emissions-control equipment vendors building targeted B2B facility lists by state and NAICS industry prefix.
- Policy researchers & journalists tracking enforcement actions, penalties, and inspection backlogs across states.
Input
All filters have sensible defaults that return Clean Water Act (CWA) violation records in Arizona (["AZ"]) in a few seconds.
program(string enum):CWA(Clean Water Act / NPDES),CAA(Clean Air Act stationary sources), orRCRA(Resource Conservation and Recovery Act hazardous waste). Default:"CWA".states(array of strings, required): 1 to 10 two-letter US state or territory postal codes (e.g.["AZ"]or["AZ", "NV", "NM"]). Default:["AZ"].onlySignificantNoncompliance(boolean): Whentrue, keeps only facilities in Significant Noncompliance (CWA/RCRASNC) or High Priority Violation (CAAHPV). Default:false.minPenaltiesUsd(integer): Minimum 5-year formal enforcement penalties in USD. Default:0.naicsPrefix(string): Optional 1- to 6-digit NAICS industry code prefix (e.g."32"or"2213"). Default:""(all industries).maxItems(integer): Maximum number of facility rows to return. Default:200.
Example input JSON
{"program": "CWA","states": ["AZ"],"onlySignificantNoncompliance": false,"minPenaltiesUsd": 0,"naicsPrefix": "","maxItems": 200}
Example run options (default max charge $50)
When starting a run via the Apify API or Console, set a default maximum charge of $50 ("maxTotalChargeUsd": 50) in your run options:
{"maxTotalChargeUsd": 50}
Output
Results are deduplicated by registryId + program and sorted newest first by lastPenaltyDate descending, then lastInspectionDate descending. Rows with a penalty date rank first even when the 5-year penalty total is 0, followed by inspection recency for rows tied on penalty date or without a penalty date. ECHO sometimes returns several permits (SourceIDs) for one registry, and they can disagree on compliance status: in that case the row kept is the most severe record (currently in SNC first, then most quarters in violation, then the latest inspection), not the first one returned.
| Field | Type | Description |
|---|---|---|
registryId | string | null | 12-digit EPA Facility Registry Service (FRS) identifier. |
sourceId | string | null | Program-specific permit or handler ID (NPDES ID, ICIS-Air ID, or RCRA Handler ID). |
facilityName | string | null | Facility name reported to EPA ECHO. |
street | string | null | Facility street address. |
city | string | null | Facility city. |
state | string | null | Two-letter state code. |
zip | string | null | Facility ZIP code. |
county | string | null | County name. |
naicsCodes | string | null | Space- or comma-separated NAICS codes associated with the facility. |
sicCodes | string | null | Space- or comma-separated SIC codes associated with the facility. |
program | string | Regulatory program queried (CWA, CAA, or RCRA). |
complianceStatus | string | null | Current EPA ECHO compliance status label. |
quartersInViolationLast12 | integer | null | Number of quarters in noncompliance over the last 12 quarters (3 years). |
isSNC | boolean | true if the facility is flagged for Significant Noncompliance (SNC) or High Priority Violation (HPV). |
lastInspectionDate | string | null | Most recent inspection/evaluation date (YYYY-MM-DD). |
daysSinceLastInspection | integer | null | Days elapsed since the most recent inspection/evaluation. |
formalActions5yr | integer | null | Count of formal enforcement actions over the past 5 years. |
totalPenalties5yrUsd | number | null | Total formal enforcement penalties assessed over the past 5 years (USD). |
lastPenaltyDate | string | null | Date of the most recent penalty assessment (YYYY-MM-DD). |
echoUrl | string | null | Direct link to the EPA ECHO Detailed Facility Report (https://echo.epa.gov/detailed-facility-report?fid=<registryId>). |
Sample output row (synthetic example)
{"registryId": "110099990001","sourceId": "AZ0099991","facilityName": "Example Desert Surface Processing Plant","street": "100 Industrial Parkway","city": "Phoenix","state": "AZ","zip": "85040","county": "Maricopa","naicsCodes": "327320","sicCodes": "3273","program": "CWA","complianceStatus": "Significant/Category I Noncompliance","quartersInViolationLast12": 4,"isSNC": true,"lastInspectionDate": "2026-06-15","daysSinceLastInspection": 138,"formalActions5yr": 1,"totalPenalties5yrUsd": 18500,"lastPenaltyDate": "2026-08-01","echoUrl": "https://echo.epa.gov/detailed-facility-report?fid=110099990001"}
How pricing works
Pay per result. You only pay for rows returned. The Actor checks your run's maximum spending limit before every dataset push (recommended default: "maxTotalChargeUsd": 50) and stops cleanly if that limit is reached.
Data source and terms
- Official source: U.S. EPA Enforcement and Compliance History Online (ECHO) Web Services and ECHO About the Data / Terms.
- Update frequency: EPA ECHO refreshes ICIS-NPDES (CWA), ICIS-Air (CAA), and RCRAInfo data weekly from federal and state reporting systems.
- Disclaimers:
- Facility data only, with a residual privacy risk: This Actor outputs facility-level regulatory records only. It does not seek personal information about individuals. Residual risk: a facility name in EPA ECHO can be a sole proprietor's personal name, and a facility address can in some cases be associated with an individual operator. Treat
facilityNameand address fields accordingly. - Status labels: "In violation", "Significant Noncompliance", and "High Priority Violation" are administrative status labels published by EPA ECHO based on federal/state agency data submissions and are not a legal finding of liability.
- This Actor is an independent tool and is not affiliated with or endorsed by the U.S. Environmental Protection Agency (EPA).
- Facility data only, with a residual privacy risk: This Actor outputs facility-level regulatory records only. It does not seek personal information about individuals. Residual risk: a facility name in EPA ECHO can be a sole proprietor's personal name, and a facility address can in some cases be associated with an individual operator. Treat
Limits and FAQ
- Why do some rows show
complianceStatus: "No Violation Identified"whilequartersInViolationLast12is greater than 0? EPA ECHO'sp_qiv=GE1filter selects facilities with at least one quarter of noncompliance in the 12-quarter (3-year) window. A facility that had a violation in an earlier quarter but returned to compliance in the most recent quarter will havequartersInViolationLast12 >= 1and a current status of"No Violation Identified". SetonlySignificantNoncompliance: trueto restrict results to active SNC/HPV facilities. - Why are
formalActions5yrorlastPenaltyDatenull on many rows? Most environmental compliance violations are resolved through informal notices or corrective actions without a formal penalty. When EPA ECHO reports no formal enforcement action or no penalty date for a facility, those fields are returned asnull. - How many states can I query at once? Up to 10 states per run. Each state is queried sequentially at a maximum of 2 requests/second to respect EPA ECHO server limits.
Canary input
A tiny input that returns at least 1 row in under 30 seconds:
{"program": "CWA","states": ["AZ"],"onlySignificantNoncompliance": false,"minPenaltiesUsd": 0,"naicsPrefix": "","maxItems": 5}
A healthy canary run ends with a status starting Complete: and every row validates against the output schema.
Troubleshooting
- Status starts with
PARTIAL:: The run finished but something was withheld or a source problem occurred (for example a state query failed, or EPA ECHO returned fewer rows than it reported). The status message states the concrete reason and the scanned / matched / emitted counts. APARTIAL:caused only by your own limits (max charge) is expected behavior; raise the limit to get more rows. - Zero matches (
Complete: 0 rows): The source is healthy but no facility matched your filters. Widen them: add states, setonlySignificantNoncompliancetofalse, lowerminPenaltiesUsd, or clearnaicsPrefix. - Run failed with a schema drift message: EPA ECHO renamed or dropped a column this Actor depends on. The failure message names the missing fields.
Found a problem or need a field? Open an issue on the Issues tab; we respond quickly.
Changelog
v0.1.3 (2026-11-01)
- Retry policy raised to 6 attempts with exponential backoff 2, 4, 8, 16, 32 s plus jitter, capped at 120 s. Retry-After is now parsed as seconds or as an HTTP-date. Added exampleRunInput matching the default input, description now starts with "Scrape", sort semantics and the residual privacy risk for facility names are documented plainly, and the 512 MB / 600 s resource choice is justified in TEST_NOTES.
v0.1.2 (2026-10-31)
-
Red Team fix round. High: the core-column sentinel now also covers the street, city, state, ZIP, county, and SIC columns for all three programs, so a rename there fails loudly instead of emitting nulls. Medium: the request read timeout is 90 s (the ECHO air service legitimately takes 36 to 110 s on filtered queries; a 30 s timeout failed whole CAA runs on latency alone). Medium: when ECHO returns several permits for one registry and they disagree, the dedupe now keeps the most severe record (current SNC first, then most quarters in violation, then the latest inspection) instead of the first row returned. Retry-After is honored on retried requests.
-
v0.1.1 (2026-10-31): Honest status contract (
Complete:/PARTIAL:with scanned, matched, and emitted counts; zero matches is now a successfulComplete: 0run instead of a failure); per-row output validation with a 20% skip limit; core-column sentinel that fails loudly on EPA ECHO schema drift; per-state failure isolation;isSNCnow reflects current SNC status only (historical SNC quarters alone no longer flag a facility); store category corrected to BUSINESS; default run options set (max charge $50). -
v0.1 (2026-10-31): Initial release supporting CWA, CAA, and RCRA facility violation queries,
QueryIDpagination, SNC/HPV filtering, and penalty/inspection sorting.