# EPA Enforcement Actions Feed - Penalties & Consent Decrees (`moment-data/epa-enforcement-actions-feed`) Actor

Feed of new US EPA and state environmental enforcement cases from official EPA ECHO data: company/facility, statute (CAA, CWA, RCRA, SDWA...), violations, federal and state penalties, SEPs, milestones, links. Filter by state, law, penalty, company. New-since-last-run alerts.

- **URL**: https://apify.com/moment-data/epa-enforcement-actions-feed.md
- **Developed by:** [Luke Miller](https://apify.com/moment-data) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 enforcement cases

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/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 Enforcement Actions Feed: Environmental Penalties, Consent Decrees & Violations API

Get a clean, daily feed of **new US EPA and state environmental enforcement cases** against companies and facilities: Clean Air Act, Clean Water Act, RCRA hazardous waste, Safe Drinking Water Act, EPCRA, FIFRA pesticide, CERCLA Superfund and TSCA lead-paint cases, with **federal and state penalties, Supplemental Environmental Projects (SEPs), consent decrees, final orders, violation types, facility name and address, company defendants and direct ECHO links**. Export as JSON, CSV or Excel, or schedule it in *new since last run* mode as an environmental enforcement alert feed.

Data comes straight from EPA's official **ECHO (Enforcement and Compliance History Online)** case services, the same ICIS Federal Enforcement & Compliance data behind ECHO's Enforcement Case Search. No login, no API key, no scraping of web pages.

**Why this one:** most EPA/ECHO tools on the Store are *facility lookups* (you must already know which facility to ask about). This Actor is **case-centric and time-based**: it tells you **what enforcement happened in the last N days across the whole country**, newest first, with the full case report (milestones, penalties, SEPs, complying actions, pollutants, summary) merged into one flat record.

### Who it is for

- **ESG, sustainability and compliance analysts**: track environmental penalties and consent decrees against portfolio companies, suppliers and peers; feed ESG controversy scores.
- **Environmental lawyers and consultants**: see new CAFOs, consent decrees and penalty orders by statute, state or region the week they are recorded; prospect companies that just settled.
- **Insurers and underwriters**: environmental liability signals by facility, industry (NAICS/SIC) and state.
- **Supply-chain and procurement risk teams**: watch suppliers' plants for Clean Air / Clean Water violations and penalties.
- **Journalists, NGOs and researchers**: a weekly digest of the largest environmental penalties, with case summaries and links.
- **Lenders, M\&A and due-diligence teams**: recent enforcement history before a deal.
- **Developers**: normalized ECHO case data through the Apify API, webhooks and integrations (Slack, Google Sheets, Zapier, Make, n8n).

### What you get for each case

- **Case**: case number, ECHO activity ID, case name, category (administrative formal / judicial / informal), status, enforcement type (e.g. *Civil Judicial Action*, *CAA 113D1 Action for Penalty*, *State CWA Penalty AO*), civil/criminal, lead agency (EPA / State / Local), court and DOJ docket numbers.
- **Law**: primary statute (CAA, CWA, RCRA, SDWA, EPCRA, FIFRA, CERCLA, TSCA) with full name, all statutes involved, law sections and programs (e.g. *MACT Standards*, *Industrial Stormwater*, *Lead-Based Paint Disclosure Rule*), violation types.
- **Money**: federal penalty, state/local penalty, total penalty, penalty collected, SEP cost with SEP category and description, compliance action (injunctive relief) cost, cost recovery.
- **Dates**: latest milestone and its date (`actionDate`), complaint filed, settlement lodged, final order entered/issued, closed, and the full milestone timeline.
- **Who / where**: company defendants, facility name, street address, city, state, ZIP, FRS ID, NAICS/SIC, all facilities in the case (up to 25), EPA region.
- **Context**: pollutants, complying actions (monitoring, testing, emission controls...), voluntary disclosure flag, EPA's case summary.
- **Links**: ECHO case report (`echoCaseUrl`), ECHO detailed facility report per facility, and the JSON API URL.
- **New since last run** mode with saved history per *State key*; a case is delivered again when it reaches a new milestone (e.g. complaint filed, then consent decree entered).
- **Privacy by design**: entity-level data only. Defendants who appear to be private individuals are omitted (and masked in case names and summaries); cases brought only against individuals are skipped.
- **Fast**: a default run takes about 15 seconds at 512 MB.

### Quick start

1. Click **Start** with the default input. You get about 40 of the most recent civil enforcement cases nationwide (formal administrative orders and judicial cases with a milestone in the last 30 days), with full case details.
2. Narrow it down: `states`, `statutes`, `minPenalty`, `companyKeyword`, `leads`. Raise `maxItems` (up to 5,000) and `daysBack` (up to 365) for bigger pulls.
3. **Weekly enforcement alerts (schedule tip):** create an Apify **Schedule** (e.g. every Monday 8:00) with:

```json
{ "mode": "sinceLastRun", "stateKey": "big-penalties", "minPenalty": 100000, "daysBack": 45, "maxItems": 500 }
```

Each run delivers only cases (or new case milestones) not delivered before for that `stateKey`. Connect Slack, e-mail, Google Sheets or a webhook. Use one `stateKey` per schedule. Keep `daysBack` at 30+ because ECHO publishes case data weekly with a 1-2 week lag.

More examples:

- Texas and Louisiana Clean Air Act cases this quarter: `{ "states": ["TX", "LA"], "statutes": ["CAA"], "daysBack": 90, "maxItems": 500 }`
- Penalties of $1M+ in the last year: `{ "minPenalty": 1000000, "daysBack": 365, "maxItems": 1000 }`
- Everything mentioning a company: `{ "companyKeyword": "Tyson", "daysBack": 365 }`
- EPA-led pesticide (FIFRA) import cases: `{ "statutes": ["FIFRA"], "leads": ["EPA"], "daysBack": 60 }`
- Bulk year export, list fields only (fast): `{ "daysBack": 365, "maxItems": 5000, "enrichDetails": false }`

### Input

| Field | Default | Meaning |
|---|---|---|
| `states` | all | case location state codes, e.g. `TX`, `CA`, `PR` |
| `statutes` | all | `CAA`, `CWA`, `RCRA`, `SDWA`, `EPCRA`, `FIFRA`, `CERCLA`, `TSCA` (primary or secondary law) |
| `minPenalty` | 0 | minimum federal + state/local penalty in USD |
| `companyKeyword` | none | case name contains this text |
| `daysBack` | 30 | cases with a milestone in the last N days (1-365) |
| `maxItems` | 40 | cap per run (also caps spend); newest first |
| `caseCategories` | formal admin + judicial | add `AIF` for informal actions (NOVs, warning letters) |
| `leads` | all | `EPA`, `State`, `Local` |
| `includeCriminal` | false | add federal environmental criminal cases (company cases only) |
| `enrichDetails` | true | merge the ECHO case report (facility, defendants, milestones, SEPs...) |
| `mode` | `window` | `window` = everything in the window; `sinceLastRun` = only new (**use for schedules**) |
| `stateKey` | `default` | saved history name for `sinceLastRun` |

### Output example (real record, Oct 2026; shortened)

```json
{
  "caseNumber": "06-2022-3400",
  "caseName": "DOMTAR A.W. LLC-ASHDOWN MILL-ECDAT Consent Decree-FY2026",
  "caseCategory": "Judicial",
  "enforcementType": "Civil Judicial Action",
  "lead": "EPA",
  "primaryLaw": "CAA",
  "primaryLawName": "Clean Air Act",
  "violationTypes": ["National Emission Standard For Hazardous Air Pollutant", "New Source Performance Standard"],
  "actionDate": "2026-10-21",
  "latestMilestone": "Final Order Entered",
  "dateFiled": "2026-07-24",
  "federalPenalty": 750000,
  "stateLocalPenalty": 750000,
  "totalPenalty": 1500000,
  "defendants": ["Domtar A.W., LLC"],
  "facilityName": "DOMTAR A.W. LLC - ASHDOWN MILL",
  "facilityAddress": "285 HIGHWAY 71 SOUTH",
  "facilityCity": "ASHDOWN",
  "facilityState": "AR",
  "epaRegion": "06",
  "naicsCode": "113310",
  "pollutants": ["HYDROGEN CHLORIDE", "Mercury", "TOTAL HAZARDOUS AIR POLLUTANTS (HAPS)", "VOLATILE ORGANIC COMPOUNDS (VOCS)"],
  "courtDocketNumber": "4:26-cv-04059-JTS",
  "caseSummary": "EPA and DOJ filed this action with Arkansas Division of Environmental Quality against the Defendant for violations of the Clean Air Act ... agreed to pay a penalty of $1,500,000 and perform injunctive relief ...",
  "echoCaseUrl": "https://echo.epa.gov/enforcement-case-report?id=06-2022-3400"
}
```

Full examples: `sample-output.json`. Every run also writes a summary (window, filters, counts, skipped records) to the `OUTPUT` record. The dataset has an *Enforcement cases* table view.

### Glossary

**CAFO** = Consent Agreement and Final Order (administrative settlement). **Consent decree** = court-approved settlement in a judicial case (lodged, then entered). **SEP** = Supplemental Environmental Project a company agrees to fund as part of a settlement. **Lead** = agency that brought the case (state-lead cases are those states report to EPA). **AFR/JDC/AIF** = administrative formal / judicial / administrative informal.

### Data source, update timing and fair use

- **US EPA ECHO case web services** (`echodata.epa.gov/echo/case_rest_services`: case search + case report), built on EPA's ICIS Federal Enforcement & Compliance (FE\&C) data, the same data as ECHO's Enforcement Case Search and the ICIS FE\&C national data set.
- EPA refreshes ECHO case data weekly; new cases typically appear 1-3 weeks after the milestone date.
- U.S. Government data, free, no API key. Polite access with a declared User-Agent, rate limiting and retries.
- Penalty amounts are as recorded in ECHO (assessed, not necessarily collected; see `penaltyCollected`). Not affiliated with or endorsed by the U.S. EPA. Confirm critical decisions against the official case report (`echoCaseUrl`).
- Related feeds from moment-data: [Federal Register Notices Feed](https://apify.com/moment-data/federal-register-notices-feed), [US Product Recalls Feed](https://apify.com/moment-data/product-recalls-feed), [SEC EDGAR Filings Feed](https://apify.com/moment-data/sec-edgar-filings-feed).

### Pricing

Pay per event: a small fee per run plus a fee per enforcement case delivered. `maxItems` caps your spend, and runs stop cleanly at your maximum charge limit. See the Pricing tab.

### FAQ

**How fresh is it?** As fresh as ECHO: weekly updates, usually 1-3 weeks after the order or filing date. Use `daysBack` 30+ with `sinceLastRun` so late-arriving cases are never missed.
**Does it include inspections or violations without a case?** No, this is the enforcement *case* feed (orders, penalties, consent decrees). Informal actions can be added with `caseCategories: ["AFR","JDC","AIF"]`.
**Why is a case name empty?** Some states report cases without a name; use `facilityName` and `defendants`.
**Can I get older history?** Up to 365 days per run with `daysBack`.

# Actor input Schema

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

Optional. Two-letter codes of the case location, e.g. TX, CA, CO, PR. Empty = all states and territories.

## `statutes` (type: `array`):

Optional. Keep cases under any of these laws (primary or secondary). Empty = all laws.

## `minPenalty` (type: `integer`):

Optional. Only cases whose federal + state/local penalty is at least this amount, e.g. 100000. 0 = include non-penalty orders too.

## `companyKeyword` (type: `string`):

Optional. Case-name text match, e.g. 'Exxon', 'Tyson', 'City of'. ECHO case names normally contain the company or facility name.

## `daysBack` (type: `integer`):

Cases with an enforcement milestone (complaint filed, settlement lodged, final order issued/entered, case closed) in the last N days. ECHO publishes case data weekly with a 1-2 week lag, so keep this at 30 or more.

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

Hard cap on delivered cases (also caps your spend). Newest action first, larger penalties first on the same day.

## `caseCategories` (type: `array`):

Formal administrative orders (penalty orders, CAFOs, compliance orders) and judicial cases (consent decrees). Informal actions (notices of violation, warning letters) are optional.

## `leads` (type: `array`):

Optional. EPA-led, state-led or local-agency-led cases. Empty = all.

## `includeCriminal` (type: `boolean`):

Also include federal environmental criminal cases (company defendants only; no detailed report).

## `enrichDetails` (type: `boolean`):

Fetch each case's ECHO case report: facility name and address, company defendants, violation types, milestones, SEPs, complying actions, pollutants and case summary. Turn off for very large, faster pulls with list fields only.

## `mode` (type: `string`):

window (default): every case in the time window, no saved state. sinceLastRun: only cases (or new milestones of a case) not delivered before for this State key. Use for schedules and alerts.

## `stateKey` (type: `string`):

Name of the saved feed for sinceLastRun mode. Use one key per schedule.

## Actor input object example

```json
{
  "states": [],
  "daysBack": 30,
  "maxItems": 40,
  "caseCategories": [
    "AFR",
    "JDC"
  ],
  "includeCriminal": false,
  "enrichDetails": true,
  "mode": "window",
  "stateKey": "default"
}
```

# Actor output Schema

## `cases` (type: `string`):

One record per enforcement case.

## `summary` (type: `string`):

Window, filters, counts, skipped records.

# 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": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("moment-data/epa-enforcement-actions-feed").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": [] }

# Run the Actor and wait for it to finish
run = client.actor("moment-data/epa-enforcement-actions-feed").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 '{
  "states": []
}' |
apify call moment-data/epa-enforcement-actions-feed --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,moment-data/epa-enforcement-actions-feed"
        }
    }
}
```

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/jKmJRFurtOwg0cWeM/builds/yVesK3M5NUgxdURFJ/openapi.json
