# OSHA Inspections & Citations Feed - Workplace Safety Penalties (`moment-data/osha-inspections-feed`) Actor

Feed of new OSHA workplace-safety inspections and citations from official US Dept. of Labor data: company, site address, industry (NAICS), inspection type (fatality, complaint...), violations, standards cited, penalties. Filter by state, industry, penalty. New-since-last-run alerts.

- **URL**: https://apify.com/moment-data/osha-inspections-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 inspection records

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

Learn more: https://docs.apify.com/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

## OSHA Inspections & Citations Feed: Workplace Safety Violations and Penalties API

Get a clean, daily feed of **new OSHA workplace-safety inspections and citations** at US companies and job sites: **who was inspected, where, in what industry, why (fatality, accident, complaint, referral, planned...), how many serious / willful / repeat violations were cited, which OSHA standards were broken (in plain English), and the penalties**, with a direct link to the official OSHA inspection page. Export as JSON, CSV or Excel, or schedule it in *new since last run* mode as an OSHA alert feed.

Data comes straight from the **U.S. Department of Labor's official OSHA enforcement data** (the inspection and violation tables DOL publishes daily at data.dol.gov), the same data behind OSHA's *Establishment Search*. No login, no API key, no scraping of osha.gov.

**Why this one:** most OSHA tools are *company lookups* (you must already know who to ask about) or need a DOL API key. This Actor is **time-based and nationwide**: it tells you **which employers were just cited or just inspected across the whole country**, newest first, with every citation rolled up into one flat record. A default run takes about 10 seconds.

### Who it is for

