EPA ECHO Scraper - Environmental Violations & Penalties avatar

EPA ECHO Scraper - Environmental Violations & Penalties

Pricing

from $2.10 / 1,000 facilities

Go to Apify Store
EPA ECHO Scraper - Environmental Violations & Penalties

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

Groundplane Labs

Maintained by Community

Actor 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, or rcra_rest_services) one state at a time for facilities with noncompliance in the 12-quarter reporting window (p_qiv=GE1).
  • Paginates get_qid immediately before the session QueryID expires, 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), isSNC boolean 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 lastPenaltyDate descending, then lastInspectionDate descending before applying maxItems. Sort semantics, stated plainly: any row with a lastPenaltyDate ranks ahead of rows without one, even when its totalPenalties5yrUsd is 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 (lastInspectionDate descending). 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), or RCRA (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): When true, keeps only facilities in Significant Noncompliance (CWA / RCRA SNC) or High Priority Violation (CAA HPV). 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.

FieldTypeDescription
registryIdstring | null12-digit EPA Facility Registry Service (FRS) identifier.
sourceIdstring | nullProgram-specific permit or handler ID (NPDES ID, ICIS-Air ID, or RCRA Handler ID).
facilityNamestring | nullFacility name reported to EPA ECHO.
streetstring | nullFacility street address.
citystring | nullFacility city.
statestring | nullTwo-letter state code.
zipstring | nullFacility ZIP code.
countystring | nullCounty name.
naicsCodesstring | nullSpace- or comma-separated NAICS codes associated with the facility.
sicCodesstring | nullSpace- or comma-separated SIC codes associated with the facility.
programstringRegulatory program queried (CWA, CAA, or RCRA).
complianceStatusstring | nullCurrent EPA ECHO compliance status label.
quartersInViolationLast12integer | nullNumber of quarters in noncompliance over the last 12 quarters (3 years).
isSNCbooleantrue if the facility is flagged for Significant Noncompliance (SNC) or High Priority Violation (HPV).
lastInspectionDatestring | nullMost recent inspection/evaluation date (YYYY-MM-DD).
daysSinceLastInspectioninteger | nullDays elapsed since the most recent inspection/evaluation.
formalActions5yrinteger | nullCount of formal enforcement actions over the past 5 years.
totalPenalties5yrUsdnumber | nullTotal formal enforcement penalties assessed over the past 5 years (USD).
lastPenaltyDatestring | nullDate of the most recent penalty assessment (YYYY-MM-DD).
echoUrlstring | nullDirect 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 facilityName and 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).

Limits and FAQ

  • Why do some rows show complianceStatus: "No Violation Identified" while quartersInViolationLast12 is greater than 0? EPA ECHO's p_qiv=GE1 filter 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 have quartersInViolationLast12 >= 1 and a current status of "No Violation Identified". Set onlySignificantNoncompliance: true to restrict results to active SNC/HPV facilities.
  • Why are formalActions5yr or lastPenaltyDate null 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 as null.
  • 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. A PARTIAL: 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, set onlySignificantNoncompliance to false, lower minPenaltiesUsd, or clear naicsPrefix.
  • 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 successful Complete: 0 run 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; isSNC now 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, QueryID pagination, SNC/HPV filtering, and penalty/inspection sorting.