EPA ECHO Enforcement Scraper avatar

EPA ECHO Enforcement Scraper

Pricing

$8.00 / 1,000 epa enforcement digest rows

Go to Apify Store
EPA ECHO Enforcement Scraper

EPA ECHO Enforcement Scraper

Track EPA ECHO enforcement data. Open Input → leave defaults → Start (1 facility target + evidence 1 ≈ USD 0.008/row): https://console.apify.com/actors/ZDjXNTKA88oNNMYRe/input From USD 8/1k.

Pricing

$8.00 / 1,000 epa enforcement digest rows

Rating

0.0

(0)

Developer

naoki anzai

naoki anzai

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

Security

Limited permissions

Share

EPA ECHO Enforcement Watch Scraper

What you get: one digest row per EPA ECHO target (facility, company, or case search), with status, severity, a risk score, risk signals, recommended actions, and per-surface metrics such as matched facilities, current and significant violations, formal enforcement actions, and penalty exposure.

Sample output from a real run (2026-10-18, the JSON below: BASF, Texas, first run):

targetNamestatusseverityriskScorematched facilitiescurrent / significant violationsformal enforcementpenalty exposure
BASF Texas EPA Watchinitialhigh100513 / 18$431,770

First recommended action from that row: "Review current violation and SNC/HPV indicators for BASF Texas EPA Watch and confirm corrective-action ownership." Each row is one $0.008 dataset-item event.

Open Input (leave defaults → Start)

Paid first run ≈ USD 0.008 per digest row (1 facility target, maxEvidenceItems 1). Open Console Input (deep link above) and run this JSON.

{
"targets": [
{
"id": "basf-texas-first-run",
"name": "BASF Texas EPA Watch",
"criticality": "high",
"owner": "EHS / Compliance",
"tags": "chemical,texas,epa",
"facilityName": "BASF",
"state": "TX",
"facilitySearch": {
"nameMatchMode": "CONTAINS"
},
"complianceScreener": {
"years": 3,
"activeOnly": true,
"nameMatchMode": "CONTAINS",
"evidenceLimit": 1
}
}
],
"delivery": "dataset",
"datasetMode": "all",
"snapshotKey": "epa-enforcement-first-run",
"diffMode": "line_summary",
"summaryMaxLines": 6,
"maxEvidenceItems": 1,
"concurrency": 1,
"batchDelayMs": 500,
"dryRun": false
}

Use this actor to monitor public EPA ECHO facility, compliance, and enforcement-case records for EHS and diligence review workflows. Input facility names, states, FRS IDs, case searches, or target watchlists; get source-linked digest rows for changed or action-needed records. This actor is informational only and does not provide professional advice, certification, or opaque scoring.

Store Quickstart

  • Add one or more targets[] entries.
  • For facility/company watches, use facilitySearch and/or complianceScreener.
  • For narrow enforcement feeds, use caseSearch with a state/region and a date window.
  • Keep the same snapshotKey across recurring runs so deltas remain comparable.

Use with Apify MCP

Exact actor: taroyamada/epa-enforcement-digest

Sample input JSON:

{
"targets": [
{
"id": "basf-texas-first-run",
"name": "BASF Texas EPA Watch",
"criticality": "high",
"owner": "EHS / Compliance",
"tags": "chemical,texas,epa",
"facilityName": "BASF",
"state": "TX",
"facilitySearch": {
"nameMatchMode": "CONTAINS"
},
"complianceScreener": {
"years": 3,
"activeOnly": true,
"nameMatchMode": "CONTAINS",
"evidenceLimit": 1
}
}
],
"delivery": "dataset",
"datasetMode": "all",
"snapshotKey": "epa-enforcement-first-run",
"diffMode": "line_summary",
"summaryMaxLines": 6,
"maxEvidenceItems": 1,
"concurrency": 1,
"batchDelayMs": 500,
"dryRun": false
}

