# New OSHA Inspection Leads 🦺 (within 2 days of opening) (`tagadanar/osha-inspection-leads`) Actor

Every new US OSHA workplace-safety inspection, usually within a day or two of it opening: establishment, site address, city, state, NAICS industry, inspection type and scope, and the OSHA office running it. Monitor mode returns only inspections new since your last run, with a Slack digest.

- **URL**: https://apify.com/tagadanar/osha-inspection-leads.md
- **Developed by:** [Tagada Data](https://apify.com/tagadanar) (community)
- **Categories:** Lead generation, Automation, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 1,000 inspection founds

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## New OSHA Inspection Leads

Every new US workplace-safety inspection OSHA opens, usually within a day or two
of the inspector walking in. You get the establishment, the site address, the
industry, the type of inspection and the OSHA office running it, as one clean row
per inspection. Run it on a schedule and it hands you only the inspections that
are new since your last run.

This sells **new inspections**, not penalties. An inspection appears on osha.gov
within 0 to 2 days of opening, while citations and dollar amounts are only posted
30 days after the employer receives them, and the case often stays open for
months. If a company is being inspected today, this is where you find out today.
Penalties are in the record too, and they fill in later when OSHA publishes them.

Federal OSHA and all 22 state-plan agencies (Cal/OSHA, WA DOSH, Oregon OSHA,
Michigan MIOSHA and the rest), 55 states and territories in total. No API key,
nothing to sign up for. You only pay for inspections you actually get back.

### Who uses this

- **Safety consultants and EHS firms.** A company that just got inspected is a
  company that suddenly needs a safety audit, training or an abatement plan. The
  inspection type tells you why: a complaint, a referral, a fatality.
- **Workers' comp and liability insurers.** New inspection activity in a book of
  business, or a portfolio-wide watch on high-hazard NAICS codes, weeks before
  any penalty is public.
- **Workplace safety and employment lawyers.** Fatality and catastrophe
  inspections, filtered to a state and an industry, the day they open.
- **Industrial hygiene, fall protection and PPE suppliers** prospecting into
  construction, manufacturing and warehousing right when a site is under scrutiny.
- **Risk and compliance teams** monitoring their own sites, contractors and
  suppliers without refreshing osha.gov by hand.

Pair it with our [US WARN Layoff Monitor](https://apify.com/tagadanar/us-warn-layoffs)
if you sell into the same buyers: WARN tells you which employers are shrinking,
this one tells you which are under a safety inspection. Same states, same clean
schema, same monitor mode.

### What you get

One record per inspection:

| Field | Description |
| --- | --- |
| `inspectionNumber` | OSHA inspection number, e.g. `1907491.015` |
| `openedDate` | Date the inspection was opened |
| `company` | Establishment inspected |
| `siteAddress`, `siteCity`, `siteState`, `siteZip` | The inspected site |
| `mailingAddress` | The employer's mailing address, often a different HQ |
| `state`, `stateCode` | State the site is in |
| `officeName`, `officeCode` | OSHA area, district or state-plan office running it |
| `inspectionType` | As OSHA labels it: Fat/Cat, Complaint, Referral, Planned, FollowUp, Unprog Rel |
| `inspectionCategory` | The same in plain words: fatality-catastrophe, complaint, referral, planned, follow-up, other |
| `scope` | Complete, Partial or Records |
| `safetyHealth` | Safety or Health inspection |
| `ownership` | Private, Local Government, State Government, Federal |
| `unionStatus` | Union or NonUnion site |
| `emphasis` | National and local emphasis programs that triggered it, e.g. `N:Fall` |
| `naicsCode`, `naicsTitle` | Industry, e.g. `238160` / Roofing Contractors |
| `sicCode` | Legacy SIC code, where OSHA still records one |
| `caseStatus` | OPEN or CLOSED |
| `closeConference`, `caseClosedDate` | Closing conference date, and the date the case closed |
| `totalViolations`, `seriousViolations`, `willfulViolations`, `repeatViolations`, `otherViolations` | Violation counts, once cited |
| `initialPenalty`, `currentPenalty` | Proposed and current penalty in USD, once cited |
| `sourceUrl` | The OSHA inspection detail page |
| `isNew` | In monitor mode, whether this inspection is new since the last run |

Sample row, a Cal/OSHA heat-illness inspection of a farm, captured the day after
it opened:

```json
{
  "inspectionNumber": "1909379.015",
  "openedDate": "2026-08-05",
  "company": "Victors Grove Services Inc",
  "siteAddress": "Victors Grove Services Inc, 74th Avenue & Polk Street",
  "siteCity": "Thermal",
  "siteState": "CA",
  "siteZip": "92274",
  "mailingAddress": "31560 Via Del Paso, Winchester, CA 92596",
  "stateCode": "CA",
  "state": "California",
  "officeCode": "0950694",
  "officeName": "El Centro Agricultural Enforcement Task Force District Office",
  "inspectionType": "Planned",
  "inspectionCategory": "planned",
  "scope": "Complete",
  "safetyHealth": "Health",
  "ownership": "Private",
  "unionStatus": "NonUnion",
  "advancedNotice": "N",
  "emphasis": "P:Aetf, N:Heatnep, S:Aetf, S:Heatsep-Outdoor",
  "naicsCode": "111219",
  "naicsTitle": "Other Vegetable (except Potato) and Melon Farming",
  "sicCode": null,
  "caseStatus": "OPEN",
  "closeConference": null,
  "caseClosedDate": null,
  "totalViolations": null,
  "seriousViolations": null,
  "willfulViolations": null,
  "repeatViolations": null,
  "otherViolations": null,
  "initialPenalty": null,
  "currentPenalty": null,
  "sourceUrl": "https://www.osha.gov/ords/imis/establishment.inspection_detail?id=1909379.015",
  "isNew": null,
  "retrievedAt": "2026-08-07T00:35:29.849Z"
}
```

The nulls on that row are not missing data, they are the point: the inspection
opened the day before, so no citation exists yet. Rows for closed cases carry the
full violation counts and both penalty figures.

### Input examples

Every construction inspection opened in Texas in the last week:

```json
{
  "states": ["TX"],
  "sinceDays": 7,
  "naicsPrefixes": ["23"],
  "maxInspections": 200
}
```

A daily fatality and catastrophe watch across the Gulf states, alerting Slack:

```json
{
  "states": ["TX", "LA", "MS", "AL", "FL"],
  "inspectionTypes": ["fatality-catastrophe"],
  "sinceDays": 3,
  "monitorMode": true,
  "webhookUrl": "https://hooks.slack.com/services/XXX/YYY/ZZZ"
}
```

One metro only, by OSHA office, complaints and referrals:

```json
{
  "offices": ["626600", "626700"],
  "inspectionTypes": ["complaint", "referral"],
  "sinceDays": 30
}
```

Watch named companies anywhere in California, including closed cases with
penalties:

```json
{
  "states": ["CA"],
  "keywords": ["Amazon", "Tesla"],
  "sinceDays": 365,
  "caseStatus": "closed"
}
```

### How monitor mode works

Turn on `monitorMode` and schedule the actor, daily is typical. The first run
returns up to `maxInspections` from your look-back window and treats the rest of
that window as history. Every run after that returns, and charges for, only
inspections it has never reported, and posts them to your webhook if you set one.
A daily run costs you the handful of new inspections in your states, not the
whole window again.

The memory is per actor, kept in a named key-value store, so it survives across
runs and across schedules.

### Choosing states or offices

`states` is what most people want: pick the states you sell into and the actor
sweeps every OSHA office that works there, federal or state-plan.

`offices` is for narrowing to a metro. OSHA's field structure is area offices
(Houston North, Houston South, Fort Worth) and state-plan district offices, and
the dropdown gives you all of them with their codes. When you set `offices`, only
those offices are swept; a `states` list set alongside it still filters the
results, which is useful for the handful of offices that straddle a state line.

### Frequently asked questions

**How fresh is the data?**
OSHA publishes an inspection 0 to 2 days after it opens. A run logs the exact
date OSHA says its data is current through, so you always know.

**Does this include penalty amounts?**
Yes, when they exist. They usually do not exist yet on a new inspection: OSHA
posts citations 30 days after the employer receives them, and many cases stay
open for months. Set `caseStatus` to `closed` and a long `sinceDays` if what you
want is settled cases with final penalties.

**Does it cover state-plan states like California, Washington and Michigan?**
Yes. Cal/OSHA, WA DOSH, Oregon OSHA, MIOSHA, MNOSHA, NC DOL, Puerto Rico and the
rest all report into the same OSHA database, and all 55 states and territories
are covered.

**Do I need an API key or a DOL account?**
No. The DOL's own inspection API is key-gated and its bulk CSV files were
retired; this actor reads OSHA's public establishment search instead, so there is
nothing to register for.

**Can I filter by industry?**
Yes, with `naicsPrefixes`. Prefixes match from the left, so `23` gets all of
construction, `2381` gets foundation and structure contractors, `238160` gets
roofing only.

**How do I find inspections of one specific company?**
Put the name in `keywords` and widen `sinceDays`. Keywords match the
establishment name, city, street address and industry title.

**What is the difference between an inspection type and a category?**
`inspectionType` is OSHA's own label, which is terse (`Fat/Cat`, `Unprog Rel`).
`inspectionCategory` is the same information in words you can filter and report
on. The `inspectionTypes` input filters on the category.

**Why does one inspection number end in .015?**
That is how OSHA keys its inspection records. It is kept exactly as published so
the number matches OSHA's own pages and any other OSHA data you hold.

**Is this legal to use for prospecting?**
It is US federal and state public enforcement data, published by OSHA for public
inspection. It is establishment data, not personal data.

### Related actors

- [US WARN Layoff Monitor](https://apify.com/tagadanar/us-warn-layoffs): plant closings and mass layoffs from the state workforce agencies.
- [New Contractor License Leads](https://apify.com/tagadanar/contractor-license-leads): newly issued CA, FL and TX contractor licenses.
- [FDA Warning Letters Monitor](https://apify.com/tagadanar/fda-warning-letters): new FDA enforcement letters, the day they are posted.
- [FMCSA Carrier Leads](https://apify.com/tagadanar/fmcsa-carrier-leads): newly authorised US trucking carriers.

***

OSHA inspection scraper, OSHA inspection data, OSHA enforcement data, workplace
safety leads, OSHA violations by company, OSHA inspection search, safety
consultant leads, EHS lead generation, OSHA fatality inspections, Cal/OSHA
inspections, OSHA establishment search API, OSHA citations and penalties.

# Actor input Schema

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

States and territories to sweep. Covers federal OSHA and every state-plan agency. Leave empty only if you name OSHA offices below instead.

## `offices` (type: `array`):

Narrow to specific OSHA area, district or state-plan offices, for example a single metro. Leave empty to sweep every office in the states above.

## `sinceDays` (type: `integer`):

How far back to look, counted from the inspection opening date. A daily scheduled run needs 3 to 7 days (OSHA publishes an inspection 0 to 2 days after it opens). Look back further for a first sweep or a history pull.

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

Only return these kinds of inspection. Leave empty for all of them.

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

Only return inspections whose NAICS code starts with one of these, for example <code>23</code> for construction, <code>31</code>/<code>32</code>/<code>33</code> for manufacturing, <code>4841</code> for general freight trucking. Leave empty for every industry.

## `keywords` (type: `array`):

Only return inspections matching these words in the establishment name, city, street address or industry title. Handy for watching named companies or a single town.

## `caseStatus` (type: `string`):

Open cases are inspections OSHA has not finished yet, which is where the new-lead value is. Closed cases are the settled ones, with final penalties.

## `maxInspections` (type: `integer`):

Stop after this many inspections across the whole run. This is what caps what you pay.

## `monitorMode` (type: `boolean`):

Built for a scheduled run. The first run returns everything in your window and remembers it; every run after that returns, and charges for, only inspections it has never reported.

## `webhookUrl` (type: `string`):

In monitor mode, post a short digest of the new inspections here. Works with a Slack incoming webhook or any endpoint that accepts <code>{"text": "..."}</code> JSON.

## Actor input object example

```json
{
  "states": [
    "TX"
  ],
  "offices": [],
  "sinceDays": 14,
  "inspectionTypes": [],
  "naicsPrefixes": [],
  "keywords": [],
  "caseStatus": "all",
  "maxInspections": 50,
  "monitorMode": false
}
```

# Actor output Schema

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

One item per OSHA inspection in the default dataset.

# 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": [
        "TX"
    ],
    "offices": [],
    "sinceDays": 14,
    "inspectionTypes": [],
    "naicsPrefixes": [],
    "keywords": [],
    "caseStatus": "all",
    "maxInspections": 50,
    "monitorMode": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("tagadanar/osha-inspection-leads").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": ["TX"],
    "offices": [],
    "sinceDays": 14,
    "inspectionTypes": [],
    "naicsPrefixes": [],
    "keywords": [],
    "caseStatus": "all",
    "maxInspections": 50,
    "monitorMode": False,
}

# Run the Actor and wait for it to finish
run = client.actor("tagadanar/osha-inspection-leads").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": [
    "TX"
  ],
  "offices": [],
  "sinceDays": 14,
  "inspectionTypes": [],
  "naicsPrefixes": [],
  "keywords": [],
  "caseStatus": "all",
  "maxInspections": 50,
  "monitorMode": false
}' |
apify call tagadanar/osha-inspection-leads --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tagadanar/osha-inspection-leads"
        }
    }
}

```

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/LATU9ld9fLaa7h6Br/builds/1jQEzHLklBMiUiuDq/openapi.json
