# EPA ECHO Scraper - Facilities, Violations & Compliance Leads (`scrapesage/epa-echo-scraper`) Actor

Scrape the official EPA ECHO database: regulated facilities with name, address, NAICS/SIC, Clean Air/Water/RCRA/SDWA compliance status, violations, inspections, enforcement, penalties & toxic releases. Filter by state, industry & noncompliance. B2B compliance leads + monitoring.

- **URL**: https://apify.com/scrapesage/epa-echo-scraper.md
- **Developed by:** [Scrape Sage](https://apify.com/scrapesage) (community)
- **Categories:** Lead generation, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 facility / compliance records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## EPA ECHO Scraper — Facilities, Violations & Environmental Compliance Leads

Extract **regulated facilities and their full environmental-compliance history** straight from **[EPA ECHO](https://echo.epa.gov)** (Enforcement and Compliance History Online) — the U.S. Environmental Protection Agency's official enforcement database. Every facility comes back as a ready-to-use **B2B lead**: name, full address, industry (NAICS/SIC), the programs it's regulated under (Clean Air Act, Clean Water Act, RCRA hazardous waste, Safe Drinking Water Act, Toxic Release Inventory, greenhouse gas, Superfund), its **compliance status, violations, inspections, formal enforcement actions, penalties and toxic-release totals**, plus a derived **lead score**.

No login, no cookies, no browser, **no API key** — fast, reliable extraction from EPA's public ECHO web services.

### Why this EPA ECHO scraper?

Generic "paste-a-URL" crawlers grab a few visible fields and miss the data that actually matters. This actor queries EPA's facility-search and Detailed Facility Report services directly and ships the **richest dataset in the category** — firmographics **and** every compliance, enforcement, penalty and toxic-release signal, in one clean table.

| Data | Thin EPA scrapers | This actor |
|---|---|---|
| Facility name, full address, county, EPA region, geo | partial | ✅ |
| Industry **NAICS + SIC** (codes + description) | ❌ | ✅ |
| Programs (CAA / NPDES / RCRA / SDWA / TRI / GHG / Superfund / TSCA / RMP) | one program only | ✅ all in one |
| Overall **+ per-program compliance status** | ❌ | ✅ |
| Significant-noncompliance (SNC) flag + quarters in noncompliance | ❌ | ✅ |
| Inspections (count + dates), informal & **formal enforcement** | partial | ✅ |
| **Penalties** (count, total $, last amount, per program) | ❌ | ✅ |
| **Toxic Release Inventory** (lbs released/transferred + multi-year chemical history) | ❌ | ✅ |
| Greenhouse-gas CO₂ totals, impaired-waters flag, demographics | ❌ | ✅ |
| **Detailed Facility Report** (per-statute summaries, every formal action, all permits) | ❌ | ✅ |
| Derived **lead score + lead signals** | ❌ | ✅ |
| Only-new / changed **monitoring mode** | ❌ | ✅ |

### Use cases

- **Environmental-services lead generation** — facilities in significant noncompliance, with open violations or recent penalties are in-market buyers for **environmental consulting, remediation, compliance/EHS software, air & water permitting, and legal services**. Export them with industry, address and lead score and feed your CRM.
- **Regulatory & legal intelligence** — track formal enforcement actions, penalties and SNC status across an industry or state for environmental and product-liability law firms.
- **ESG, due diligence & risk** — screen a portfolio, supply chain or acquisition target for environmental violations, penalties and toxic-release history.
- **Insurance & underwriting** — assess environmental risk by facility, program and enforcement history.
- **Market & competitive research** — map every regulated facility in a sector (refineries, power plants, chemical manufacturers, waste handlers) with size (major-facility flag) and compliance posture.
- **Community & journalism** — surface the biggest polluters and repeat offenders in a county or watershed.

### How to use

1. [Sign up for Apify](https://console.apify.com/sign-up) — the free plan is enough to try this actor.
2. Open the **EPA ECHO Scraper**, set a **state** (and optionally an **industry**, **program** or **compliance** filter), and choose your limit.
3. Click **Start** and watch facility records stream into the dataset table.
4. **Export** as JSON, CSV, Excel, XML, or RSS — or pull results programmatically via the [Apify API](https://docs.apify.com/api/v2).

### Input

```json
{
    "states": ["TX"],
    "naicsCodes": ["325"],
    "significantNoncomplianceOnly": true,
    "includeDetailedReport": true,
    "sortBy": "leadScore",
    "maxResults": 500
}
````

- **registryIds** — look up specific facilities by EPA FRS Registry ID. Leave empty to search with filters.
- **states / epaRegions / counties / cities / zipCodes** — location filters (all optional, combine with AND).
- **facilityNameQuery / streetQuery** — text-contains filters on the facility name or street.
- **naicsCodes / sicCodes** — industry filters (full code or prefix, e.g. `325` chemicals, `3241` petroleum, `2211` power, `562` waste).
- **programs** — keep only facilities under CAA, NPDES, RCRA, SDWA, TRI, GHG, SEMS (Superfund), TSCA or RMP.
- **activeOnly** *(default true)*, **majorFacilitiesOnly**, **federalFacilitiesOnly** — facility filters.
- **complianceStatus / significantNoncomplianceOnly / currentViolationsOnly** — compliance-intent filters.
- **hasPenaltiesOnly / minPenaltyAmount / hasFormalEnforcementOnly / minQuartersInNoncompliance** — enforcement filters.
- **inspectionRecency** — `within5yr`, `notWithin5yr` (overdue sites) or `neverInspected`.
- **includeDetailedReport** *(default false)* — enrich each facility with its full Detailed Facility Report (per-statute summaries, every formal action, all permits, TRI chemical history). Billed as `detailedReport`.
- **maxResults / sortBy / deduplicateResults** — output controls. Sort by `leadScore` (default), `penaltiesHigh`, `recentEnforcement`, `recentInspection`, or `source`.
- **monitorMode / monitorKey** — only return facilities that are new or whose compliance changed since the last run.
- **proxyConfiguration** — optional; the ECHO API needs no proxy, so leave it off for the fastest queries.

### Output

By default you get **one clean, dense table of facilities** — every column applies to every row. A facility record:

```json
{
    "registryId": "110000468093",
    "facilityName": "HF SINCLAIR PARCO REFINING CO LLC",
    "fullAddress": "100 E LINCOLN AVE, SINCLAIR, WY, 82334",
    "city": "SINCLAIR",
    "state": "WY",
    "zip": "82334",
    "county": "CARBON",
    "epaRegion": "08",
    "latitude": 41.78,
    "longitude": -107.11,
    "naicsPrimary": "324110",
    "naicsDescription": "Petroleum Refineries",
    "sicPrimary": "2911",
    "programs": ["Clean Air Act", "RCRA Hazardous Waste", "Toxic Release Inventory", "Greenhouse Gas Reporting", "Risk Management Plan"],
    "isMajor": true,
    "complianceStatus": "Significant Violation",
    "inSignificantNoncompliance": true,
    "quartersInNoncompliance": 12,
    "inspectionCount": 14,
    "lastInspectionDate": "2026-05-06",
    "formalActionCount": 4,
    "lastFormalActionDate": "2025-11-21",
    "penaltyCount": 2,
    "totalPenalties": 431500,
    "triReleasesTransfers": 425309,
    "echoScore": 100,
    "dfrUrl": "https://echo.epa.gov/detailed-facility-report?fid=110000468093",
    "leadScore": 100,
    "leadSignals": ["Significant noncompliance (SNC)", "4 formal enforcement actions", "12 of last 12 quarters in noncompliance", "2 penalties ($431,500)", "Major facility", "425,309 lbs toxic releases/transfers"],
    "detailedReport": {
        "enforcementSummaries": [{ "statute": "RCRA", "inspections": 7, "currentStatus": "Significant Noncomplier", "quartersInNoncompliance": 12, "totalPenalties": 0 }],
        "formalActions": [{ "statute": "CAA", "actionType": "Administrative Order", "leadAgency": "State", "actionDate": "2022-10-04", "penaltyAmount": 110000 }],
        "permits": [{ "program": "FRS", "sourceId": "110000468093", "epaRegion": "08" }],
        "triChemicals": [{ "chemical": "Ammonia", "poundsByYear": { "2022": 25110, "2023": 28240, "2024": 23110 } }]
    },
    "scrapedAt": "2026-06-20T12:00:00.000Z"
}
```

The `detailedReport` block is present only when **includeDetailedReport** is on. Switch the dataset view to **Facilities**, **Compliance leads**, or **Violations & penalties** for a focused table.

#### What to expect (field coverage)

EPA ECHO aggregates many program systems, so some fields are populated only when a facility participates in that program or has that history.

| Field group | Coverage |
|---|---|
| Facility name, address, state, Registry ID, geo, programs | ✅ ~100% |
| NAICS / SIC, compliance status, inspection & enforcement counts | ✅ high (present whenever EPA has the data) |
| Penalties, formal actions, SNC flag | present for facilities with enforcement history |
| TRI releases & chemical history | present for TRI reporters |
| Greenhouse-gas CO₂ | present for GHG reporters |

A blank field means EPA doesn't publish that signal for that facility — not that scraping failed. Nothing is dropped, so you always get the richest record available.

### Automate & schedule

Run this actor on autopilot and pull results into your own stack:

- **[Apify API](https://docs.apify.com/api/v2)** — start runs, fetch datasets, and manage schedules over REST.
- **[apify-client for JavaScript](https://docs.apify.com/api/client/js/)** and **[apify-client for Python](https://docs.apify.com/api/client/python/)** — official SDKs.
- **[Schedules](https://docs.apify.com/platform/schedules)** — run it daily/weekly with **monitoring mode** to capture newly-cited facilities and fresh enforcement actions as leads.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** — trigger downstream actions (CRM import, Slack alert, email sequence) the moment a run finishes.

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

const client = new ApifyClient({ token: 'MY_APIFY_TOKEN' });

const run = await client.actor('scrapesage/epa-echo-scraper').call({
    states: ['TX'],
    naicsCodes: ['325'],
    significantNoncomplianceOnly: true,
    sortBy: 'leadScore',
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} facilities`);
```

### Integrate with any app

Connect the dataset to 5,000+ apps — no code required:

- **[Make](https://docs.apify.com/platform/integrations/make)** — multi-step automation scenarios.
- **[Zapier](https://docs.apify.com/platform/integrations/zapier)** — push new facility leads straight into your CRM.
- **[Slack](https://docs.apify.com/platform/integrations/slack)** — get notified when a monitored state or industry gets a new violation or penalty.
- **[Google Drive / Sheets](https://docs.apify.com/platform/integrations/drive)** — auto-export every run to a spreadsheet.
- **[Airbyte](https://docs.apify.com/platform/integrations/airbyte)** — pipe results into your data warehouse.
- **[GitHub](https://docs.apify.com/platform/integrations/github)** — trigger runs from commits or releases.

### Use with AI assistants (MCP)

The output is clean, LLM-ready JSON. Call this actor from Claude, ChatGPT, or any agent framework through the **[Apify MCP server](https://docs.apify.com/platform/integrations/mcp)** — ask your assistant to "find every chemical plant in Texas in significant noncompliance, with penalties and a lead score" and let it run the scraper for you.

### More scrapers from scrapesage

Build a complete **government-data, compliance & B2B lead-gen stack**:

- **[FDA Scraper (openFDA)](https://apify.com/scrapesage/fda-scraper)** — drug, device & food recalls, adverse events and manufacturer leads.
- **[FMCSA Trucking Scraper](https://apify.com/scrapesage/fmcsa-trucking-scraper)** — DOT carriers, safety ratings, inspections and fleet leads.
- **[FAA Aircraft Registry Scraper](https://apify.com/scrapesage/faa-aircraft-registry-scraper)** — registered aircraft and business-owner leads.
- **[SBA Loan Leads Scraper](https://apify.com/scrapesage/sba-loan-leads-scraper)** — financed small businesses from SBA 7(a) & 504 data.
- **[PPP Loan Data Scraper](https://apify.com/scrapesage/ppp-loan-data-scraper)** — 11M+ PPP loans with firmographics and owner demographics.
- **[Form 5500 ERISA Scraper](https://apify.com/scrapesage/form-5500-erisa-scraper)** — retirement & benefit-plan leads from DOL filings.
- **[USASpending Scraper](https://apify.com/scrapesage/usaspending-scraper)** — federal awards, recipients and contractor leads.
- **[GSA eLibrary Scraper](https://apify.com/scrapesage/gsa-elibrary-scraper)** — federal Schedule contractors with UEI, email and website.
- **[US Federal Grants Scraper](https://apify.com/scrapesage/us-federal-grants-scraper)** — grant opportunities and awardees.
- **[US Business Formation Scraper](https://apify.com/scrapesage/us-business-formation-scraper)** — newly-registered companies as fresh leads.

### Tips

- **Start with a state + industry** (e.g. `TX` + NAICS `325`) for a fast, focused list, then layer on compliance filters.
- **Highest-intent leads**: set `significantNoncomplianceOnly` or `hasPenaltiesOnly` and sort by `leadScore` — these facilities have an active reason to buy compliance, remediation or legal services.
- **Overdue sites**: set `inspectionRecency: "notWithin5yr"` to find facilities that haven't been inspected recently.
- **Detailed reports**: turn on `includeDetailedReport` to pull per-statute summaries, every formal action and the multi-year toxic-release history (one extra request per facility).
- **Recurring monitoring**: combine [Schedules](https://docs.apify.com/platform/schedules) with `monitorMode` to capture only facilities added or changed since the last run.

### FAQ

**Where does the data come from?** From EPA's official **ECHO** (Enforcement and Compliance History Online) public web services — the same data behind [echo.epa.gov](https://echo.epa.gov), covering facilities regulated under the Clean Air Act, Clean Water Act, RCRA, Safe Drinking Water Act, TRI and more.

**Does it need an API key or login?** No. ECHO's public services are queried directly — no key, no login, no browser.

**How fresh is it?** EPA refreshes ECHO regularly (most program data weekly). Run on a [Schedule](https://docs.apify.com/platform/schedules) with monitoring mode to capture new violations and enforcement as they post.

**Can I export to Google Sheets, CSV, or Excel?** Yes — one click in the dataset view, or automatically on every run via the [Google Drive integration](https://docs.apify.com/platform/integrations/drive).

**What's the Detailed Facility Report?** EPA's deep per-facility report — per-statute compliance summaries, every formal enforcement action (type, agency, date, penalty), all environmental permits, and multi-year Toxic Release Inventory chemical data. Enable `includeDetailedReport` to attach it.

**A field is empty — why?** A facility only carries data for the programs it participates in (e.g. no TRI releases if it's not a TRI reporter). Blank means EPA has no value, never that scraping failed.

**Is scraping this data legal?** This actor collects publicly available U.S. government data. You're responsible for using it in compliance with applicable laws and EPA's terms.

### Need help?

Open an issue on the actor's **Issues** tab, or visit the [Apify help center](https://help.apify.com/). Feature requests are welcome — this actor is actively maintained.

# Actor input Schema

## `registryIds` (type: `array`):

Look up specific facilities by their EPA FRS Registry ID, e.g. <code>110000468075</code>. Leave empty to search the whole database with the filters below.

## `states` (type: `array`):

Filter by facility state — two-letter USPS codes, e.g. <code>CA</code>, <code>TX</code>, <code>NY</code>, <code>PA</code>. Leave empty for all states & territories.

## `epaRegions` (type: `array`):

Filter by EPA region number, <code>01</code>–<code>10</code> (e.g. <code>09</code> = AZ/CA/HI/NV). Use instead of, or together with, states.

## `counties` (type: `array`):

Filter by county name (case-insensitive), e.g. <code>Harris</code>, <code>Los Angeles</code>, <code>Cook</code>. Combine with a state for accuracy.

## `cities` (type: `array`):

Filter by city name (case-insensitive), e.g. <code>Houston</code>, <code>Newark</code>, <code>Chicago</code>.

## `zipCodes` (type: `array`):

Filter by facility ZIP — full ZIP (<code>77002</code>) or a prefix (<code>770</code> matches all 770xx).

## `facilityNameQuery` (type: `string`):

Only return facilities whose name contains this text (case-insensitive), e.g. <code>chemical</code>, <code>refinery</code>, <code>steel</code>, or a specific company name.

## `streetQuery` (type: `string`):

Filter by street address (case-insensitive contains), e.g. <code>industrial</code>, <code>harbor</code>.

## `naicsCodes` (type: `array`):

Filter by NAICS industry code — full or prefix, e.g. <code>325</code> (chemical mfg), <code>3241</code> (petroleum), <code>2211</code> (power generation), <code>562</code> (waste management). Add several to combine.

## `sicCodes` (type: `array`):

Filter by legacy SIC industry code — full or prefix, e.g. <code>2911</code> (petroleum refining), <code>4911</code> (electric services), <code>2800</code> (chemicals).

## `programs` (type: `array`):

Keep only facilities regulated under the selected program(s). Leave empty for all. <b>CAA</b> = Clean Air Act, <b>NPDES</b> = Clean Water Act discharge permits, <b>RCRA</b> = hazardous waste, <b>SDWA</b> = Safe Drinking Water, <b>TRI</b> = Toxic Release Inventory, <b>GHG</b> = greenhouse-gas reporters, <b>SEMS</b> = Superfund sites.

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

Only include facilities currently flagged as active in EPA systems (recommended for clean, contactable leads). Turn off to include inactive / historical facilities.

## `majorFacilitiesOnly` (type: `boolean`):

Only return facilities flagged as <b>major</b> under their program (large air or water dischargers) — the biggest, highest-value sites.

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

Only return federally-owned facilities (military bases, federal agencies).

## `complianceStatus` (type: `array`):

Keep only facilities with the selected current compliance status. Leave empty for all. Pick <b>Significant/High Priority Violation</b> + <b>Violation</b> for the strongest service / legal intent.

## `significantNoncomplianceOnly` (type: `boolean`):

Only facilities flagged in <b>Significant Noncompliance (SNC)</b> / High Priority Violation — the most serious, highest-intent environmental enforcement targets.

## `currentViolationsOnly` (type: `boolean`):

Only facilities with an open / current violation on record.

## `hasPenaltiesOnly` (type: `boolean`):

Only facilities that have been assessed monetary penalties.

## `minPenaltyAmount` (type: `integer`):

Only facilities whose total assessed penalties are at least this amount (USD).

## `hasFormalEnforcementOnly` (type: `boolean`):

Only facilities with at least one formal enforcement action (civil/administrative/judicial) on record.

## `minQuartersInNoncompliance` (type: `integer`):

Only facilities that have been out of compliance for at least this many of the last 12 quarters (0–12).

## `inspectionRecency` (type: `string`):

Filter by when the facility was last inspected. <b>Not inspected in 5+ years</b> surfaces overdue sites; <b>Inspected in last 5 years</b> surfaces actively-monitored ones.

## `includeDetailedReport` (type: `boolean`):

Enrich each facility with its full EPA Detailed Facility Report — per-statute enforcement summaries, every formal action (type/agency/date/penalty), all environmental permits, and the multi-year Toxic Release Inventory chemical history. Adds one request per facility and is billed as a <i>detailedReport</i> instead of a <i>facilityRecord</i>.

## `maxResults` (type: `integer`):

Maximum number of facility records to return in this run.

## `sortBy` (type: `string`):

<b>Lead score</b> = most contactable / highest-intent first (recommended). <b>Highest penalties</b> / <b>Recent enforcement</b> / <b>Recent inspection</b> rank by those signals. <b>Source order</b> = fastest on very large limits.

## `deduplicateResults` (type: `boolean`):

Skip duplicate facilities (same Registry ID) within this run (recommended).

## `monitorMode` (type: `boolean`):

Remember which facilities were already returned (in a named key-value store) and emit ONLY facilities that are <b>new</b> or whose compliance changed since the last run — each tagged with a <code>monitorEvent</code> (<code>new</code>, <code>new\_violation</code>, <code>new\_enforcement</code>, <code>new\_penalty</code>, <code>status\_change</code>). EPA refreshes ECHO regularly; run on a Schedule to capture fresh enforcement as leads. Works alongside Apify Schedules (the schedule starts the run; monitoring decides what's new).

## `monitorKey` (type: `string`):

Names the memory used by monitoring mode. Use a distinct key per saved watch (e.g. per state or industry) so different monitors don't share state.

## `proxyConfiguration` (type: `object`):

Optional proxy. The EPA ECHO API is queried directly and needs no proxy — leave this off for the fastest queries. Enable Apify Proxy only if your network requires it.

## Actor input object example

```json
{
  "states": [
    "WY"
  ],
  "activeOnly": true,
  "majorFacilitiesOnly": false,
  "federalFacilitiesOnly": false,
  "significantNoncomplianceOnly": false,
  "currentViolationsOnly": false,
  "hasPenaltiesOnly": false,
  "hasFormalEnforcementOnly": false,
  "inspectionRecency": "any",
  "includeDetailedReport": false,
  "maxResults": 1000,
  "sortBy": "leadScore",
  "deduplicateResults": true,
  "monitorMode": false,
  "monitorKey": "default",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

All scraped facility records in the default dataset, each with firmographics, environmental programs, compliance status, violations, inspections, enforcement, penalties, toxic releases and a lead score.

# 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 = {
    "states": [
        "WY"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/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 = {
    "states": ["WY"],
    "proxyConfiguration": { "useApifyProxy": False },
}

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

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

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

```

## CLI example

```bash
echo '{
  "states": [
    "WY"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call scrapesage/epa-echo-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=scrapesage/epa-echo-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "EPA ECHO Scraper - Facilities, Violations & Compliance Leads",
        "description": "Scrape the official EPA ECHO database: regulated facilities with name, address, NAICS/SIC, Clean Air/Water/RCRA/SDWA compliance status, violations, inspections, enforcement, penalties & toxic releases. Filter by state, industry & noncompliance. B2B compliance leads + monitoring.",
        "version": "0.1",
        "x-build-id": "HPRU1XLa6NKn2EI7a"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/scrapesage~epa-echo-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-scrapesage-epa-echo-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/scrapesage~epa-echo-scraper/runs": {
            "post": {
                "operationId": "runs-sync-scrapesage-epa-echo-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/scrapesage~epa-echo-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-scrapesage-epa-echo-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "registryIds": {
                        "title": "FRS Registry IDs (direct lookup)",
                        "type": "array",
                        "description": "Look up specific facilities by their EPA FRS Registry ID, e.g. <code>110000468075</code>. Leave empty to search the whole database with the filters below.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "states": {
                        "title": "States",
                        "type": "array",
                        "description": "Filter by facility state — two-letter USPS codes, e.g. <code>CA</code>, <code>TX</code>, <code>NY</code>, <code>PA</code>. Leave empty for all states & territories.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "epaRegions": {
                        "title": "EPA regions",
                        "type": "array",
                        "description": "Filter by EPA region number, <code>01</code>–<code>10</code> (e.g. <code>09</code> = AZ/CA/HI/NV). Use instead of, or together with, states.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "counties": {
                        "title": "Counties",
                        "type": "array",
                        "description": "Filter by county name (case-insensitive), e.g. <code>Harris</code>, <code>Los Angeles</code>, <code>Cook</code>. Combine with a state for accuracy.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "cities": {
                        "title": "Cities",
                        "type": "array",
                        "description": "Filter by city name (case-insensitive), e.g. <code>Houston</code>, <code>Newark</code>, <code>Chicago</code>.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "zipCodes": {
                        "title": "ZIP codes (prefix)",
                        "type": "array",
                        "description": "Filter by facility ZIP — full ZIP (<code>77002</code>) or a prefix (<code>770</code> matches all 770xx).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "facilityNameQuery": {
                        "title": "Facility name contains",
                        "type": "string",
                        "description": "Only return facilities whose name contains this text (case-insensitive), e.g. <code>chemical</code>, <code>refinery</code>, <code>steel</code>, or a specific company name."
                    },
                    "streetQuery": {
                        "title": "Street address contains",
                        "type": "string",
                        "description": "Filter by street address (case-insensitive contains), e.g. <code>industrial</code>, <code>harbor</code>."
                    },
                    "naicsCodes": {
                        "title": "NAICS codes",
                        "type": "array",
                        "description": "Filter by NAICS industry code — full or prefix, e.g. <code>325</code> (chemical mfg), <code>3241</code> (petroleum), <code>2211</code> (power generation), <code>562</code> (waste management). Add several to combine.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "sicCodes": {
                        "title": "SIC codes",
                        "type": "array",
                        "description": "Filter by legacy SIC industry code — full or prefix, e.g. <code>2911</code> (petroleum refining), <code>4911</code> (electric services), <code>2800</code> (chemicals).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "programs": {
                        "title": "Environmental programs",
                        "type": "array",
                        "description": "Keep only facilities regulated under the selected program(s). Leave empty for all. <b>CAA</b> = Clean Air Act, <b>NPDES</b> = Clean Water Act discharge permits, <b>RCRA</b> = hazardous waste, <b>SDWA</b> = Safe Drinking Water, <b>TRI</b> = Toxic Release Inventory, <b>GHG</b> = greenhouse-gas reporters, <b>SEMS</b> = Superfund sites.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "CAA",
                                "NPDES",
                                "RCRA",
                                "SDWA",
                                "TRI",
                                "GHG",
                                "SEMS",
                                "TSCA",
                                "RMP"
                            ],
                            "enumTitles": [
                                "Clean Air Act (CAA)",
                                "Clean Water Act (NPDES)",
                                "RCRA hazardous waste",
                                "Safe Drinking Water (SDWA)",
                                "Toxic Release Inventory (TRI)",
                                "Greenhouse Gas (GHG)",
                                "Superfund (SEMS)",
                                "TSCA chemicals",
                                "Risk Mgmt Plan (RMP)"
                            ]
                        }
                    },
                    "activeOnly": {
                        "title": "Active facilities only",
                        "type": "boolean",
                        "description": "Only include facilities currently flagged as active in EPA systems (recommended for clean, contactable leads). Turn off to include inactive / historical facilities.",
                        "default": true
                    },
                    "majorFacilitiesOnly": {
                        "title": "Major facilities only",
                        "type": "boolean",
                        "description": "Only return facilities flagged as <b>major</b> under their program (large air or water dischargers) — the biggest, highest-value sites.",
                        "default": false
                    },
                    "federalFacilitiesOnly": {
                        "title": "Federal facilities only",
                        "type": "boolean",
                        "description": "Only return federally-owned facilities (military bases, federal agencies).",
                        "default": false
                    },
                    "complianceStatus": {
                        "title": "Compliance status",
                        "type": "array",
                        "description": "Keep only facilities with the selected current compliance status. Leave empty for all. Pick <b>Significant/High Priority Violation</b> + <b>Violation</b> for the strongest service / legal intent.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "significant",
                                "violation",
                                "compliant",
                                "noViolation"
                            ],
                            "enumTitles": [
                                "Significant / High Priority Violation",
                                "Violation identified",
                                "In compliance",
                                "No violation"
                            ]
                        }
                    },
                    "significantNoncomplianceOnly": {
                        "title": "Significant noncompliance only",
                        "type": "boolean",
                        "description": "Only facilities flagged in <b>Significant Noncompliance (SNC)</b> / High Priority Violation — the most serious, highest-intent environmental enforcement targets.",
                        "default": false
                    },
                    "currentViolationsOnly": {
                        "title": "Has current violations",
                        "type": "boolean",
                        "description": "Only facilities with an open / current violation on record.",
                        "default": false
                    },
                    "hasPenaltiesOnly": {
                        "title": "Has penalties",
                        "type": "boolean",
                        "description": "Only facilities that have been assessed monetary penalties.",
                        "default": false
                    },
                    "minPenaltyAmount": {
                        "title": "Min total penalty ($)",
                        "type": "integer",
                        "description": "Only facilities whose total assessed penalties are at least this amount (USD)."
                    },
                    "hasFormalEnforcementOnly": {
                        "title": "Has formal enforcement",
                        "type": "boolean",
                        "description": "Only facilities with at least one formal enforcement action (civil/administrative/judicial) on record.",
                        "default": false
                    },
                    "minQuartersInNoncompliance": {
                        "title": "Min quarters in noncompliance",
                        "type": "integer",
                        "description": "Only facilities that have been out of compliance for at least this many of the last 12 quarters (0–12)."
                    },
                    "inspectionRecency": {
                        "title": "Inspection recency",
                        "enum": [
                            "any",
                            "within5yr",
                            "notWithin5yr",
                            "neverInspected"
                        ],
                        "type": "string",
                        "description": "Filter by when the facility was last inspected. <b>Not inspected in 5+ years</b> surfaces overdue sites; <b>Inspected in last 5 years</b> surfaces actively-monitored ones.",
                        "default": "any"
                    },
                    "includeDetailedReport": {
                        "title": "Include Detailed Facility Report (DFR)",
                        "type": "boolean",
                        "description": "Enrich each facility with its full EPA Detailed Facility Report — per-statute enforcement summaries, every formal action (type/agency/date/penalty), all environmental permits, and the multi-year Toxic Release Inventory chemical history. Adds one request per facility and is billed as a <i>detailedReport</i> instead of a <i>facilityRecord</i>.",
                        "default": false
                    },
                    "maxResults": {
                        "title": "Max results",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Maximum number of facility records to return in this run.",
                        "default": 1000
                    },
                    "sortBy": {
                        "title": "Sort order",
                        "enum": [
                            "leadScore",
                            "penaltiesHigh",
                            "recentEnforcement",
                            "recentInspection",
                            "source"
                        ],
                        "type": "string",
                        "description": "<b>Lead score</b> = most contactable / highest-intent first (recommended). <b>Highest penalties</b> / <b>Recent enforcement</b> / <b>Recent inspection</b> rank by those signals. <b>Source order</b> = fastest on very large limits.",
                        "default": "leadScore"
                    },
                    "deduplicateResults": {
                        "title": "Deduplicate within a run",
                        "type": "boolean",
                        "description": "Skip duplicate facilities (same Registry ID) within this run (recommended).",
                        "default": true
                    },
                    "monitorMode": {
                        "title": "Monitoring mode — only new / changed facilities",
                        "type": "boolean",
                        "description": "Remember which facilities were already returned (in a named key-value store) and emit ONLY facilities that are <b>new</b> or whose compliance changed since the last run — each tagged with a <code>monitorEvent</code> (<code>new</code>, <code>new_violation</code>, <code>new_enforcement</code>, <code>new_penalty</code>, <code>status_change</code>). EPA refreshes ECHO regularly; run on a Schedule to capture fresh enforcement as leads. Works alongside Apify Schedules (the schedule starts the run; monitoring decides what's new).",
                        "default": false
                    },
                    "monitorKey": {
                        "title": "Monitor key",
                        "type": "string",
                        "description": "Names the memory used by monitoring mode. Use a distinct key per saved watch (e.g. per state or industry) so different monitors don't share state.",
                        "default": "default"
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Optional proxy. The EPA ECHO API is queried directly and needs no proxy — leave this off for the fastest queries. Enable Apify Proxy only if your network requires it.",
                        "default": {
                            "useApifyProxy": false
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
