# OSHA & EPA Violation Monitor: Fines by Company (`offerastudio/osha-epa-violation-monitor`) Actor

Find US OSHA and EPA enforcement cases by company, state, industry and date: penalties, citations, violation type and a link to the official record. EPA works with no key; OSHA uses the free Department of Labor API key. No proxy or login.

- **URL**: https://apify.com/offerastudio/osha-epa-violation-monitor.md
- **Developed by:** [Offera Studio](https://apify.com/offerastudio) (community)
- **Categories:** Lead generation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 case returneds

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

### What does OSHA & EPA Violation Monitor do?

**OSHA & EPA Violation Monitor** finds **US workplace-safety (OSHA) and environmental (EPA) enforcement cases** and returns them in **one normalised format**: facility, address, state, industry code, dates, violation type, number of citations, **initial and current penalty** and a **link to the official record**. Both sources are official, free US government data:

- 🦺 **OSHA** inspections with citations, from the **US Department of Labor open data API** (the Occupational Safety and Health Administration's enforcement data). Citations are grouped per inspection, with the penalties added up and the most severe type (willful, repeat, serious, other-than-serious) shown.
- 🌿 **EPA** civil and criminal enforcement cases, from the **EPA ECHO** web services (Enforcement and Compliance History Online): Clean Air Act, Clean Water Act, RCRA, TSCA and other laws, with the federal penalty and the registered facility's address.

You can search by **company name (fuzzy)**, **state(s)**, **NAICS or SIC code**, **date range** (default last 90 days) and **minimum penalty**.

### Who is it for?

- **Insurers, underwriters and brokers**: check a client's or prospect's safety and environmental record before quoting.
- **Lenders, investors and due-diligence teams**: spot repeat and willful violators and large penalties in a portfolio or a supply chain.
- **Procurement and supplier-risk teams**: watch suppliers and contractors by name or by state and industry.
- **Journalists and researchers**: find the biggest recent penalties in a state or an industry.
- **Safety, ESG and compliance consultants**: lead lists of companies with fresh citations.

### How to use it

1. Click **Start** with the default input: **OSHA and EPA**, **Texas**, **last 90 days**, **minimum penalty $50,000**, up to 50 cases.
2. To check specific companies, add **company names** (for example `Cargill`, `Tyson Foods`); leave the state empty to search the whole country.
3. **Schedule** the Actor (for example weekly with the last 7 days) to get fresh cases, and connect the dataset to a spreadsheet, Slack or e-mail.

#### The OSHA key

OSHA data comes from the Department of Labor's API, which needs a **free API key** (register at [dataportal.dol.gov](https://dataportal.dol.gov)). The Actor reads the key from its own settings or from the optional **DOL API key** input field. **Without a key the Actor still runs: it returns the EPA cases and one free info row (`osha-key-missing`)** that explains how to switch OSHA on. You are never charged for that row.

### Input example

```json
{
    "sources": ["osha", "epa"],
    "companyNames": ["Cargill", "Tyson Foods"],
    "states": ["TX", "OK"],
    "naicsCodes": ["311"],
    "daysBack": 90,
    "minPenalty": 50000,
    "maxResults": 50,
    "sortBy": "date"
}
```

| Field | Meaning |
| --- | --- |
| `sources` | `osha`, `epa` or both (default both). |
| `companyNames` | Optional fuzzy names. Legal suffixes (Inc, LLC, Corp) are ignored, plurals and small typos are tolerated, all words of your name must appear. OSHA matches the establishment name; EPA matches the case name. |
| `states` | Two-letter state codes. Empty: whole country. |
| `naicsCodes`, `sicCodes` | NAICS prefixes (2 to 6 digits) and 4-digit SIC codes, up to 5 each. A case matching any of them is included. |
| `daysBack`, `dateFrom`, `dateTo` | The period, default the last 90 days. OSHA: citations issued in the period. EPA: cases with a filing, settlement, lodging or closing date in the period. |
| `minPenalty` | Only cases with at least this current penalty in USD. For OSHA the penalties of the inspection's citations are added up. |
| `maxResults` | Up to 1,000 (default 50). This also caps your cost. |
| `sortBy` | `date` (newest first, default) or `penalty` (largest first); decides which cases are kept when there are more than the maximum. |
| `epaFacilityDetails` | Adds the registered facility's name, address and NAICS to the first 60 EPA cases (two extra requests each). On by default. |
| `dolApiKey` | Optional secret field for your own DOL key. |

### Output example

Real output of a local run on 2 October 2026 with the default input, EPA part (no DOL key was available for the run): 18 cases in 43 seconds, here the first four.

| Source | Facility | City | Latest action | Violation | Penalty | Status |
| --- | --- | --- | --- | --- | --- | --- |
| epa | HESS CORPORATION | HOUSTON, TX | 2026-09-25 | Clean Water Act | $2,100,000 | Final Order Lodged |
| epa | GERDAU MIDLOTHIAN PLANT | MIDLOTHIAN, TX | 2026-09-14 | TSCA (toxic substances) | $112,156 | Final Order Issued |
| epa | INDORAMA VENTURES OXIDES, LLC - PASADENA PLANT | PASADENA, TX | 2026-09-14 | Clean Air Act | $132,737 | Final Order Issued |
| epa | FRIONA PLANT | FRIONA, TX | 2026-09-08 | Clean Air Act | $313,000 | Final Order Issued |

One row (real EPA data):

```json
{
    "source": "epa",
    "caseId": "06-2026-3555",
    "facilityName": "INDORAMA VENTURES OXIDES, LLC - PASADENA PLANT",
    "caseName": "Indorama Ventures-Pasadena, TX-RMP CAFO-FY 2026",
    "address": "9801 BAY AREA BOULEVARD, PASADENA,",
    "city": "PASADENA",
    "state": "TX",
    "zip": "77507",
    "naics": "325199",
    "openDate": "2026-09-11",
    "closeDate": "2026-09-14",
    "actionDate": "2026-09-14",
    "status": "Final Order Issued",
    "violationType": "Clean Air Act",
    "violationBreakdown": "Administrative - Formal, section 112[R][7]",
    "citationCount": null,
    "initialPenalty": null,
    "currentPenalty": 132737.29,
    "outcome": "Final Order With Penalty",
    "matchedName": null,
    "matchScore": null,
    "url": "https://echo.epa.gov/enforcement-case-report?id=06-2026-3555",
    "retrievedAt": "2026-10-02T09:43:17.190Z",
    "error": null,
    "errorMessage": null
}
```

An OSHA row has the same fields, with `citationCount`, `initialPenalty`, `currentPenalty` (sums over the inspection's citations in the period) and a `violationBreakdown` such as `Willful 1, Serious 1, Other-than-serious 1`. Its `url` points to the OSHA inspection page. `initialPenalty` and `outcome` do not exist for EPA cases and are `null` there; `citationCount` is `null` for EPA.

### Pair it with product recalls

A company with fresh OSHA or EPA cases may also have product problems. Take the `facilityName` values and check them with the [US Product Recalls Monitor](https://apify.com/offerastudio/us-product-recalls-monitor) (FDA and CPSC recalls in one feed), for a fuller picture of a manufacturer or food business.

### How much does it cost?

This Actor uses **pay per event**:

| Event | Price |
| --- | --- |
| Case returned (one row per OSHA inspection or EPA case) | **$0.003** |
| Info and error rows (missing key, no results, source errors) | **free** |

- The default run (18 EPA cases) costs about **$0.054**; 1,000 cases cost **$3**.
- Both government APIs are free. Apify also charges a tiny standard start fee per run.
- Set **Maximum cost per run** in the run options and the Actor stops when it is reached; `maxResults` also caps the number of billed rows.

### Limitations

- **Official data as published.** OSHA and EPA data can lag, contain errors and change; penalties are the agencies' figures at the time of the run. This is not legal advice or a compliance certificate.
- **OSHA needs a key** (free). Without it only EPA is returned. OSHA's dataset has no state or company filter for citations, so the Actor reads the citations of the period and then looks up the inspections; very broad searches (a whole year, all states, no minimum penalty) read at most the newest 80,000 citations and check at most 6,000 inspections, and say so in the log. Narrow the search with a state or a minimum penalty.
- **EPA company search matches the case name**, not every name the facility ever had. Case names usually contain the company name (`Cargill Meat Solutions-Friona, TX ...`), but not always.
- **EPA dates**: the period matches cases with any milestone (filed, settled, lodged, closed) in it, so a case filed years ago but settled this month is included; `openDate` can then be old or empty. `actionDate` is the latest of the dates.
- **EPA rate limit**: EPA ECHO allows about 300 requests an hour and 1,500 a day per IP address. A default run uses about 40. Facility details are therefore added to the first 60 cases only; the Actor reports a `rate-limited` problem as a free `epa-error` row and returns what it has.
- **Penalties differ by source**: OSHA penalties are the sum of the citations' current and initial penalties; EPA shows the federal penalty assessed. State agencies' penalties and EPA's supplemental projects are not included.
- No personal data about individuals is returned; sole proprietors appear under the establishment name the agency published.

### FAQ

#### Is this official data?

Yes. OSHA data comes from the US Department of Labor open data API and EPA data from EPA ECHO. The Actor links every row to the official record where one exists.

#### Do I need to register anywhere?

Only for OSHA: a free DOL API key. EPA needs nothing.

#### Why do I get an `osha-key-missing` row?

No DOL key was set. It is free and never charged. Add the key in the input or ask the Actor owner to set it.

#### Can I look up a single company?

Yes: put the name in `companyNames` and leave `states` empty (and consider a longer period, for example `daysBack` 365). A name matches when all its words appear in the establishment or case name, ignoring suffixes like Inc.

#### How fresh is it?

Both agencies publish with a delay: EPA ECHO refreshes its data on a regular schedule and OSHA citations often appear months after an inspection starts. `retrievedAt` shows when the Actor asked.

### More tools from the same developer

All pay-per-result, no proxy or login needed, built and maintained by the same developer:

**Website audits**

- [Website Accessibility Checker: WCAG 2.2 & EAA](https://apify.com/offerastudio/website-accessibility-audit): accessibility issues with fixes, SEO basics and security headers.
- [Cookie & Tracker Audit: GDPR Consent Checker](https://apify.com/offerastudio/cookie-tracker-audit): cookies and tracking tags that load before consent.
- [AI Crawler Access Checker: robots.txt & llms.txt](https://apify.com/offerastudio/ai-crawler-access-audit): which AI crawlers a site allows, plus llms.txt.
- [Structured Data Validator: Schema & Rich Results](https://apify.com/offerastudio/structured-data-validator): JSON-LD and Microdata checked against Google's rich result rules.
- [Website Change Monitor: Diffs, Prices & Alerts](https://apify.com/offerastudio/website-change-monitor): get a row only when a page changes, with a clean diff.
- [Policy Change Monitor: Privacy & Terms Tracker](https://apify.com/offerastudio/policy-change-monitor): privacy policy and terms changes, classified clause by clause.
- [SaaS Pricing Monitor: Track Competitor Plans](https://apify.com/offerastudio/saas-pricing-monitor): competitor pricing plans as structured data, with price-change diffs.
- [Sitemap Change Monitor: New & Removed URLs](https://apify.com/offerastudio/sitemap-change-monitor): new, removed and changed URLs from a site's sitemaps.
- [Site SEO Crawler: Broken Links & On-Page Audit](https://apify.com/offerastudio/site-seo-crawler-audit): site-wide crawl for broken links, redirects and on-page SEO issues.
- [Website Tech Stack Detector: Bulk Lead Filters](https://apify.com/offerastudio/website-tech-stack-detector): technologies used by websites, with filters for lead lists.
- [Domain Availability & Expiry Checker (RDAP)](https://apify.com/offerastudio/domain-whois-availability): domain availability, registrar and expiry dates from RDAP.
- [Status Page SLA Monitor: Uptime & Incidents](https://apify.com/offerastudio/status-page-sla-monitor): SaaS vendor uptime, incidents and a monthly SLA table from public status pages.

**Company data and compliance**

- [Company Contact Finder: Emails, Phones & Socials](https://apify.com/offerastudio/company-contact-finder): contact details published on company websites.
- [UK New Companies Feed: Companies House Daily](https://apify.com/offerastudio/uk-new-companies-feed): newly incorporated UK companies with sector filters.
- [EU VAT Number Validator: Bulk VIES Checker](https://apify.com/offerastudio/eu-vat-number-validator): bulk VAT checks with name, address and consultation number.
- [LEI Corporate Tree: GLEIF Parents & Subsidiaries](https://apify.com/offerastudio/gleif-lei-corporate-tree): LEI lookup with parents, subsidiaries and a KYC summary.
- [UK Company Distress Watch: Insolvency Alerts](https://apify.com/offerastudio/uk-company-distress-watch): administrations, liquidations and winding-up petitions from The Gazette.
- [IBAN Validator: Bulk Check & Bank Lookup](https://apify.com/offerastudio/iban-bank-validator): IBAN format and checksum, plus bank name and BIC where open data exists.
- [Sanctions Screening: OFAC, EU, UN & UK Lists](https://apify.com/offerastudio/sanctions-screening): names screened against official sanctions lists, with match scores.
- [Email List Precheck: Syntax, MX & Disposable Check](https://apify.com/offerastudio/email-list-precheck): cheap email list hygiene before a real verification.
- [UK Company Officer Changes: Director & PSC Alerts](https://apify.com/offerastudio/uk-company-officer-changes): director, owner, address and status changes for a watchlist of UK companies.
- [FDA Warning Letters Monitor: By Company & Subject](https://apify.com/offerastudio/fda-warning-letters-monitor): FDA warning letters by company and subject, with cited regulations.
- [Supplier Risk Report: Sanctions, VAT & Insolvency](https://apify.com/offerastudio/supplier-risk-report): one risk row per supplier from eight official registers, with changes since last run.
- [Brand Impersonation Domain Monitor: Look-alikes](https://apify.com/offerastudio/brand-impersonation-domain-monitor): look-alike domains and certificates that imitate your brand, with a risk score.

**Media and AI**

- [Audio & Video Transcriber: Podcasts, SRT, Speakers](https://apify.com/offerastudio/audio-video-transcriber): audio, video, podcasts and social links to text, SRT and VTT.
- [Podcast Mention Alerts: Brand Mentions by Second](https://apify.com/offerastudio/podcast-mention-alerts): where your brand is said in new podcast episodes, with the exact second.
- [News Brand Mentions Monitor: New Articles Only](https://apify.com/offerastudio/news-brand-mentions-monitor): new news articles about your brand, people or topics.
- [YouTube Channel Monitor: New Videos & Growth](https://apify.com/offerastudio/youtube-channel-monitor): new videos and view growth of the channels you watch.

**Market signals**

- [US WARN Layoff Notices: 12 States Daily Feed](https://apify.com/offerastudio/us-warn-layoff-notices): layoff and plant closure notices from official state sources.
- [US Product Recalls Monitor: FDA & CPSC Feed](https://apify.com/offerastudio/us-product-recalls-monitor): FDA and CPSC recalls in one feed, with severity.
- [EU Tenders Feed: TED Public Procurement Alerts](https://apify.com/offerastudio/eu-tender-feed): EU public tenders from TED with CPV, country and value filters.
- [Liquor License Openings: New Bars & Stores (US)](https://apify.com/offerastudio/liquor-license-openings): new US liquor licences from official state open data.
- [Clinical Trials Change Monitor: Status & Updates](https://apify.com/offerastudio/clinicaltrials-change-monitor): status, enrollment and results changes on ClinicalTrials.gov studies.
- [Career Site Jobs Monitor: ATS Jobs & New Roles](https://apify.com/offerastudio/career-site-jobs-monitor): open roles from company career sites, with new and closed roles since the last run.
- [App Reviews Monitor: App Store & Google Play](https://apify.com/offerastudio/app-store-reviews-monitor): app reviews from both stores, only new ones in monitor mode.
- [US Federal Contracts Feed: SAM.gov & USAspending](https://apify.com/offerastudio/us-federal-contracts-feed): SAM.gov contract opportunities with the buyer's award history.
- [Grants.gov Opportunities: US Federal Grants Feed](https://apify.com/offerastudio/grants-gov-opportunities): US federal grant opportunities by keyword, eligibility and agency.
- [Federal Register Monitor: US Rules & Notices Feed](https://apify.com/offerastudio/federal-register-monitor): new US rules, proposed rules and notices by agency or topic.
- [B2B Sales Trigger Feed: Hiring + Tech Leads](https://apify.com/offerastudio/b2b-sales-trigger-feed): companies hiring for a role and using (or not using) a technology, with contacts.
- [Local Business Leads: OpenStreetMap, No Website](https://apify.com/offerastudio/local-business-leads-osm): local businesses by city and category, including those with no website.
- [Solana Token Pair Monitor: New & Trending Pairs](https://apify.com/offerastudio/solana-token-pair-monitor): new and trending Solana pairs with liquidity, volume and safety flags.

### Feedback

Missing a field or a filter? Open an issue on the **Issues** tab.

# Changelog

This Actor's version history is a separate document: https://apify.com/offerastudio/osha-epa-violation-monitor/changelog.md

# Actor input Schema

## `sources` (type: `array`):

OSHA: workplace-safety inspections with citations (needs a free DOL API key). EPA: environmental enforcement cases from EPA ECHO (no key). Leave both for the full picture.

## `companyNames` (type: `array`):

Optional. Companies or facilities to find, for example Cargill or "Tyson Foods". Matching is fuzzy: legal suffixes such as Inc or LLC are ignored and small typos are tolerated. EPA matches on the case name. Leave empty to list every case that fits the other filters.

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

Two-letter US state codes, for example TX or CA. Leave empty for all states.

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

Industry codes or prefixes of 2 to 6 digits, for example 311 (food manufacturing) or 2381. Up to 5. A case matching any of them is included.

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

4-digit SIC codes, for example 2011. Up to 5.

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

Cases with activity in the last N days. OSHA: citations issued. EPA: filed, settled or closed. Ignored when "Date from" is set.

## `dateFrom` (type: `string`):

Optional start of the period (YYYY-MM-DD). Overrides "Days back".

## `dateTo` (type: `string`):

Optional end of the period (YYYY-MM-DD). Default: today.

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

Only cases with a current penalty of at least this amount. OSHA: the sum of the inspection's citations.

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

Upper limit of cases returned, and so of the cost: at most this many cases are billed.

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

Which cases are kept when there are more than the maximum.

## `epaFacilityDetails` (type: `boolean`):

Looks up the registered facility (name, address, NAICS) of each EPA case. Costs two extra requests per case, for the first 60 cases. Turn off for a faster run.

## `dolApiKey` (type: `string`):

Optional. Free key from dataportal.dol.gov. If left empty the Actor uses its own key, when it has one. Without any key only EPA cases are returned.

## Actor input object example

```json
{
  "sources": [
    "osha",
    "epa"
  ],
  "states": [
    "TX"
  ],
  "daysBack": 90,
  "minPenalty": 50000,
  "maxResults": 50,
  "sortBy": "date",
  "epaFacilityDetails": true
}
```

# Actor output Schema

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

No description

## `details` (type: `string`):

No description

# API

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

## JavaScript example

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

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

// Prepare Actor input
const input = {
    "sources": [
        "osha",
        "epa"
    ],
    "states": [
        "TX"
    ],
    "daysBack": 90,
    "minPenalty": 50000,
    "maxResults": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("offerastudio/osha-epa-violation-monitor").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 = {
    "sources": [
        "osha",
        "epa",
    ],
    "states": ["TX"],
    "daysBack": 90,
    "minPenalty": 50000,
    "maxResults": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("offerastudio/osha-epa-violation-monitor").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 '{
  "sources": [
    "osha",
    "epa"
  ],
  "states": [
    "TX"
  ],
  "daysBack": 90,
  "minPenalty": 50000,
  "maxResults": 50
}' |
apify call offerastudio/osha-epa-violation-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,offerastudio/osha-epa-violation-monitor"
        }
    }
}
```

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/q8K9iwOavdlfoU92b/builds/hhcQaTks7q9d2thhV/openapi.json
