# EPA ECHO Facility Compliance & Enforcement Scraper (`haketa/epa-echo-scraper`) Actor

Scrape US EPA ECHO facility data: compliance status (air, water, hazardous waste), violations, inspections, penalties ($), major-polluter flag, %minority, coordinates and program IDs. For ESG, due diligence and compliance research. Not affiliated with the EPA.

- **URL**: https://apify.com/haketa/epa-echo-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Business, Lead generation
- **Features:** Limited permissions
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.75 / 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 Scraper — Facility Compliance, Violations & Penalties Data

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-blue?logo=apify\&logoColor=white)](https://apify.com/haketa/epa-echo-scraper)
[![Maintenance](https://img.shields.io/badge/Maintained-Active-brightgreen)](#-changelog)
[![Data Quality](https://img.shields.io/badge/De--duplicated-100%25-success)](#-key-features)
[![Output Formats](https://img.shields.io/badge/Output-JSON%20%7C%20CSV%20%7C%20Excel-orange)](#-data-fields--output-structure)
[![Pagination](https://img.shields.io/badge/Pagination-1%2C000%2B%20Unlocked-blueviolet)](#-at-a-glance)
[![Compliance](https://img.shields.io/badge/Compliance-CAA%20%7C%20CWA%20%7C%20RCRA%20%7C%20SDWA-teal)](#-environmental-statutes-covered)

Extract official US environmental enforcement and compliance records from the **EPA Enforcement & Compliance History Online (ECHO)** system at scale. Search regulated industrial, commercial, and municipal facilities across the United States by company name, state, city, ZIP code, or industry NAICS/SIC codes to retrieve structured data on **inspections, formal enforcement actions, civil penalties in USD, environmental justice metrics (% minority), and multi-statute compliance statuses** across Air (CAA), Water (CWA), and Hazardous Waste (RCRA).

Whether conducting ESG risk assessments, corporate M\&A due diligence, vendor environmental audits, insurance underwriting, or environmental justice research, this scraper enables seamless bulk data extraction into **JSON, CSV, and Excel** without API rate-limit bottlenecks or browser overhead.

***

### ⚡ At a glance

| Feature | Specification |
|---|---|
| **Data Source** | US EPA Enforcement & Compliance History Online (ECHO) database |
| **Search Modes** | Keyword / Company Name, State, City, ZIP, NAICS, SIC industry codes |
| **Enforcement Filters** | Server-side current violations (`onlyWithViolations`), Major facilities (`onlyMajor`) |
| **Throughput Speed** | ~500 facilities per batch (~10–25s per 1,000 records) |
| **Pagination Limit** | Unlimited (set `maxItems: 0` for complete dataset or 1,000+ results) |
| **Default Sample Run** | Automatic multi-state sample (~100 items) when run without filters |
| **Deduplication** | 100% deduplicated across EPA FRS Registry IDs |
| **Export Formats** | Dataset (JSON, CSV, XML, Excel) & Key-Value Store `OUTPUT` mirror |
| **Proxy Requirement** | Standard Datacenter Proxy (fully supported, cost-effective) |
| **Execution Architecture** | Pure protocol-level HTTP pipeline (sub-second query resolution) |

***

### 🔎 Why scrape EPA ECHO data?

The EPA ECHO platform serves as the authoritative federal repository documenting compliance histories for over 800,000 regulated industrial, manufacturing, chemical, utility, and municipal sites across the 50 US states and territories.

While the public web portal is designed for single-facility lookups, extracting enterprise-wide or regional records manually is slow and error-prone. This scraper turns manual searches into an automated, bulk data extraction engine capable of delivering thousands of verified, clean rows directly into your analytical workflows.

#### Strategic Value & Business Intelligence Applications:

- **ESG & Sustainability Benchmarking:** Quantify corporate environmental track records using hard government metrics (total penalties paid in USD, active non-compliance quarters, repeat violations) rather than self-reported sustainability claims.
- **M\&A & Private Equity Due Diligence:** Uncover hidden environmental liabilities, pending enforcement actions, and historical fines before completing mergers, acquisitions, or commercial real estate transactions.
- **Supply Chain & Counterparty Vetting:** Verify supplier compliance with Clean Air and Clean Water regulations across US operational footprints to mitigate vendor disruption risks.
- **Credit Rating & Insurance Underwriting:** Incorporate regulatory infraction frequencies and major facility designations into commercial underwriting models and actuarial loss risk matrices.
- **Environmental Justice & Policy Research:** Analyze correlations between industrial pollution enforcement and local community demographics via the demographic % minority metric.
- **Academic & Legal Discovery:** Extract historical violation logs and formal administrative orders for regulatory impact studies and environmental litigation support.

***

### 🏛️ Environmental statutes covered

This scraper extracts official compliance statuses and program identification codes across all major federal environmental regulatory statutes:

1. **Clean Air Act (CAA):** Stationary air pollution source permits, Title V major emitters, synthetic minors, and compliance records under the National Emission Standards for Hazardous Air Pollutants (NESHAP).
2. **Clean Water Act (CWA):** National Pollutant Discharge Elimination System (NPDES) surface water discharge permits, municipal stormwater permits, and industrial effluent violations.
3. **Resource Conservation and Recovery Act (RCRA):** Hazardous waste handlers, Treatment, Storage, and Disposal Facilities (TSDFs), large-quantity generators (LQG), and corrective action statuses.
4. **Safe Drinking Water Act (SDWA):** Public water system regulatory records, maximum contaminant level (MCL) violations, and community water supply monitoring.
5. **Toxics Release Inventory (TRI):** Chemical manufacturing, processing, and environmental release reporting identifiers.
6. **Greenhouse Gas Reporting Program (GHGRP):** Mandatory federal direct greenhouse gas emitter identifiers and reporting links.

***

### ✨ Key features

- 🏢 **Multi-Statute Compliance Auditing:** Captures overall `complianceStatus` as well as granular statute-specific flags (`airComplianceStatus`, `waterComplianceStatus`, `hazWasteComplianceStatus`, `drinkingWaterComplianceStatus`).
- 💰 **Granular Penalty & Enforcement Tracking:** Scrapes cumulative civil penalties (`totalPenaltiesUsd`), penalty counts, most recent penalty dates, formal enforcement administrative actions, and inspection counts.
- 🎯 **High-Precision Server-Side Filtering:** Toggle `onlyWithViolations` to isolate active violators or `onlyMajor` to target major industrial facilities where penalty and program data is richest.
- ⚡ **Deep Pagination Support (1,000+ Records):** Automatically pages through multi-thousand result sets in 500-record batches without truncation or artificial caps.
- 🧼 **Standardized Field Normalization:** Automatically scrubs missing indicators, standardizes boolean flags, parses monetary strings into pure numeric amounts, and formats geographic coordinates.
- 🔗 **Direct Inspection Permalinks:** Produces verified links to each facility's complete Detailed Facility Report (`detailedReportUrl`) for one-click manual audits.
- 🛡️ **Zero Browser Overhead:** Pure lightweight protocol architecture for rapid execution, minimal memory consumption, and reliable scheduled runs.

***

### 📥 Input parameters

The actor accepts flexible input parameters. All filters can be combined to refine searches.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `searchTerms` | `array` | `["exxon mobil"]` | List of company or facility names to search (e.g. `["chevron", "dupont"]`). |
| `states` | `array` | `["TX"]` | Two-letter US state postal abbreviations (e.g. `["TX", "CA", "LA"]`). |
| `cities` | `array` | `[]` | Optional list of specific city names to restrict search. |
| `zipCodes` | `array` | `[]` | Optional list of 5-digit US ZIP codes. |
| `naicsCodes` | `array` | `[]` | North American Industry Classification System codes (e.g. `["324110"]` for petroleum refineries). |
| `sicCodes` | `array` | `[]` | Standard Industrial Classification codes (e.g. `["2911"]`). |
| `onlyMajor` | `boolean` | `false` | When true, restricts results exclusively to federally designated major facilities. |
| `onlyWithViolations` | `boolean` | `false` | When true, returns only facilities with current active violations or significant non-compliance. |
| `maxItems` | `integer` | `0` | Maximum total records to scrape (`0` = unlimited up to query total; prefilled to `100` for rapid testing). |
| `proxyConfiguration` | `object` | `{ "useApifyProxy": true }` | Proxy settings. Standard datacenter proxies operate reliably. |

***

### 📊 Data fields & output structure

Every output record contains comprehensive facility identification, geographic data, regulatory statuses, violation metrics, and penalty histories.

#### 🏢 Facility Identity & Location

| Field | Type | Coverage | Description |
|---|---|---|---|
| `registryId` | `string` | 🟢 High (100%) | EPA Facility Registry Service (FRS) unique identifier |
| `name` | `string` | 🟢 High (100%) | Official facility or operating company name |
| `street` | `string` | 🟢 High (>98%) | Physical facility street address |
| `city` | `string` | 🟢 High (100%) | Municipality or city name |
| `state` | `string` | 🟢 High (100%) | Two-letter US state code |
| `zip` | `string` | 🟢 High (>98%) | Standard 5-digit postal ZIP code |
| `county` | `string` | 🟢 High (>98%) | County name |
| `epaRegion` | `string` | 🟢 High (100%) | Federal EPA administrative region number (1–10) |
| `latitude` | `string` | 🟢 High (>98%) | Geographic latitude coordinate |
| `longitude` | `string` | 🟢 High (>98%) | Geographic longitude coordinate |

#### 📋 Classification & Demographics

| Field | Type | Coverage | Description |
|---|---|---|---|
| `sicCodes` | `string` | 🟡 Conditional | Associated Standard Industrial Classification codes |
| `naicsCodes` | `string` | 🟡 Conditional | Associated North American Industry Classification codes |
| `federalAgency` | `string` | 🟡 Conditional | Operating federal department (if federally owned site) |
| `inIndianCountry` | `string` | 🟢 High (100%) | Boolean indicator (`true`/`false`) of tribal territory location |
| `majorFacility` | `string` | 🟢 High (100%) | Flag designating major emitter or permit threshold status |
| `percentMinority` | `string` | 🟢 High (>95%) | Surrounding community demographic minority percentage (EJ screening) |

#### ⚖️ Environmental Compliance & Violations

| Field | Type | Coverage | Description |
|---|---|---|---|
| `complianceStatus` | `string` | 🟢 High (100%) | Overall compliance status evaluation |
| `airComplianceStatus` | `string` | 🟡 Conditional | Clean Air Act (CAA) compliance standing |
| `waterComplianceStatus` | `string` | 🟡 Conditional | Clean Water Act (CWA/NPDES) compliance standing |
| `hazWasteComplianceStatus` | `string` | 🟡 Conditional | Resource Conservation and Recovery Act (RCRA) standing |
| `drinkingWaterComplianceStatus` | `string` | 🟡 Conditional | Safe Drinking Water Act (SDWA) standing |
| `significantViolator` | `string` | 🟢 High (100%) | Significant Non-Complier (SNC) indicator (`true`/`false`) |
| `quartersInNonCompliance` | `string` | 🟢 High (100%) | Total quarterly monitoring periods in non-compliance (past 3 years) |
| `threeYearComplianceHistory` | `string` | 🟢 High (100%) | 12-quarter chronological compliance code sequence |

#### 🔨 Inspections, Enforcement & Penalties

| Field | Type | Coverage | Description |
|---|---|---|---|
| `inspectionCount` | `string` | 🟢 High (100%) | Total EPA and state environmental inspections recorded |
| `lastInspectionDate` | `string` | 🟡 Conditional | Date of most recent formal site inspection |
| `formalActionCount` | `string` | 🟢 High (100%) | Number of formal administrative and judicial enforcement actions |
| `lastFormalActionDate` | `string` | 🟡 Conditional | Date of latest formal enforcement action |
| `totalPenaltiesUsd` | `string` | 🟢 High (100%) | Cumulative civil and administrative penalties assessed in USD |
| `penaltyCount` | `string` | 🟢 High (100%) | Total count of individual penalty actions |
| `lastPenaltyDate` | `string` | 🟡 Conditional | Date of latest penalty assessment |
| `lastPenaltyAmountUsd` | `string` | 🟡 Conditional | Dollar amount of most recent penalty assessment |

#### 🆔 Environmental Program Identifiers

| Field | Type | Coverage | Description |
|---|---|---|---|
| `airIds` | `string` | 🟡 Conditional | Clean Air Act program permit identifiers |
| `waterIds` | `string` | 🟡 Conditional | National Pollutant Discharge Elimination System (NPDES) IDs |
| `hazWasteIds` | `string` | 🟡 Conditional | RCRA hazardous waste permit identifiers |
| `drinkingWaterIds` | `string` | 🟡 Conditional | SDWA public water system identifiers |
| `toxicsReleaseIds` | `string` | 🟡 Conditional | Toxics Release Inventory (TRI) program IDs |
| `greenhouseGasIds` | `string` | 🟡 Conditional | Mandatory Greenhouse Gas Reporting Program IDs |
| `detailedReportUrl` | `string` | 🟢 High (100%) | Direct URL to complete Detailed Facility Report |
| `scrapedAt` | `string` | 🟢 High (100%) | ISO 8601 scrape timestamp |

***

### 💡 Example output record

```json
{
  "registryId": "110000456123",
  "name": "BAYTOWN OLEFINS PLANT",
  "street": "3525 DECKER DRIVE",
  "city": "BAYTOWN",
  "state": "TX",
  "zip": "77520",
  "county": "HARRIS",
  "epaRegion": "6",
  "latitude": 29.7561,
  "longitude": -95.0124,
  "sicCodes": ["2869"],
  "naicsCodes": ["325110"],
  "federalAgency": "",
  "inIndianCountry": false,
  "majorFacility": true,
  "complianceStatus": "Significant Violation",
  "airComplianceStatus": "Significant Violation",
  "waterComplianceStatus": "No Violation",
  "hazWasteComplianceStatus": "No Violation",
  "drinkingWaterComplianceStatus": "",
  "significantViolator": true,
  "quartersInNonCompliance": 8,
  "threeYearComplianceHistory": "VVVVVVVVVVVV",
  "inspectionCount": 24,
  "lastInspectionDate": "2024-03-12",
  "formalActionCount": 5,
  "lastFormalActionDate": "2023-11-18",
  "totalPenaltiesUsd": 2250000,
  "penaltyCount": 3,
  "lastPenaltyDate": "2023-11-18",
  "lastPenaltyAmountUsd": 750000,
  "percentMinority": 68.4,
  "airIds": ["TX000123456"],
  "waterIds": ["TXR05A123"],
  "hazWasteIds": ["TXD000147258"],
  "drinkingWaterIds": [],
  "toxicsReleaseIds": ["77520XXNMB3525D"],
  "greenhouseGasIds": ["1002345"],
  "detailedReportUrl": "https://echo.epa.gov/detailed-facility-report?fid=110000456123",
  "scrapedAt": "2026-11-10T16:35:00.000Z"
}
```

***

### 🎯 Practical input recipes

#### Recipe 1: Nationwide Corporate Footprint Audit

Audit environmental violations for a major enterprise across all operating sites:

```json
{
  "searchTerms": ["chevron", "dow chemical"],
  "maxItems": 500,
  "onlyMajor": false
}
```

#### Recipe 2: Active Violators in an Industrial State

Extract all current Significant Non-Compliers in the state of Texas:

```json
{
  "states": ["TX"],
  "onlyWithViolations": true,
  "onlyMajor": true,
  "maxItems": 1000
}
```

#### Recipe 3: Chemical Manufacturing Sector Benchmark

Scrape chemical manufacturing facilities (`NAICS 325`) in the Gulf Coast region:

```json
{
  "states": ["TX", "LA"],
  "naicsCodes": ["325"],
  "maxItems": 1500
}
```

#### Recipe 4: Local Community & Environmental Justice Audit

Audit industrial operations located in specific ZIP codes:

```json
{
  "zipCodes": ["77012", "77017", "70079"],
  "maxItems": 250
}
```

#### Recipe 5: High-Impact Air Polluter Screening

Extract major facilities with Title V Clean Air Act permits in California:

```json
{
  "states": ["CA"],
  "onlyMajor": true,
  "maxItems": 500
}
```

#### Recipe 6: Comprehensive Corporate Due Diligence

Audit environmental liabilities for a holding group across all manufacturing subsidiaries:

```json
{
  "searchTerms": ["general electric", "honeywell"],
  "onlyMajor": false,
  "maxItems": 1000
}
```

***

### 🚀 How to use & integrate

1. **Configure Parameters:** Specify company name keywords, states, or NAICS industry codes.
2. **Select Filters:** Toggle `onlyWithViolations` if you only need non-compliant sites.
3. **Execute Run:** Run via Apify Web Console or trigger asynchronously via API:
   ```bash
   curl --request POST \
     --url "https://api.apify.com/v2/acts/haketa~epa-echo-scraper/runs?token=YOUR_API_TOKEN" \
     --header 'Content-Type: application/json' \
     --data '{"states": ["TX"], "onlyWithViolations": true, "maxItems": 200}'
   ```
4. **Consume Dataset:**
   - **Python:** Load directly into a Pandas DataFrame using `apify-client`.
   - **Node.js:** Stream records via Apify SDK.
   - **No-Code:** Export to Google Sheets or trigger downstream workflows via Zapier or Make.

***

### 📈 Scalability & pagination guide

- **500-Record Sequential Batches:** The scraper automatically queries and paginates through the EPA ECHO database in 500-facility batches. Setting `maxItems: 0` instructs the engine to pull every available match.
- **Deduplication Safeguards:** Facility records are deduplicated by their unique FRS Registry ID in memory. Overlapping geographic and keyword queries will never create duplicate rows.
- **Fast Default Validation:** Running the actor with empty input defaults to a sample search (`TX`, `CA`) capped at 100 records for fast, cost-efficient sanity checking.

***

### 💡 Optimization & best practices

- **Targeted Due Diligence:** When researching an acquisition target or corporate entity, query `searchTerms` with the primary trade names and corporate parent names. Leave location filters open to discover all subsidiary facilities across the US.
- **Isolating High-Risk Facilities:** For rapid environmental risk screening, enable both `onlyMajor: true` and `onlyWithViolations: true`. This narrows the dataset to significant industrial facilities currently experiencing non-compliance issues.
- **Managing High-Volume Statewide Scrapes:** When scraping large manufacturing states like Texas, California, or Ohio without search terms, set `maxItems` according to your quota needs (e.g., `1000` or `5000`).
- **Combining Industry & State Filters:** Narrow by NAICS code (e.g., `325` for Chemical Manufacturing) combined with specific states to benchmark regional industrial compliance performance.
- **Handling Empty Values:** Some facilities may not have recorded penalties or specific program IDs if they operate under general permits or have never received formal enforcement actions. Filter on `totalPenaltiesUsd > 0` in your downstream analysis for penalty-focused investigations.

***

### ❓ Frequently asked questions

##### Is scraping EPA ECHO legal?

Yes. The EPA ECHO database is an open US federal government public record. This scraper extracts public regulatory information.

##### Do I need an EPA API key or login?

No. No login, account, or private API keys are required. The scraper handles all protocol requirements out of the box.

##### How many facilities can I scrape in a single run?

You can scrape anywhere from 10 to 10,000+ facilities. Because pagination is handled in 500-facility chunks, scraping 1,000 facilities typically finishes in under 30 seconds.

##### Why are some compliance and penalty fields blank?

Federal and state agencies only populate penalty and statutory enforcement histories for regulated facilities that have been inspected or cited. Non-industrial or passive facilities will naturally have fewer enforcement entries.

##### What is the Registry ID?

The Registry ID is the EPA's Facility Registry Service (FRS) master identifier. It provides a permanent key to cross-reference data across federal environmental databases.

##### What does the % Minority field represent?

The `percentMinority` field is the demographic percentage of minority residents living within the surrounding census block or radial zone, used in federal environmental justice screenings.

##### Can I schedule recurring monitoring runs?

Yes. You can use Apify's built-in Scheduler to run weekly or monthly audits of your target companies or regions and automatically push alerts when new violations or penalties appear.

##### How does deduplication work?

Every facility scraped is checked against an internal set of unique EPA FRS Registry IDs. If multiple search terms or overlapping geographic queries return the same facility, it is emitted only once, ensuring clean datasets with 0% duplication rate.

##### What is the difference between major and minor facilities?

Major facilities (`onlyMajor: true`) are industrial plants and utilities that exceed specific statutory emission or discharge thresholds (e.g., emitting more than 100 tons per year of a criteria air pollutant, or major municipal wastewater plants discharging more than 1 million gallons per day). These facilities undergo stricter compliance monitoring and have the richest compliance histories.

##### Can I query by multiple states or NAICS codes at the same time?

Yes. The actor accepts arrays for states (e.g., `["TX", "CA", "LA"]`) and NAICS codes (e.g., `["324110", "325110"]`). The query engine handles multi-value requests efficiently.

##### How are penalties calculated?

The `totalPenaltiesUsd` field reflects the cumulative total of all civil and administrative penalties assessed against the facility across all tracked environmental statutes, normalized into clean numerical values.

##### How can I export the data into a spreadsheet or data warehouse?

From the Apify dataset tab, click "Export" and choose JSON, CSV, or Excel format. Alternatively, connect directly to BigQuery, Snowflake, or PostgreSQL via Apify integrations or webhook notifications upon run completion.

***

### 🔗 Related intelligence scrapers

- [USAspending Federal Awards Scraper](https://apify.com/haketa/usaspending-scraper) — Extract federal contracts, grants, and procurement awards.
- [ProPublica Nonprofit Scraper](https://apify.com/haketa/propublica-nonprofit-scraper) — Scrape IRS Form 990 filings, executive compensations, and grants.
- [Google Maps Business Leads Scraper](https://apify.com/haketa/google-maps-contacts-scraper) — Extract business listings with enriched email and social profiles.
- [Article Content Extractor](https://apify.com/haketa/article-content-extractor) — Clean text and metadata extraction from environmental news feeds.

***

### 📋 Changelog

#### v1.2 (2026-11)

- **Deep Pagination Unlocked:** Fully unlocked continuous multi-page pagination for 1,000+ facilities; removed legacy limits and streamlined 500-facility batch requests.
- **Fast Prefill Optimization:** Adjusted prefill limits to 100 records for sub-15s sample execution.
- **Default Fallback Robustness:** Added safe fallback defaults (`TX`, `CA`) ensuring runs with empty input payloads execute reliably with ~100 sample records.
- **URL Sanitization:** Standardized deterministic detailed report URL construction from registry IDs.

#### v1.1 (2026-10)

- **Server-Side Violation Filtering:** Upgraded `onlyWithViolations` filter to utilize server-side parameter flags, eliminating false-positive client-side regex matches.
- **Key-Value Store Mirroring:** Added automatic `OUTPUT` mirroring in Key-Value Store for synchronous API integrations.

#### v1.0 (2026-09)

- Initial release featuring multi-statute compliance parsing, FRS ID mapping, environmental justice metrics, and penalty aggregations.

# Changelog

This Actor's version history is a separate document: https://apify.com/haketa/epa-echo-scraper/changelog.md

# Actor input Schema

## `searchTerms` (type: `array`):

Facility/company name keywords (e.g. "chevron", "3M"). Combined with the location filters below. Leave empty to pull all facilities matching the location filters.

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

Two-letter US state codes to filter by (e.g. TX, CA, NY).

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

City names to filter by (optional).

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

ZIP codes to filter by (optional).

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

NAICS industry codes to filter by (optional).

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

SIC industry codes to filter by (optional).

## `onlyMajor` (type: `boolean`):

Return only facilities flagged as major (larger regulated sites).

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

Return only facilities that currently have a violation, are significant non-compliers, or have recent non-compliance quarters.

## `maxItems` (type: `integer`):

Maximum facilities across all searches. 0 = no limit.

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

Apify Proxy. The API is public — datacenter is enough and enabled by default.

## Actor input object example

```json
{
  "searchTerms": [
    "exxon mobil"
  ],
  "states": [
    "TX"
  ],
  "onlyMajor": false,
  "onlyWithViolations": false,
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

EPA FRS Registry ID

## `name` (type: `string`):

Facility name

## `street` (type: `string`):

Street address

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

City

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

State

## `zip` (type: `string`):

ZIP code

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

County

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

EPA region

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

Latitude

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

Longitude

## `sicCodes` (type: `string`):

SIC codes

## `naicsCodes` (type: `string`):

NAICS codes

## `federalAgency` (type: `string`):

Federal agency (if federal)

## `inIndianCountry` (type: `string`):

In Indian country

## `majorFacility` (type: `string`):

Major-polluter flag

## `complianceStatus` (type: `string`):

Overall compliance

## `airComplianceStatus` (type: `string`):

Clean Air Act status

## `waterComplianceStatus` (type: `string`):

Clean Water Act status

## `hazWasteComplianceStatus` (type: `string`):

RCRA status

## `drinkingWaterComplianceStatus` (type: `string`):

SDWA status

## `significantViolator` (type: `string`):

Significant non-complier

## `quartersInNonCompliance` (type: `string`):

Quarters in non-compliance

## `threeYearComplianceHistory` (type: `string`):

12-quarter compliance string

## `inspectionCount` (type: `string`):

Inspection count

## `lastInspectionDate` (type: `string`):

Last inspection date

## `formalActionCount` (type: `string`):

Formal enforcement actions

## `lastFormalActionDate` (type: `string`):

Last formal action date

## `totalPenaltiesUsd` (type: `string`):

Total penalties (USD)

## `penaltyCount` (type: `string`):

Number of penalties

## `lastPenaltyDate` (type: `string`):

Last penalty date

## `lastPenaltyAmountUsd` (type: `string`):

Last penalty amount (USD)

## `percentMinority` (type: `string`):

Surrounding %minority (EJ)

## `airIds` (type: `string`):

Clean Air Act program IDs

## `waterIds` (type: `string`):

NPDES program IDs

## `hazWasteIds` (type: `string`):

RCRA program IDs

## `toxicsReleaseIds` (type: `string`):

TRI program IDs

## `greenhouseGasIds` (type: `string`):

Greenhouse-gas program IDs

## `detailedReportUrl` (type: `string`):

ECHO detailed facility report

## `scrapedAt` (type: `string`):

ISO timestamp

# 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 = {
    "searchTerms": [
        "exxon mobil"
    ],
    "states": [
        "TX"
    ],
    "maxItems": 100,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/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 = {
    "searchTerms": ["exxon mobil"],
    "states": ["TX"],
    "maxItems": 100,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/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 '{
  "searchTerms": [
    "exxon mobil"
  ],
  "states": [
    "TX"
  ],
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call haketa/epa-echo-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,haketa/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/XHDxvsmuBCxDZIhIh/builds/3gDoC4BwfBAFeI7yD/openapi.json