Key Features

  • 🏛️ Government-sourced — Pulls directly from official agency feeds — no third-party aggregators
  • ⏱️ Timely digests — Daily/weekly rollups of new filings, rulings, or actions
  • 🔍 Keyword watchlists — Flag items matching your compliance/legal watch terms
  • 📊 Structured metadata — Agency, date, docket, document type, link — all dataset-ready
  • 📡 Webhook alerts — Push to legal/compliance teams the moment new items match watchlist

Use Cases

WhoWhy
DevelopersAutomate recurring data fetches without building custom scrapers
Data teamsPipe structured output into analytics warehouses
Ops teamsMonitor changes via webhook alerts
Product managersTrack competitor/market signals without engineering time

Input

FieldTypeDefaultDescription
targetsarrayprefilledList of watched facilities, company footprints, or case feeds. Shared target-level selectors (frsId, facilityName, state
requestTimeoutSecondsinteger30Maximum time to wait for one EPA ECHO web-service request.
userAgentstring—Optional custom User-Agent string for public EPA ECHO requests.
deliverystring"dataset"dataset writes selected target rows to the dataset. webhook posts the digest JSON.
datasetModestring"changes_only"Controls which target rows are persisted: action-needed only, changed/initial/partial/error rows, or every row.
webhookUrlstring—POST destination when delivery=webhook.
notifyOnNoChangebooleanfalseWhen true, webhook delivery still fires even when no selected target changed.
snapshotKeystring"epa-enforcement-digest-snapshots"Stable key used to load and save prior ECHO surface snapshots between recurring runs.

Input Example

{
"targets": [
{
"id": "basf-texas",
"name": "BASF Texas EPA Watch",
"criticality": "high",
"owner": "EHS / Compliance",
"tags": "chemical,texas,epa",
"facilityName": "BASF",
"state": "TX",
"facilitySearch": {
"nameMatchMode": "CONTAINS"
},
"complianceScreener": {
"years": 5,
"activeOnly": true,
"nameMatchMode": "CONTAINS",
"evidenceLimit": 5
}
},
{
"id": "delaware-afr-feed",
"name": "Delaware Administrative Formal Cases",
"criticality": "high",
"owner": "Legal / Compliance",
"tags": "case-feed,delaware,enforcement",
"caseSearch": {
"state": "DE",
"caseCategory": "AFR",
"fromDate": "01/01/2024",
"toDate": "12/31/2024",
"evidenceLimit": 5
}
}
],
"delivery": "dataset",
"datasetMode": "changes_only",
"snapshotKey": "epa-enforcement-example",
"diffMode": "line_summary",
"summaryMaxLines": 12,
"maxEvidenceItems": 5,
"concurrency": 2,
"batchDelayMs": 500,
"dryRun": false
}

Input Examples

Example: One facility/company watch

{
"targets": [
{
"id": "basf-texas",
"name": "BASF Texas EPA Watch",
"criticality": "high",
"owner": "EHS / Compliance",
"tags": "chemical,texas,epa",
"facilityName": "BASF",
"state": "TX",
"facilitySearch": {
"nameMatchMode": "CONTAINS"
},
"complianceScreener": {
"years": 3,
"activeOnly": true,
"nameMatchMode": "CONTAINS",
"evidenceLimit": 1
}
}
],
"datasetMode": "all",
"snapshotKey": "epa-basf-tx",
"maxEvidenceItems": 1
}

Example: Two companies

{
"targets": [
{
"id": "basf-texas",
"name": "BASF Texas EPA Watch",
"criticality": "high",
"owner": "EHS / Compliance",
"tags": "chemical,texas,epa",
"facilityName": "BASF",
"state": "TX",
"facilitySearch": {
"nameMatchMode": "CONTAINS"
},
"complianceScreener": {
"years": 3,
"activeOnly": true,
"nameMatchMode": "CONTAINS",
"evidenceLimit": 1
}
},
{
"id": "dow-louisiana",
"name": "Dow Louisiana EPA Watch",
"criticality": "standard",
"tags": "chemical,louisiana",
"facilityName": "DOW",
"state": "LA",
"facilitySearch": {
"nameMatchMode": "CONTAINS"
}
}
],
"datasetMode": "all",
"snapshotKey": "epa-chem-portfolio",
"maxEvidenceItems": 1
}

Output

FieldTypeDescription
metaobject
recurringDigestobject
actionNeededarray
resultsarray
actionNeeded[].targetIdstring
actionNeeded[].targetNamestring
actionNeeded[].ownerstring
actionNeeded[].severitystring
actionNeeded[].statusstring
actionNeeded[].riskScorenumber
actionNeeded[].reasonstring
actionNeeded[].signalsarray
actionNeeded[].recommendedActionsarray
actionNeeded[].executiveSummarystring

Output Example

Real dataset row from a run on 2026-10-18 (the first JSON above; lists shortened to 2 items, long text cut with …):

{
"targetId": "basf-texas-first-run",
"targetName": "BASF Texas EPA Watch",
"criticality": "high",
"owner": "EHS / Compliance",
"tags": [
"chemical",
"texas"
],
"status": "initial",
"severity": "high",
"riskScore": 100,
"reason": "BASF Texas EPA Watch: initial EPA ECHO baseline captured across 2 surface(s). Current risk signals were present at baseline. Signals: significant_violation, current_violation, historical_noncompliance, formal_enforcement…",
"executiveSummary": "BASF Texas EPA Watch baseline captured for recurring EPA enforcement/compliance tracking.",
"recommendedActions": [
"Review current violation and SNC/HPV indicators for BASF Texas EPA Watch and confirm corrective-action ownership.",
"Review enforcement case activity for BASF Texas EPA Watch and assess legal/compliance impact."
],
"signals": [
"significant_violation",
"current_violation"
],
"targetSummary": {
"monitoredSurfaceCount": 2,
"changedSurfaceCount": 0,
"initialSurfaceCount": 2,
"unchangedSurfaceCount": 0,
"errorSurfaceCount": 0,
"changedSurfaces": [],
"surfaceTypes": [
"facility_search",
"compliance_screener"
],
"riskMetrics": {
"matchedFacilityCount": 51,
"currentViolationCount": 3,
"significantViolationCount": 1,
"historicalNoncomplianceCount": 9,
"formalEnforcementCount": 8,
"settlementCount": 1,
"openCaseCount": 1,
"caseCount": 0,
"penaltyExposureUsd": 431770,
"highestMaxScore": 13
},
"surfaceMetrics": {
"facility_search": {
"queryRows": 51,
"currentViolationCount": 3,
"significantViolationCount": 1,
"historicalNoncomplianceCount": 9,
"formalEnforcementCount": 8,
"informalEnforcementCount": 6,
"inspectionCount": 11,
"totalPenaltiesUsd": 431770,
"mediaCounts": {
"caaRows": 9,
"cwaRows": 14,
"rcraRows": 22,
"sdwaRows": 0,
"triRows": 10
},
"clusteredResults": false
},
"compliance_screener": {
"queryRows": 21,
"activeRows": 21,
"currentViolationCount": 3,
"significantViolationCount": 1,
"facilitiesWithActionCount": 1,
"settlementCount": 1,
"openCaseCount": 1,
"highestMaxScore": 13,
"penaltyFlagCount": 0,
"mediaCounts": {
"caaRows": 1,
"cwaRows": 1,
"rcraRows": 0,
"sdwaRows": 1
}
}
},
"actionNeeded": false
},
"delta": {
"changedIndicators": [
"facility_search:queryRows",
"facility_search:currentViolationCount"
],
"surfaceDeltas": {
"facility_search": {
"changedIndicators": [
"queryRows",
"currentViolationCount"
],
"values": {
"queryRows": 51,
"currentViolationCount": 3,
"significantViolationCount": 1,
"historicalNoncomplianceCount": 9,
"formalEnforcementCount": 8,
"informalEnforcementCount": 6,
"totalPenaltiesUsd": 431770
}
},
"compliance_screener": {
"changedIndicators": [
"queryRows",
"activeRows"
],
"values": {
"queryRows": 21,
"activeRows": 21,
"currentViolationCount": 3,
"significantViolationCount": 1,
"facilitiesWithActionCount": 1,
"settlementCount": 1,
"openCaseCount": 1,
"highestMaxScore": 13,
"penaltyFlagCount": 0
}
}
}
},
"changes": [
{
"surfaceId": "basf-texas-first-run-facility-search",
"surfaceName": "All-Media Facility Search",
"surfaceType": "facility_search",
"status": "initial",
"queryUrl": "https://echodata.epa.gov/echo/echo_rest_services.get_facility_info?output=JSON&p_fn=BASF&p_fntype=CONTAINS&p_st=TX",
"checkedAt": "2026-10-18T09:41:16.860Z",
"previousCheckedAt": "",
"preview": "51 facility match(es); 1 significant violation, 3 current violation, 8 formal enforcement, penalties $431,770.",
"changeSummary": {
"addedCount": 0,
"removedCount": 0,
"added": [],
"removed": []
},
"signals": [
"significant_violation",
"current_violation"
],
"error": null
},
{
"surfaceId": "basf-texas-first-run-compliance-screener",
"surfaceName": "Corporate Compliance Screener",
"surfaceType": "compliance_screener",
"status": "initial",
"queryUrl": "https://echodata.epa.gov/echo/comp_screen_services.get_facilities?output=JSON&p_fn=BASF&p_fntype=CONTAINS&p_st=TX&p_active=Y&p_yrs=3&tablelist=Y&responseset=1",
"checkedAt": "2026-10-18T09:41:16.860Z",
"previousCheckedAt": "",
"preview": "21 screened facility match(es); 3 current violation, 1 significant violation, 1 row(s) with recent enforcement or settlements.",
"changeSummary": {
"addedCount": 0,
"removedCount": 0,
"added": [],
"removed": []
},
"signals": [
"significant_violation",
"current_violation"
],
"error": null
}
],
"checkedAt": "2026-10-18T09:41:16.860Z",
"error": null
}

API Usage

Run this actor programmatically using the Apify API. Replace YOUR_API_TOKEN with your token from Apify Console → Settings → Integrations.

cURL

curl -X POST "https://api.apify.com/v2/acts/taroyamada~epa-enforcement-digest/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "targets": [ { "id": "basf-texas", "name": "BASF Texas EPA Watch", "criticality": "high", "owner": "EHS / Compliance", "tags": "chemical,texas,epa", "facilityName": "BASF", "state": "TX", "facilitySearch": { "nameMatchMode": "CONTAINS" }, "complianceScreener": { "years": 5, "activeOnly": true, "nameMatchMode": "CONTAINS", "evidenceLimit": 5 } }, { "id": "delaware-afr-feed", "name": "Delaware Administrative Formal Cases", "criticality": "high", "owner": "Legal / Compliance", "tags": "case-feed,delaware,enforcement", "caseSearch": { "state": "DE", "caseCategory": "AFR", "fromDate": "01/01/2024", "toDate": "12/31/2024", "evidenceLimit": 5 } } ], "delivery": "dataset", "datasetMode": "changes_only", "snapshotKey": "epa-enforcement-example", "diffMode": "line_summary", "summaryMaxLines": 12, "maxEvidenceItems": 5, "concurrency": 2, "batchDelayMs": 500, "dryRun": false }'

Python

from apify_client import ApifyClient
client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("taroyamada/epa-enforcement-digest").call(run_input={
"targets": [
{
"id": "basf-texas",
"name": "BASF Texas EPA Watch",
"criticality": "high",
"owner": "EHS / Compliance",
"tags": "chemical,texas,epa",
"facilityName": "BASF",
"state": "TX",
"facilitySearch": {
"nameMatchMode": "CONTAINS"
},
"complianceScreener": {
"years": 5,
"activeOnly": true,
"nameMatchMode": "CONTAINS",
"evidenceLimit": 5
}
},
{
"id": "delaware-afr-feed",
"name": "Delaware Administrative Formal Cases",
"criticality": "high",
"owner": "Legal / Compliance",
"tags": "case-feed,delaware,enforcement",
"caseSearch": {
"state": "DE",
"caseCategory": "AFR",
"fromDate": "01/01/2024",
"toDate": "12/31/2024",
"evidenceLimit": 5
}
}
],
"delivery": "dataset",
"datasetMode": "changes_only",
"snapshotKey": "epa-enforcement-example",
"diffMode": "line_summary",
"summaryMaxLines": 12,
"maxEvidenceItems": 5,
"concurrency": 2,
"batchDelayMs": 500,
"dryRun": false
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

JavaScript / Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
const run = await client.actor('taroyamada/epa-enforcement-digest').call({
"targets": [
{
"id": "basf-texas",
"name": "BASF Texas EPA Watch",
"criticality": "high",
"owner": "EHS / Compliance",
"tags": "chemical,texas,epa",
"facilityName": "BASF",
"state": "TX",
"facilitySearch": {
"nameMatchMode": "CONTAINS"
},
"complianceScreener": {
"years": 5,
"activeOnly": true,
"nameMatchMode": "CONTAINS",
"evidenceLimit": 5
}
},
{
"id": "delaware-afr-feed",
"name": "Delaware Administrative Formal Cases",
"criticality": "high",
"owner": "Legal / Compliance",
"tags": "case-feed,delaware,enforcement",
"caseSearch": {
"state": "DE",
"caseCategory": "AFR",
"fromDate": "01/01/2024",
"toDate": "12/31/2024",
"evidenceLimit": 5
}
}
],
"delivery": "dataset",
"datasetMode": "changes_only",
"snapshotKey": "epa-enforcement-example",
"diffMode": "line_summary",
"summaryMaxLines": 12,
"maxEvidenceItems": 5,
"concurrency": 2,
"batchDelayMs": 500,
"dryRun": false
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Tips & Limitations

  • Run daily for active watchlists; weekly for passive monitoring.
  • Webhook delivery works well for compliance team Slack channels — include docket URL for 1-click access.
  • Use watchKeywords generously — false positives are cheap to triage, false negatives miss filings.
  • Pair with regulatory-change-monitor for cross-agency coverage.
  • Archive Dataset rows weekly for long-term compliance evidence retention.

FAQ

How far back does history go?

This actor monitors forward-only — new items since first run. For historical data, use the agency's own search tool.

What timezones are used?

All timestamps are UTC. Use your downstream pipeline to convert to agency-local time if needed.

Does it translate non-English content?

No — original language is preserved. Use downstream translation services if needed.

Is the data official?

Yes — sourced directly from official government websites and feeds. Not a third-party aggregator.

Can I use this for legal research?

For alerting and monitoring, yes. For litigation research, cross-verify with primary sources (agency websites) — this actor is a monitoring tool, not a legal database.

Government & Regulatory cluster — explore related Apify tools:

Cost

Failed targets are not charged. If every monitored source for a target fails (the target gets status: "error"), that target is not written to the dataset, so it is not billed. It is saved in the run's key-value store record FAILED_ROWS (and in the OUTPUT record), and the run status message says how many targets failed. Webhook delivery is unchanged.

Pay Per Event:

  • apify-default-dataset-item: $0.008 per digest row (one row per target)

Example: 10 targets = 10 rows = $0.08

No subscription required — you only pay for what you use.

⭐ Was this helpful?

If this actor saved you time, please leave a ★ rating on Apify Store. It takes 10 seconds, helps other developers discover it, and keeps updates free.

Bug report or feature request? Open an issue on the Issues tab of this actor.

Compliance Guardrails

This actor is independently operated and has no source-agency affiliation, sponsorship, or approval. It uses public data from EPA ECHO web services and public datasets (https://echo.epa.gov/tools/web-services). Results are informational only and may be delayed, incomplete, amended, withdrawn, or superseded by the source. Verify all records with the linked official source before relying on them.

  • Use EPA ECHO web services/data endpoints, not UI scraping.
  • No professional advice, certification, or opaque scoring.
  • Output source fields transparently with official source URLs and retrieval timestamps.