# EPA ECHO Scraper - Compliance, Violations & Enforcement Data (`scrapers_lat/epa-echo-scraper`) Actor

EPA ECHO scraper and API for US environmental compliance and enforcement data. Get facility violations, penalties, inspections, formal actions, per-program compliance, TRI releases, Superfund flags and enforcement cases across all 50 states. For ESG, KYB and due diligence. JSON, CSV, Excel export.

- **URL**: https://apify.com/scrapers_lat/epa-echo-scraper.md
- **Developed by:** [Scrapers Lat](https://apify.com/scrapers_lat) (community)
- **Categories:** Business, Automation, Other
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $6.15 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

[![EPA ECHO Facility Compliance & Violations Scraper](https://scrapers.lat/banners/epa-echo-scraper.png)](https://console.apify.com/actors/SKioxlSEARmV8LkNF/input)

## EPA ECHO Scraper: Facility Compliance, Violations & Enforcement Data

Here is one real result (a Clean Air Act significant violator with $6.1M in penalties), showing the fields this actor returns:

```json
{
  "facilityName": "BIG LAKE PLANT",
  "address": "6 MI. E. OF BIG LAKE, TX.",
  "city": "BIG LAKE",
  "county": "REAGAN",
  "state": "TX",
  "zip": "76932",
  "lat": 31.152959,
  "lng": -101.344583,
  "registryId": "110007180790",
  "naics": "211112 211130 211111 32411 325311",
  "sic": null,
  "complianceStatus": "Significant Violation",
  "inspectionsLast5yr": 0,
  "violationsCurrent": 1,
  "significantNonComplianceFlag": true,
  "programsWithSnc": 1,
  "formalActionsLast5yr": 2,
  "penaltyCount": 2,
  "totalPenaltiesUsd": 6125000,
  "lastFormalActionDate": "2022-02-17",
  "lastPenaltyDate": "2022-02-17",
  "programIds": {"AIR": ["TX0000004838300003"], "RMP": ["100000112219"], "EIS": ["7552311"]},
  "dfrUrl": "https://echo.epa.gov/detailed-facility-report?fid=110007180790",
  "epaRegion": "06",
  "countyFips": "48383",
  "majorFacility": true,
  "activeFacility": true,
  "currentViolationFlag": true,
  "currentSignificantViolationFlag": true,
  "caaHighPriorityViolator": true,
  "quartersInNoncompliance": 12,
  "threeYearComplianceHistory": "SSSSSSSSSSSS",
  "complianceByProgram": {"CAA": "Violation Unaddressed; State Has Lead Enforcement"},
  "permitTypes": {"CAA": "Major Emissions"},
  "programs": {"air": true, "superfund": false, "toxicSubstances": false, "emissionsInventory": true},
  "formalActionsByProgram": {"CAA": 2},
  "penaltiesByProgramUsd": {"CAA": 6125000},
  "lastPenaltyAmountUsd": 3000000,
  "sncByProgram": {"CAA": true, "CWA": false, "RCRA": false, "SDWA": false},
  "quartersInNoncomplianceByProgram": {"CAA": 12},
  "complianceHistoryByProgram": {"CAA": "SSSSSSSSSSSS"},
  "lastFormalActionDateByProgram": {"CAA": "2022-02-17"},
  "lastPenaltyByProgramUsd": {"CAA": 3000000},
  "lastFormalActionDateEpa": "2022-02-03",
  "lastFormalActionDateState": "2022-02-17",
  "federalCaseIds": ["06-2019-3401", "TX000A770410852022168", "TX000A852464042019025"],
  "percentPeopleOfColor": 52.17,
  "percentLowIncome": 39.13,
  "populationDensity": 0.81,
  "congressionalDistrict": "23",
  "watershed": "Middle Concho",
  "observedAt": "2026-09-04T00:28:26.409Z",
  "programSummaries": [
    {"statute": "CAA", "currentStatus": "High Priority Violation", "lastInspection": "2020-10-19", "qtrsInNonCompliance": 12, "qtrsInSignificantNonCompliance": 12, "formalActions": 2, "totalPenaltiesUsd": 6125000}
  ],
  "formalActions": [
    {"statute": "CAA", "actionType": "Civil Judicial Action", "actionDate": "2022-02-17", "leadAgency": "State", "penaltyUsd": 3000000, "sourceId": "TX0000004838300003"},
    {"statute": "CAA", "actionType": "Civil Judicial Action", "actionDate": "2022-02-03", "leadAgency": "EPA", "penaltyUsd": 3125000, "sourceId": "TX0000004838300003"}
  ],
  "enforcementCases": [
    {"statute": "CAA", "caseId": "06-2019-3401", "caseType": "Judicial", "caseName": "WTG Gas Processing (R6 Lead)-8 Facilities TX NM-RMP Consent Decree-FY2022", "epaSystem": "ICIS-Air", "leadAgency": "EPA", "issueDate": "2021-09-13", "settlementDate": "2022-02-03", "federalPenaltyUsd": 3125000, "stateLocalPenaltyUsd": 0, "penaltyCollectedUsd": 3125000}
  ]
}
```

Some fields are omitted above for brevity (see the full [output reference](#output-reference)); `null` values and the AI add-on fields are not shown.

The most complete EPA ECHO scraper and EPA compliance data API on Apify. It returns the fields the ECHO facility search and Detailed Facility Report expose, from location, NAICS/SIC, and per-program compliance status to environmental violations, significant non-compliance and high-priority-violator flags, inspections, formal and informal enforcement actions, penalties, federal enforcement cases with settlement amounts, TRI chemical releases, Superfund and RMP program membership, and environmental-justice demographics, plus two optional AI add-ons. It gives you 24 filters to target exactly the facilities you need, more input filters and more valid output fields than any other EPA ECHO, environmental compliance, or facility enforcement scraper listed. Pull facility enforcement history, environmental violations, and EPA penalties for environmental due diligence, KYB and supplier risk, ESG screening, and compliance monitoring.

**📥 [Input](https://apify.com/scrapers_lat/epa-echo-scraper/input-schema) · 📤 [Output](https://apify.com/scrapers_lat/epa-echo-scraper/output-schema) · 💰 [Pricing](https://apify.com/scrapers_lat/epa-echo-scraper/pricing) · ▶️ [Examples](https://apify.com/scrapers_lat/epa-echo-scraper/examples)**

![Apify](https://img.shields.io/badge/Platform-Apify-1CE1CE?logo=apify\&logoColor=white)
![Coverage](https://img.shields.io/badge/Coverage-United%20States-blue)
![Output](https://img.shields.io/badge/Output-JSON%20%7C%20CSV%20%7C%20Excel-orange)
![Billing](https://img.shields.io/badge/Billing-Pay%20per%20result-brightgreen)

### Table of contents

- [What it does](#what-it-does)
- [How we compare](#how-we-compare)
- [Use cases](#use-cases)
- [Quickstart](#quickstart)
- [Input reference](#input-reference)
- [Output reference](#output-reference)
- [Example output record](#example-output-record)
- [Run via API and CLI](#run-via-api-and-cli)
- [Fetch results](#fetch-results)
- [Billing and limits](#billing-and-limits)
- [FAQ and troubleshooting](#faq-and-troubleshooting)

### What it does

The actor queries EPA's Enforcement and Compliance History Online (ECHO), applies the filters you pass, and writes one normalized record per regulated facility to the run's dataset. Each record carries the facility name and address, geocoordinates, NAICS/SIC industry codes, EPA registry id, overall and per-program compliance status, current violations, significant non-compliance and high-priority-violator flags, quarters in noncompliance, formal and informal enforcement actions and penalties over the last five years, inspection history, program membership (including Superfund/SEMS, Risk Management Plan, and TSCA), TRI and greenhouse-gas reporting, and environmental-justice demographic context.

With details enabled (the default), each facility is enriched from its Detailed Facility Report (DFR): a per-program compliance breakdown (Clean Air, Clean Water/NPDES, RCRA hazardous waste, Safe Drinking Water), the list of formal enforcement actions with penalty amounts and dates, federal enforcement cases with their federal/state settlement penalty breakdown, and per-chemical TRI release history. Two optional paid AI add-ons produce a plain-language compliance summary and a regulatory risk rating.

### How we compare

Several EPA ECHO scrapers exist on Apify, including `compute-edge/epa-echo-scraper`, `fortuitous_pirate/epa-echo-facilities`, `neuton/epa-echo-facilities-compliance-scraper`, `ryanclinton/epa-echo-search`, `changewire/epa-echo-compliance`, and `ntriqpro/epa-environmental-risk`, plus TRI-only tools like `copious_atoll/epa-toxic-releases`. Most are facility locators with a handful of fields and a narrow filter set, and cover only the Clean Air, Clean Water, and RCRA programs. This actor returns the fullest compliance and enforcement record, adds Safe Drinking Water, TRI, greenhouse-gas, Superfund, RMP, and TSCA coverage, and gives you the widest set of filters, so you can pull exactly the non-compliant, high-penalty, or industry-specific facilities you need in one run.

| Capability | scrapers.lat EPA ECHO | Other EPA ECHO scrapers on Apify |
|---|---|---|
| Violations, penalties, inspections, formal + informal actions | Yes, all included | Cheapest ones return facility name/address/ID only, no enforcement data |
| Per-program compliance breakdown (Air, Water/NPDES, RCRA, SDWA) | Yes, from the Detailed Facility Report | Rarely, or overall status only |
| Significant non-compliance and high-priority-violator flags (overall + per program) | Yes | Usually missing |
| Quarters-in-noncompliance and 12-quarter compliance-history strings (overall + per program) | Yes | Not offered |
| Federal enforcement cases with settlement penalty breakdown (federal / state / collected) | Yes, from the DFR | Not offered |
| TRI chemical-level release history and on-site / off-site split | Yes | TRI-only tools cover chemicals; general ECHO scrapers do not |
| Superfund (SEMS), Risk Management Plan (RMP), and TSCA program membership | Yes | Not offered |
| Filter by NAICS or SIC industry code | Yes | Most support state/city only |
| Filter by EPA program, region, major, federal, tribal land | Yes | Partial, one or two at most |
| Compliance-signal filters (violations only, enforcement only, min penalty, inspected/enforced since) | Yes | Not offered |
| Geographic radius search (lat/lng + miles) | Yes | Some support it, most do not |
| Direct FRS Registry ID lookup | Yes | Some support it |
| Environmental-justice demographics (percent minority / low income / population density) | Yes | Not offered |
| Greenhouse-gas reporting, congressional district, watershed context | Yes | Not offered |
| Optional AI compliance summary and regulatory risk score | Yes | Not offered |
| No API key, no user-supplied proxy, no browser | Yes | Some require you to bring your own proxy |
| No charge on failed or empty runs | Yes | Varies |

Filter breadth and output completeness are the real difference. No other listed EPA ECHO scraper combines NAICS, program, compliance status, geographic radius, and enforcement date range while also returning the full penalty, inspection, per-program enforcement record, federal enforcement cases, and TRI chemical detail. Some rivals do things we do not: `changewire/epa-echo-compliance` and `getascraper/epa-echo-violation-monitor` are change-diff monitors that track day-over-day enforcement changes, which is a different job from this actor's full-record extraction.

### Use cases

- **Environmental due diligence and M\&A.** Screen a target company's facilities for open violations, significant non-compliance, penalty history, and pending enforcement before a deal closes.
- **KYB and supplier / vendor risk.** Add EPA compliance status and regulatory penalty history to know-your-business checks on US suppliers, counterparties, and portfolio companies.
- **ESG and sustainability screening.** Pull Clean Air, Clean Water, and hazardous-waste compliance signals, TRI releases, and greenhouse-gas reporting flags to score environmental risk across a portfolio.
- **Compliance monitoring.** Track a watchlist of facilities by FRS Registry ID or region and re-run to catch new inspections, formal actions, and penalties.
- **Legal and enforcement research.** Build case lists of significant violators or high-penalty facilities by state, industry, or program for regulatory, litigation, or expert-witness work.
- **Journalism and public-interest research.** Map environmental violations and enforcement in a city, county, or ZIP code, cross-referenced with environmental-justice demographics.
- **Real-estate environmental risk.** Run a radius search around a parcel to find nearby regulated facilities, hazardous-waste sites, and impaired-water or nonattainment-area flags.

### Quickstart

Open the actor, paste this into the input, and press Run. It returns up to 10 facilities in Austin, TX with their compliance detail.

```json
{
  "state": "TX",
  "city": "AUSTIN",
  "withDetails": true,
  "maxFacilities": 10
}
```

Every input is optional. State is the most reliable primary filter. Add `onlyWithViolations`, `minPenaltyUsd`, or `naicsCode` to focus on non-compliant or industry-specific facilities.

### Input reference

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `state` | enum | no | (any) | Two-letter US state or territory code, for example `CA`, `NY`, `TX`, `PR`. The most reliable primary filter. |
| `county` | string | no | (empty) | County name, for example `ALAMEDA`, `HARRIS`. Combine with `state`. |
| `city` | string | no | `AUSTIN` | City name, for example `HOUSTON`. Combine with `state`. |
| `zipCode` | string | no | (empty) | 5-digit US ZIP code. |
| `facilityName` | string | no | (empty) | Facility name to match, for example `CHEVRON`, `US STEEL`. Partial matches supported. |
| `registryId` | string | no | (empty) | Look up one exact facility by its EPA FRS Registry ID, for example `110033527805`. |
| `naicsCode` | string | no | (empty) | Industry NAICS code, full or prefix, for example `3254` or `324`. |
| `sicCode` | string | no | (empty) | Industry SIC code, for example `2911`. |
| `program` | enum | no | (all) | Restrict to one EPA program: `A` Clean Air, `W` Clean Water (NPDES), `R` RCRA hazardous waste, `S` Safe Drinking Water, `T` Toxics Release Inventory, `G` Greenhouse Gas, `E` EPCRA. |
| `epaRegion` | enum | no | (all) | Restrict to one EPA Region (`01` to `10`). |
| `activeOnly` | boolean | no | `false` | Restrict to facilities currently flagged active in EPA program systems. |
| `majorOnly` | boolean | no | `false` | Restrict to facilities classified as major under Clean Air or Clean Water programs. |
| `federalFacilitiesOnly` | boolean | no | `false` | Restrict to federally owned or operated facilities. |
| `tribalLandOnly` | boolean | no | `false` | Restrict to facilities in Indian country / tribal land. |
| `latitude` | string | no | (empty) | Center-point latitude for a radius search. Provide with `longitude` and `radiusMiles`. |
| `longitude` | string | no | (empty) | Center-point longitude for a radius search. |
| `radiusMiles` | integer | no | (none) | Search radius in miles around the lat/lng point. |
| `onlyWithViolations` | boolean | no | `false` | Keep only facilities with a current violation in any program. |
| `onlyWithEnforcement` | boolean | no | `false` | Keep only facilities with at least one formal enforcement action in the last 5 years. |
| `onlySignificantViolators` | boolean | no | `false` | Keep only facilities flagged as significant non-compliers or high-priority violators. |
| `minPenaltyUsd` | integer | no | (none) | Keep only facilities whose total assessed penalties are at least this amount. |
| `inspectedSince` | string | no | (empty) | Keep only facilities last inspected on or after this date (`YYYY-MM-DD`). |
| `enforcedSince` | string | no | (empty) | Keep only facilities whose most recent formal enforcement action was on or after this date (`YYYY-MM-DD`). |
| `withDetails` | boolean | no | `true` | Enrich each facility with its Detailed Facility Report (per-program compliance and enforcement actions). |
| `maxFacilities` | integer | no | `10` | Maximum facilities to collect. |
| `withSummary` | boolean | no | `false` | Paid AI add-on. Plain-language summary of the facility's compliance profile. Billed only on usable AI output. |
| `withRisk` | boolean | no | `false` | Paid AI add-on. Regulatory risk rating (low/medium/high/severe) with a 0 to 100 score. Billed only on usable AI output. |

Filters combine with logical AND.

### Output reference

One dataset item per facility. Types: `string`, `number`, `integer`, `boolean`, `object`, `object[]`, or `null` when the source value is absent. Key fields:

| Field | Type | Description |
|---|---|---|
| `facilityName` | string | Facility name. |
| `address` / `city` / `county` / `state` / `zip` | string | Facility mailing address parts. |
| `lat` / `lng` | number | Facility geocoordinates. |
| `registryId` | string | EPA FRS registry id (unique per facility). |
| `naics` / `sic` | string | Industry codes (space-separated when multiple). |
| `federalFacility` | boolean | Whether the facility is federally owned/operated. |
| `federalAgencyName` | string | Owning federal agency when applicable. |
| `complianceStatus` | string | Overall current compliance status. |
| `inspectionsLast5yr` | integer | Inspections in the last 5 years. |
| `violationsCurrent` | integer | Count of current violations. |
| `significantNonComplianceFlag` | boolean | Whether the facility is in significant non-compliance. |
| `programsWithSnc` | integer | Number of programs with significant non-compliance. |
| `formalActionsLast5yr` | integer | Formal enforcement actions in the last 5 years. |
| `informalActionsLast5yr` | integer | Informal actions in the last 5 years. |
| `penaltyCount` | integer | Number of penalties assessed. |
| `totalPenaltiesUsd` | number | Total assessed penalties in USD. |
| `lastPenaltyAmountUsd` | number | Most recent penalty amount. |
| `lastInspectionDate` / `lastFormalActionDate` / `lastPenaltyDate` / `lastInformalActionDate` | string | Most recent event dates (`YYYY-MM-DD`). |
| `daysSinceLastInspection` | integer | Days since the last inspection. |
| `epaRegion` | string | EPA Region (`01` to `10`). |
| `countyFips` | string | County FIPS code. |
| `majorFacility` / `activeFacility` / `tribalLand` | boolean | Classification flags. |
| `nonattainmentArea` / `impairedWater` | boolean | Environmental-area flags. |
| `currentViolationFlag` / `currentSignificantViolationFlag` / `caaHighPriorityViolator` | boolean | Current-status violation flags. |
| `quartersInNoncompliance` | integer | Quarters in non-compliance. |
| `threeYearComplianceHistory` | string | Compact 12-quarter compliance history string. |
| `everViolationFlag` / `enforcementActionLast5yrFlag` / `hasPollutantReport` | boolean | History flags: any past violation, any formal action in 5 years, has a pollutant report. |
| `programIds` | object | Program-system ids per statute (AIR, NPDES, RCRA, SDWA, TRI, GHG, SEMS/Superfund, RMP, TSCA, EIS, CAMD). |
| `programs` | object | Booleans for each program the facility is regulated under, including `superfund`, `toxicSubstances`, `emissionsInventory`. |
| `complianceByProgram` | object | Current compliance status per program. |
| `sncByProgram` | object | Significant-non-compliance / high-priority-violator boolean per program. |
| `quartersInNoncomplianceByProgram` | object | Quarters in noncompliance per program. |
| `complianceHistoryByProgram` | object | Compact 12/13-quarter compliance-history string per program. |
| `permitTypes` | object | Permit type per program. |
| `inspectionsByProgram` / `formalActionsByProgram` / `informalActionsByProgram` / `penaltiesByProgramUsd` | object | Per-program counts and penalty totals (inspections cover CAA, CWA, RCRA, SDWA, EPCRA, TSCA, FIFRA). |
| `lastFormalActionDateByProgram` / `lastPenaltyByProgramUsd` | object | Most recent formal action date and penalty amount per program. |
| `cwaEffluentExceedances13qtr` | integer | Clean Water effluent limit exceedances over the last 13 quarters. |
| `lastInspectionDateEpa` / `lastInspectionDateState` / `lastFormalActionDateEpa` / `lastFormalActionDateState` | string | Most recent action dates split by EPA vs state lead. |
| `federalCaseCount` / `federalCaseLastDate` / `federalCasePenaltiesUsd` / `federalCaseIds` | mixed | Federal (EPA multimedia) enforcement case count, last date, total penalties, and case ids. |
| `ghgCo2ReleasesTons` | number | Greenhouse-gas CO2 releases in tons when reported. |
| `triReleasesTransfersLbs` / `triOnSiteReleasesLbs` / `triOffSiteTransfersLbs` | number | TRI releases and transfers in pounds when reported. |
| `triReporterInPast` | boolean | Whether the facility has reported to the Toxics Release Inventory. |
| `nonattainmentPollutants` / `nonattainmentCategories` | string | Clean Air Act nonattainment-area pollutants and categories. |
| `percentMinority` / `percentPeopleOfColor` / `percentLowIncome` / `populationDensity` | number | Environmental-justice demographics of the surrounding area. |
| `congressionalDistrict` / `watershed` / `tribes` | string | US congressional district, watershed (HUC-8) name, and tribal-land names. |
| `dfrUrl` | string | Link to the facility's Detailed Facility Report on ECHO. |
| `programSummaries` | object\[] | Per-program compliance summary (with details on). |
| `formalActions` | object\[] | List of formal enforcement actions with penalties and dates (with details on). |
| `enforcementCases` | object\[] | Federal/multimedia enforcement cases with statute, case type, dates, and federal/state/collected settlement penalties (with details on). |
| `triChemicals` | object\[] | Per-chemical TRI release/transfer amounts for the most recent reporting year (with details on, when the facility reports to TRI). |
| `observedAt` | string | ISO 8601 timestamp of when the record was collected. |
| `error` | string | `null` on success. On a failed run, a single item with a populated `error` field is written instead. |

Detail fields (`programSummaries`, `formalActions`, `enforcementCases`, `triChemicals`, and the per-program breakdowns) are populated only when `withDetails` is enabled. AI fields are added only when the matching add-on is on. Any field ECHO does not populate for a facility is returned as `null` (never invented).

### Example output record

Real record from a live run (input `{"state":"TX","city":"AUSTIN"}`), a facility with a large assessed penalty:

```json
{
  "facilityName": "ABF FREIGHT SYSTEM",
  "address": "8200 BAGBY DR",
  "city": "AUSTIN",
  "county": "TRAVIS",
  "state": "TX",
  "zip": "78724",
  "lat": 30.29007,
  "lng": -97.63394,
  "registryId": "110033527805",
  "naics": null,
  "sic": "4213",
  "inspectionsLast5yr": 0,
  "violationsCurrent": 0,
  "significantNonComplianceFlag": false,
  "formalActionsLast5yr": 1,
  "penaltyCount": 1,
  "totalPenaltiesUsd": 535000,
  "lastFormalActionDate": "2023-09-14",
  "lastPenaltyDate": "2023-09-14",
  "epaRegion": "06",
  "majorFacility": false,
  "activeFacility": true,
  "currentViolationFlag": false,
  "dfrUrl": "https://echo.epa.gov/detailed-facility-report?fid=110033527805",
  "observedAt": "2026-08-10T14:17:02.335Z",
  "error": null
}
```

### Run via API and CLI

Start a run and read the dataset. Replace `<TOKEN>` with your Apify API token.

Run synchronously and get dataset items in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~epa-echo-scraper/run-sync-get-dataset-items?token=<TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"state":"CA","onlyWithViolations":true,"minPenaltyUsd":100000,"maxFacilities":50}'
```

Start a run asynchronously:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~epa-echo-scraper/runs?token=<TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"state":"TX","naicsCode":"324","onlySignificantViolators":true,"maxFacilities":100}'
```

Apify CLI:

```bash
apify call scrapers_lat/epa-echo-scraper \
  --input '{"latitude":"29.7604","longitude":"-95.3698","radiusMiles":5}'
```

### Fetch results

Every run writes to a dataset. Fetch items as JSON, CSV, or Excel by changing `format`:

```bash
## JSON
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=json"

## CSV
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=csv"

## Paginate large datasets
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&offset=1000&limit=1000"
```

`<DATASET_ID>` is returned as `defaultDatasetId` in the run object. `clean=true` drops empty and internal fields.

### Billing and limits

- **Pay per result.** Each facility record bills on the `result` event. See the [pricing tab](https://apify.com/scrapers_lat/epa-echo-scraper/pricing) for the current per-result price.
- **Detail and AI events billed separately.** Fetching a Detailed Facility Report bills the `details` event. `withSummary` and `withRisk` bill the `ai_summary` and `ai_risk` events, and only when the AI returns usable output. The AI add-ons are off by default and require a paid Apify plan.
- **No charge on failure.** If a run errors, the actor writes a single item with a populated `error` field and does not charge for it. Empty runs cost nothing.
- **Spend cap respected.** Set `maxTotalChargeUsd` on the run; once reached, the actor stops emitting and charging further billable results.
- **Free Apify plans** are capped at 10 records per run. Upgrade for higher `maxFacilities`.
- **Source ceiling.** A single ECHO query returns at most a few hundred facilities. For larger pulls, split the work by state, county, or NAICS.

### FAQ and troubleshooting

**What is EPA ECHO?**
ECHO (Enforcement and Compliance History Online) is the US EPA's public system that tracks the environmental-compliance and enforcement history of regulated facilities. This actor turns ECHO's facility search and Detailed Facility Report into clean JSON, CSV, or Excel records, so you can query EPA compliance data at scale without the ECHO web interface.

**How do I find only facilities with violations or penalties?**
Set `onlyWithViolations`, `onlyWithEnforcement`, or `onlySignificantViolators` to `true`, and optionally `minPenaltyUsd` to a threshold. Add `enforcedSince` or `inspectedSince` to restrict to recent activity.

**How do I look up one specific facility?**
Pass its EPA FRS Registry ID as `registryId`. The actor returns that single facility with its full compliance and enforcement detail.

**How do I search around a point?**
Provide `latitude`, `longitude`, and `radiusMiles` together for a radius search, useful for real-estate or site environmental risk.

**Do I need an EPA API key, a proxy, or a browser?**
No. This actor needs no API key, no user-supplied proxy, and no headless browser. It handles data access internally and returns structured records directly.

**How fast is it?**
Facility search returns in about a second. With `withDetails` on, each facility also loads its Detailed Facility Report; detail fetches run in parallel, so a typical run of a few dozen facilities completes in seconds to a couple of minutes depending on `maxFacilities`.

**Can I use this for KYB, ESG, or environmental due diligence?**
Yes. The record includes compliance status, significant non-compliance flags, penalty totals, inspection and enforcement history, and per-program breakdowns, which are the signals used in supplier risk, ESG screening, and pre-deal environmental due diligence.

**What does the per-program breakdown include?**
With `withDetails` on, `programSummaries`, `complianceByProgram`, `sncByProgram`, `quartersInNoncomplianceByProgram`, `complianceHistoryByProgram`, `inspectionsByProgram`, `formalActionsByProgram`, `informalActionsByProgram`, and `penaltiesByProgramUsd` cover Clean Air, Clean Water, RCRA, and Safe Drinking Water where the facility is regulated.

**Does it return the actual enforcement cases and penalties?**
Yes. With `withDetails` on, `enforcementCases` lists each federal or state enforcement case with its statute, case type, issue and settlement dates, and a settlement penalty breakdown (federal penalty, state/local penalty, amount collected). `formalActions` lists formal actions with penalty amounts, and `federalCasePenaltiesUsd` / `totalPenaltiesUsd` give the rolled-up totals.

**Can I get chemical-level TRI emissions or Superfund status?**
Yes. `triChemicals` returns per-chemical TRI release and transfer amounts for the most recent reporting year, and `triOnSiteReleasesLbs` / `triOffSiteTransfersLbs` give the on-site and off-site split. Superfund (SEMS), Risk Management Plan (RMP), and TSCA membership appear in `programs` and `programIds` when the facility is in those systems.

**What are the percent-minority and percent-low-income fields?**
They are EPA environmental-justice demographics for the area around the facility, not the facility itself. They come from EPA's screening data.

**Why are some fields null?**
Not every program applies to every facility, and EPA does not report every metric for every site. Missing source values are returned as `null`, never invented.

**A run returned 0 records. Why?**
The filter combination matched nothing. Loosen filters (start with just `state`). Zero-result runs are not charged.

**Is this an official EPA tool?**
No. This actor is independent and is not affiliated with the US EPA. It reads only data published through the public ECHO system. Use it in accordance with EPA terms and applicable law.

### Related scrapers

- [openFDA Food Recall & Enforcement Scraper](https://apify.com/scrapers_lat/openfda-food-recalls-scraper): US FDA food recalls and enforcement.
- [USAspending Federal Award Scraper](https://apify.com/scrapers_lat/usaspending-awards-scraper): US federal prime awards.
- [BLM National Mining Claims (MLRS) Scraper](https://apify.com/scrapers_lat/blm-mining-claims-scraper): US BLM mining claims with PLSS legal descriptions.
- [SEC EDGAR Company Filings Scraper](https://apify.com/scrapers_lat/sec-edgar-filings-scraper): SEC filings by ticker or CIK.
- [Federal Register Document Scraper](https://apify.com/scrapers_lat/federal-register-scraper): US Federal Register documents.
- [Grants.gov Opportunity Scraper](https://apify.com/scrapers_lat/grants-gov-scraper): US federal grant opportunities.

### More scrapers at scrapers.lat

Built and maintained by [scrapers.lat](https://scrapers.lat), where we publish scrapers for US and Latin American public platforms: company registries, government data, finance, e-commerce and more. Browse the catalog or request a custom scraper at [scrapers.lat](https://scrapers.lat).

***

> Independent tool, not affiliated with the US EPA. Accesses only data publicly available through the EPA ECHO system. Use in accordance with EPA terms of use.

# Actor input Schema

## `maxFacilities` (type: `integer`):

Maximum number of facilities to collect. Optional. A single ECHO query returns at most a few hundred thousand rows, so narrow your filters for focused pulls.

## `withDetails` (type: `boolean`):

When enabled, each facility is enriched with its Detailed Facility Report (DFR): a per-program (Clean Air, Clean Water, RCRA, SDWA) compliance breakdown and the list of formal enforcement actions with penalty amounts and dates. Disable for a faster, list-only pull.

## `state` (type: `string`):

Two-letter US state or territory code, for example CA, NY, TX, PR. The most reliable primary filter.

## `county` (type: `string`):

County name, for example ALAMEDA, HARRIS, COOK. Combine with State.

## `city` (type: `string`):

City name, for example BERKELEY, HOUSTON. Combine with State.

## `zipCode` (type: `string`):

5-digit US ZIP code, for example 94704.

## `facilityName` (type: `string`):

Facility name to match, for example CHEVRON, US STEEL. Partial matches are supported.

## `registryId` (type: `string`):

Look up one exact facility by its EPA FRS Registry ID (the unique 12-digit facility id, for example 110033527805). Ignores the other search filters and returns that single facility with full compliance and enforcement detail.

## `naicsCode` (type: `string`):

Industry NAICS code, full or partial prefix, for example 3254 (pharmaceutical) or 324 (petroleum).

## `sicCode` (type: `string`):

Industry SIC code, for example 2911 (petroleum refining).

## `activeOnly` (type: `boolean`):

Restrict to facilities currently flagged active in EPA program systems.

## `majorOnly` (type: `boolean`):

Restrict to facilities classified as major under Clean Air or Clean Water programs (larger emitters and dischargers).

## `program` (type: `string`):

Restrict to facilities regulated under a single EPA program: Clean Air, Clean Water (NPDES), RCRA hazardous waste, Safe Drinking Water, Toxics Release Inventory, Greenhouse Gas or EPCRA.

## `epaRegion` (type: `string`):

Restrict to a single EPA Region (01 through 10). Optional; usually only needed for multi-state pulls.

## `federalFacilitiesOnly` (type: `boolean`):

Restrict to federally owned or operated facilities (military bases, federal agencies).

## `tribalLandOnly` (type: `boolean`):

Restrict to facilities located in Indian country / tribal land.

## `latitude` (type: `string`):

Center-point latitude for a radius search, for example 29.7604. Provide with Longitude and Radius to find facilities near a point.

## `longitude` (type: `string`):

Center-point longitude for a radius search, for example -95.3698.

## `radiusMiles` (type: `integer`):

Search radius in miles around the Latitude/Longitude point, for example 5.

## `onlyWithViolations` (type: `boolean`):

Keep only facilities flagged with a current violation in any program (Clean Air, Clean Water, RCRA or SDWA).

## `onlyWithEnforcement` (type: `boolean`):

Keep only facilities with at least one formal enforcement action in the last 5 years.

## `onlySignificantViolators` (type: `boolean`):

Keep only facilities currently flagged as significant non-compliers or high-priority violators.

## `minPenaltyUsd` (type: `integer`):

Keep only facilities whose total assessed penalties are at least this amount, for example 100000.

## `inspectedSince` (type: `string`):

Keep only facilities whose last inspection was on or after this date (YYYY-MM-DD), for example 2023-01-01.

## `enforcedSince` (type: `string`):

Keep only facilities whose most recent formal enforcement action was on or after this date (YYYY-MM-DD), for example 2022-01-01. Use with the compliance-signal filters to surface recent enforcement.

## `withSummary` (type: `boolean`):

Optional paid AI add-on, off by default. Adds a plain-language summary of each facility's environmental-compliance profile. Billed only when produced. Requires a paid Apify plan.

## `withRisk` (type: `boolean`):

Optional paid AI add-on, off by default. Rates each facility's regulatory risk (low/medium/high/severe) with a 0-100 score, red flags and rationale. Billed only when produced. Requires a paid Apify plan.

## Actor input object example

```json
{
  "maxFacilities": 10,
  "withDetails": true,
  "state": "TX",
  "city": "AUSTIN",
  "activeOnly": false,
  "majorOnly": false,
  "program": "",
  "epaRegion": "",
  "federalFacilitiesOnly": false,
  "tribalLandOnly": false,
  "onlyWithViolations": false,
  "onlyWithEnforcement": false,
  "onlySignificantViolators": false,
  "withSummary": false,
  "withRisk": false
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "maxFacilities": 10,
    "state": "TX",
    "city": "AUSTIN"
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapers_lat/epa-echo-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "maxFacilities": 10,
    "state": "TX",
    "city": "AUSTIN",
}

# Run the Actor and wait for it to finish
run = client.actor("scrapers_lat/epa-echo-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "maxFacilities": 10,
  "state": "TX",
  "city": "AUSTIN"
}' |
apify call scrapers_lat/epa-echo-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapers_lat/epa-echo-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/SKioxlSEARmV8LkNF/builds/ogXMTCeJEDlEZYKWm/openapi.json