- **Safety consultants, trainers and EHS software vendors**: prospect employers that were just cited for fall protection, trenching, lockout/tagout, silica or forklift violations, the week the data appears. Filter by state and industry.
- **Insurance carriers, brokers and underwriters (workers' comp, GL)**: loss-control and underwriting signals by employer, NAICS and state; fatality and catastrophe inspections.
- **Workplace-safety and employment lawyers**: new willful and repeat citations and large penalties (contest deadlines are short).
- **Staffing agencies, GCs and procurement / supplier-risk teams**: vet subcontractors and suppliers before you hire them.
- **ESG and investment analysts**: workplace-safety controversies at portfolio companies.
- **Journalists, unions, NGOs and researchers**: weekly digests of the largest OSHA penalties and fatality investigations.
- **Developers**: normalized OSHA data through the Apify API, webhooks and integrations (Slack, Google Sheets, Zapier, Make, n8n).

### What you get for each inspection

- **Event**: `eventType` = `cited` (citations issued in the window) or `opened` (inspection opened in the window), and `eventDate`.
- **Who / where**: establishment (employer) name, site address, city, state, ZIP, NAICS code with sector and industry names, SIC code, owner type (private / local / state / federal government), employees at the site, union status.
- **Inspection**: OSHA activity number, type (fatality/catastrophe, accident, complaint, referral, planned, follow-up...), scope, safety vs. health, federal OSHA vs. state plan, open date, closing conference and case close dates, case status.
- **Violations and money**: total violations; serious, willful, repeat and other counts; initial and current penalties; failure-to-abate penalties; employees exposed; first/latest citation date; contested flag; final order date.
- **What was wrong**: OSHA standards cited (e.g. `1926.501`) and plain-English hazard topics (e.g. *Fall protection*, *Excavations (protective systems / trenching)*, *Lockout/tagout*), plus up to 25 citation lines per inspection (standard as `29 CFR 1926.501(b)(13)`, type, penalty, abatement date, gravity).
- **Links and freshness**: `oshaUrl` (official OSHA inspection detail page), `dataAsOf` (DOL file date), `firstSeenAt`.
- **New since last run** mode with saved history per *State key*: an inspection is delivered once when it is opened and again when it is cited.
- **Privacy by design**: entity-level data only. Establishment names that look like a private individual's name (sole proprietors) are withheld (`[individual - name withheld]`); no inspector names, no complainant or victim data, no phone numbers.

### Quick start

1. Click **Start** with the default input. You get 40 records: the 20 most recently **cited** inspections (with violations and penalties) and the 20 most recently **opened** inspections nationwide, from the last 60 days.
2. Narrow it down: `states`, `naicsPrefixes` (e.g. `23` construction), `inspectionTypes`, `companyKeyword`, `minPenalty`, `seriousOrWillfulOnly`. Raise `maxItems` (up to 50,000) and `daysBack` (up to 365) for bigger pulls.
3. **Weekly OSHA alerts (schedule tip):** create an Apify **Schedule** (e.g. every Monday 7:00) with:

```json
{ "mode": "sinceLastRun", "stateKey": "co-construction", "states": ["CO"], "naicsPrefixes": ["23"], "daysBack": 90, "maxItems": 500 }
```

Each run delivers only inspections (or new citations of an inspection) not delivered before for that `stateKey`. Connect Slack, e-mail, Google Sheets or a webhook. Use one `stateKey` per schedule. Keep `daysBack` at 60-90 because DOL's public citation table lags several weeks behind the inspection table; the saved history makes sure you never get the same event twice. DOL refreshes the files daily, so a daily or weekly schedule is enough.

More examples:

- Big penalties nationwide this quarter: `{ "events": ["cited"], "minPenalty": 50000, "daysBack": 90, "maxItems": 500 }`
- Fatality / catastrophe inspections just opened in Texas: `{ "events": ["opened"], "states": ["TX"], "inspectionTypes": ["fatality-catastrophe"], "daysBack": 30 }`
- Willful / repeat citations in warehousing (NAICS 493) and trucking (484): `{ "events": ["cited"], "naicsPrefixes": ["493", "484"], "seriousOrWillfulOnly": true, "daysBack": 180 }`
- Everything for one company: `{ "companyKeyword": "Amazon", "daysBack": 365, "maxItems": 1000 }`
- Lean export without citation lines: `{ "daysBack": 365, "maxItems": 20000, "includeCitations": false }`

### Input

| Field | Default | Meaning |
|---|---|---|
| `events` | `cited`, `opened` | `cited` = citations issued in the window; `opened` = inspections opened in the window. With both, up to half of `maxItems` go to citations |
| `states` | all | site state codes, e.g. `TX`, `CA`, `PR` |
| `naicsPrefixes` | all | NAICS prefixes, e.g. `23`, `238`, `311`, `493`, `622` |
| `inspectionTypes` | all | `fatality-catastrophe`, `accident`, `complaint`, `referral`, `planned`, `follow-up`, ... |
| `companyKeyword` | none | establishment name contains this text |
| `minPenalty` | 0 | minimum total current or initial penalty in USD (cited only) |
| `seriousOrWillfulOnly` | false | at least one serious, willful or repeat violation (cited only) |
| `daysBack` | 60 | events in the last N days (1-365) |
| `maxItems` | 40 | cap per run (also caps spend); newest first, bigger penalties first on the same day |
| `includeCitations` | true | add up to 25 citation lines per inspection |
| `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
{
  "eventType": "cited",
  "eventDate": "2026-09-25",
  "activityNr": "348914755",
  "establishmentName": "VC EQUIPMENT, CORP.",
  "siteCity": "CAGUAS",
  "siteState": "PR",
  "siteZip": "00725",
  "naicsCode": "238910",
  "naicsSector": "Construction",
  "industry": "Specialty Trade Contractors",
  "inspectionType": "fatality-catastrophe",
  "inspectionTypeLabel": "Fatality / catastrophe",
  "jurisdiction": "state-plan",
  "employeesAtSite": 50,
  "openDate": "2026-04-27",
  "caseStatus": "closed",
  "violationsTotal": 4,
  "seriousViolations": 1,
  "willfulViolations": 2,
  "initialPenalty": 246105,
  "currentPenalty": 98442,
  "standardsCited": ["1926.651", "1926.21", "1926.652", "1926.20"],
  "hazardTopics": ["Excavations (specific requirements)", "Safety training and education", "Excavations (protective systems / trenching)", "General safety and health provisions"],
  "citations": [
    { "citationId": "02001", "standard": "29 CFR 1926.21(b)(2)", "topic": "Safety training and education", "violationType": "willful", "issuanceDate": "2026-09-25", "abateDate": "2026-10-21", "initialPenalty": 115860, "currentPenalty": 46344 }
  ],
  "dataAsOf": "2026-10-29",
  "oshaUrl": "https://www.osha.gov/ords/imis/establishment.inspection_detail?id=348914755"
}
```

Full examples: `sample-output.json`. Every run also writes a summary (window, filters, candidate counts, `dataAsOf`, `latestCitationDateInData`) to the `OUTPUT` record. The dataset has an *OSHA inspections* table view.

### Glossary

**Serious** = substantial probability of death or serious harm. **Willful** = knowing disregard or plain indifference. **Repeat** = same or similar violation cited within 5 years. **Initial vs. current penalty** = proposed penalty vs. after informal settlement / contest. **State plan** = inspections by a state OSHA program (e.g. Cal/OSHA, MIOSHA) rather than federal OSHA. **Activity number** = OSHA's inspection ID.

### Data source, update timing and fair use

- **U.S. Department of Labor, OSHA enforcement data**: the `inspection` and `violation` tables published as daily bulk files at data.dol.gov (public domain U.S. Government data, free, no API key). The Actor reads only the recent parts of these multi-GB files with HTTP range requests (about 80 MB per run), with a declared User-Agent, modest concurrency and retries.
- DOL refreshes the files daily. Inspections usually appear within days of opening; citations reach the public violation table several weeks after issuance (the run summary shows `latestCitationDateInData`). Open cases can still change (penalties are often reduced in settlements; see `currentPenalty` and `finalOrderDate`).
- Not affiliated with or endorsed by the U.S. Department of Labor or OSHA. A citation is an allegation until it becomes a final order. Confirm critical decisions against the official inspection page (`oshaUrl`).
- Related feeds from moment-data: [Federal Contract Awards Feed](https://apify.com/moment-data/federal-contract-awards-feed), [US Product Recalls Feed](https://apify.com/moment-data/product-recalls-feed), [Building Permits Feed](https://apify.com/moment-data/building-permits-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 inspection record 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 DOL's daily files (`dataAsOf`). New inspections show up within days; citations lag several weeks, so use `daysBack` 60+ with `sinceLastRun` and you will catch them as they land.
**Why do "opened" records have no violations?** OSHA has up to 6 months to issue citations after an inspection. Recently opened inspections are an early signal; the same inspection is delivered again as `cited` once citations are published (in `sinceLastRun` mode).
**Why is a name shown as `[individual - name withheld]`?** Some sole proprietors are inspected under their personal name; we withhold those for privacy. The `activityNr` and `oshaUrl` still identify the inspection.
**Can I get older history?** Up to 365 days per run with `daysBack`.

# Actor input Schema

## `events` (type: `array`):

cited = inspections whose citations (violations + penalties) were issued in the window. opened = inspections opened in the window (early signal; citations usually follow months later). With both, up to half of maxItems go to citations.

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

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

## `naicsPrefixes` (type: `array`):

Optional. NAICS code prefixes, e.g. 23 (construction), 238 (specialty trade contractors), 311 (food manufacturing), 493 (warehousing), 622 (hospitals). Empty = all industries.

## `inspectionTypes` (type: `array`):

Optional. Why OSHA inspected. Empty = all types.

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

Optional. Text match on the inspected establishment (employer) name, e.g. 'Amazon', 'Tyson', 'Construction'.

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

Optional. Only cited inspections whose total current or initial penalty is at least this amount, e.g. 50000. Implies the 'cited' event.

## `seriousOrWillfulOnly` (type: `boolean`):

Only cited inspections with at least one serious, willful or repeat violation. Implies the 'cited' event.

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

Citations issued / inspections opened in the last N days. DOL's public citation table lags several weeks behind the inspection table, so keep this at 60 or more if you want citations.

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

Hard cap on delivered records (also caps your spend). Newest first; bigger penalties first on the same day.

## `includeCitations` (type: `boolean`):

Add the individual citation items (standard, plain-English topic, type, penalty, abatement date) to each cited inspection, up to 25 per inspection.

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

window (default): everything in the time window, no saved state. sinceLastRun: only events not delivered before for this State key (an inspection is delivered once when opened and again when cited). 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
{
  "events": [
    "cited",
    "opened"
  ],
  "states": [],
  "naicsPrefixes": [],
  "seriousOrWillfulOnly": false,
  "daysBack": 60,
  "maxItems": 40,
  "includeCitations": true,
  "mode": "window",
  "stateKey": "default"
}
```

# Actor output Schema

## `inspections` (type: `string`):

One record per inspection event (cited or opened).

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

Window, filters, counts, data freshness (dataAsOf, latestCitationDateInData).

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

// Run the Actor and wait for it to finish
const run = await client.actor("moment-data/osha-inspections-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": [],
    "naicsPrefixes": [],
}

# Run the Actor and wait for it to finish
run = client.actor("moment-data/osha-inspections-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": [],
  "naicsPrefixes": []
}' |
apify call moment-data/osha-inspections-feed --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,moment-data/osha-inspections-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/tEk4zMncyKahBqE4w/builds/lRfQcp2mFCfVOvfFU/openapi.json
