OSHA Inspections & Citations Scraper - Penalties by Company avatar

OSHA Inspections & Citations Scraper - Penalties by Company

Pricing

from $2.10 / 1,000 inspections

Go to Apify Store
OSHA Inspections & Citations Scraper - Penalties by Company

OSHA Inspections & Citations Scraper - Penalties by Company

OSHA inspections joined with citations from the official DOL API: company, site address, NAICS, inspection type, open and close dates, serious, willful and repeat counts, initial and current penalties and cited standards, newest first. Filter by state, industry and penalty.

Pricing

from $2.10 / 1,000 inspections

Rating

0.0

(0)

Developer

John

John

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

11 hours ago

Last modified

Categories

Share

Fetch recent federal and state-plan OSHA workplace safety inspections joined with their cited violations, penalty amounts (initialPenaltyUsd and currentPenaltyUsd), gravity counts (Serious, Willful, Repeat), and human-readable CFR safety standards via the official U.S. Department of Labor (DOL) Open Data API v4.

What it does

The Occupational Safety and Health Administration (OSHA) conducts tens of thousands of workplace inspections each year across construction, manufacturing, warehousing, and industrial facilities. In the raw DOL database, inspection metadata (OSHA/inspection) and individual violation citations (OSHA/violation) live in separate endpoints keyed by activity_nr, and safety standards are stored as unformatted 8-character strings (e.g. 19260501).

This Actor:

  • Queries https://apiprod.dol.gov/v4/get/OSHA/inspection/json filtered by worksite state (states), NAICS industry prefix (naicsPrefix), and opening date (openDateFrom).
  • Batch-fetches matching violation records from https://apiprod.dol.gov/v4/get/OSHA/violation/json by activity_nr.
  • Aggregates violation counts (violationsCount, seriousCount, willfulCount, repeatCount), sums initialPenaltyUsd and currentPenaltyUsd, and maps the 30 most-cited OSHA standards to readable labels (e.g. 19260501 → "1926.501 Fall Protection", 19100147 → "1910.147 Control of Hazardous Energy (Lockout/Tagout)").

Found a problem or need a field? Open an issue on the Issues tab; we respond quickly.

Who it's for

  • Environmental Health & Safety (EHS) consulting and training firms identifying establishments that recently underwent planned, complaint, or referral inspections.
  • Industrial safety equipment and PPE distributors matching cited CFR standards (fall protection, respiratory protection, scaffolding, machine guarding, lockout/tagout) to safety hardware needs.
  • Commercial insurance underwriters and workers' compensation brokers evaluating workplace safety history by NAICS and geography.
  • Workplace safety and labor researchers analyzing penalty trends and enforcement activity.

Input

  • states (array of strings) — Two-letter US state codes for the inspected worksite. Default: ["AZ", "TX"]. Leave empty ([]) for all states.
  • naicsPrefix (string) — NAICS industry code prefix (e.g. "23" for Construction, "31"–"33" for Manufacturing). Default: "23". Leave empty ("") for all industries.
  • openDateFrom (string, YYYY-MM-DD) — Earliest inspection open_date to include. Defaults to 365 days.
  • minCurrentPenaltyUsd (integer) — Minimum summed currentPenaltyUsd per inspection (0 includes recent inspections even before citations are issued). Default: 0.
  • violationTypes (array of strings) — Optional filter for violation gravity ("Serious", "Willful", "Repeat", "Other-than-serious"). Default: [].
  • onlyWithCitations (boolean) — Default true. Skips inspections with no citation items issued yet (citations usually follow the inspection by weeks or months).
  • Partial results: if the time budget runs out, the DOL API keeps answering 429, the 4,000-inspection safety cap is reached, the source feed looks stale or drifted, or the max charge limit stops the push, the run still returns what it fully checked and the status message starts with PARTIAL and gives the reason. When the reason is on the source side (rate limit, schema drift, stale feed, excluded invalid rows), the message also ends with: If this keeps happening, please open an issue on this actor's Issues tab and we'll fix it fast. A PARTIAL caused only by your own limits (max charge, time budget, safety caps) omits that line — raising the limit is the fix there, not a bug report.
  • maxScanSeconds (integer) — Time budget, default 75. The DOL API is rate-limited; raise this and the run timeout for large pulls.
  • useApifyProxy (boolean) — Default false (opt-in). The DOL API throttles some shared cloud IPs, including Apify's, and can answer HTTP 429 from the first request. If that happens, turn this on. It uses Apify's shared datacenter proxy on your account: every Apify plan includes it (the Free plan has 5 shared IPs), and its data transfer counts toward your platform usage.
  • onlyOpenCases (boolean) — Keep only inspections where closeCaseDate is null. Default: false.
  • dolApiKey (string, secret, optional) — Your own free DOL Open Data API v4 key from dataportal.dol.gov. If left blank, the Actor reads the DOL_API_KEY environment secret configured on the Actor; if neither is set, the Actor fails with a clear message saying so.
  • maxItems (integer) — Maximum inspection rows to return. Default: 100.

Example input JSON

{
"states": ["AZ", "TX"],
"naicsPrefix": "23",
"openDateFrom": "2026-07-25",
"minCurrentPenaltyUsd": 0,
"violationTypes": [],
"onlyOpenCases": false,
"maxItems": 200
}

Canary input (quick health check)

{
"states": ["AZ"],
"naicsPrefix": "23",
"maxItems": 5
}

A healthy canary returns 5 rows and ends Complete: 5 rows. It ends PARTIAL only with a stated source-side reason — for example, if DOL has not posted any inspection for the query in over 60 days, or the API rate-limited the scan. Citation lag alone never makes a run PARTIAL: freshness is measured on the newest inspection DOL has posted for your query, before citation filters are applied (see the FAQ below). A canary should never end in an unexplained failure.

Example run options (default max charge $50)

Set a default maximum charge of $50 ("maxTotalChargeUsd": 50) in your run options:

{
"maxTotalChargeUsd": 50
}

Output

Results are deduplicated by activityNumber and sorted newest first by openDate descending.

FieldTypeDescription
activityNumberstringUnique OSHA inspection activity number (activity_nr).
establishmentNamestring | nullName of the inspected business establishment.
siteStreetstring | nullInspected worksite street address.
siteCitystring | nullWorksite city.
siteStatestring | nullWorksite 2-letter state code.
siteZipstring | nullWorksite postal ZIP code.
naicsCodestring | null6-digit NAICS industry code.
inspectionTypestring | nullDecoded inspection trigger (Planned, Complaint, Referral, Accident, Follow-Up, etc.).
scopestring | nullDecoded inspection scope (Complete, Partial, Records Only, No Inspection).
openDatestring | nullDate the inspection opened (YYYY-MM-DD).
closeCaseDatestring | nullDate the case closed (YYYY-MM-DD) or null if still open.
unionStatusstring | nullWorksite union representation status (Union or Non-Union).
ownerTypestring | nullSector classification (Private, Local Government, State Government, Federal Government).
violationsCountintegerTotal cited violations joined to this inspection.
seriousCountintegerCount of Serious (S) violations.
willfulCountintegerCount of Willful (W) violations.
repeatCountintegerCount of Repeat (R) violations.
initialPenaltyUsdnumberSummed initial proposed penalty in USD.
currentPenaltyUsdnumberSummed current penalty in USD (reflects latest post-settlement/contest adjustments).
citedStandardsarray<string>Human-readable CFR safety standards cited on the inspection.
inspectionUrlstring | nullOSHA IMIS inspection detail URL for interactive browser lookup.

Sample output row (synthetic example)

{
"activityNumber": "1999999",
"establishmentName": "EXAMPLE STRUCTURAL BUILDERS LLC",
"siteStreet": "1200 W INDUSTRIAL PKWY",
"siteCity": "PHOENIX",
"siteState": "AZ",
"siteZip": "85009",
"naicsCode": "236220",
"inspectionType": "Planned",
"scope": "Partial",
"openDate": "2026-10-12",
"closeCaseDate": null,
"unionStatus": "Non-Union",
"ownerType": "Private",
"violationsCount": 2,
"seriousCount": 2,
"willfulCount": 0,
"repeatCount": 0,
"initialPenaltyUsd": 24800.0,
"currentPenaltyUsd": 17360.0,
"citedStandards": [
"1926.501 Fall Protection",
"1926.1053 Ladders"
],
"inspectionUrl": "https://www.osha.gov/ords/imis/establishment.inspection_detail?id=1999999"
}

How pricing works

Pay per result. You only pay for rows returned. Set "maxTotalChargeUsd": 50 in your run options to cap spend automatically.

Data source and terms

  • Official source: U.S. Department of Labor Open Data Portal (dataportal.dol.gov).
  • Important context on penalties and citations:
    • OSHA citations and proposed penalties are often reduced or modified after an informal settlement conference with the OSHA Area Director, or may still be under formal contest before the Occupational Safety and Health Review Commission (OSHRC). currentPenaltyUsd reflects the latest value recorded in the DOL enforcement feed.
    • Because citations can take several weeks after openDate to be issued and posted, very recent inspections may show violationsCount: 0 and currentPenaltyUsd: 0.
  • Affiliation disclaimer: This Actor is an independent tool and is not affiliated with or endorsed by the Occupational Safety and Health Administration (OSHA) or the U.S. Department of Labor (DOL).

Compliance

This Actor outputs business establishment names and physical worksite addresses published by the U.S. Department of Labor (no personal contact emails or phone numbers are included). Buyers are responsible for complying with the Telephone Consumer Protection Act (TCPA), the National Do-Not-Call Registry, the CAN-SPAM Act, and all applicable federal and state privacy laws before any business outreach. Do not use this Actor for consumer or individual targeting.

Troubleshooting

  • "A DOL API key is required" — Neither the DOL_API_KEY environment secret nor the dolApiKey input was set. Add one of them (see FAQ below) and re-run.
  • "DOL API rejected the API key (HTTP 401/403)" — The configured key is invalid or revoked. Register or regenerate a key at dataportal.dol.gov and update the secret/input.
  • Status starts with PARTIAL — The run returned everything it could fully verify and stopped for the stated reason (rate limit, time budget, safety cap, stale or drifted feed, or the max charge limit). Re-run with a narrower window or a higher budget/limit.
  • "returned no matching inspections" — The filters matched nothing in the DOL feed. Widen openDateFrom, states, or naicsPrefix.

Limits and FAQ

  • How do I get a free DOL API key? Register for a free account at dataportal.dol.gov and paste your API key into the dolApiKey input, or configure the DOL_API_KEY environment secret on the Actor. If neither is set, the run fails with instructions; there is no other built-in key.
  • Why do some recent inspections have 0 violations? Under the OSH Act, OSHA has up to 6 months from an inspection opening date to issue citations. Keeping minCurrentPenaltyUsd: 0 returns newly opened inspections immediately; raising minCurrentPenaltyUsd (e.g. 5000) filters for inspections where penalty citations have already posted.
  • How is "stale source" judged? Freshness is measured on the newest inspection DOL has posted for your query — before the onlyWithCitations, penalty, and violation-type filters are applied. Because citations trail inspections by weeks to months, the newest cited inspection is routinely old even when the feed is perfectly current, so it is never used for the freshness check. Only if DOL has posted nothing for the query in over 60 days does the run end PARTIAL with a "source data may be stale" note.

Changelog

  • v0.3 (2026-10-26): Freshness is now measured on the newest inspection DOL has posted for the query (before citation filters), so normal citation lag no longer makes every run PARTIAL-stale; the stale threshold is 60 days. The Issues call-to-action is only appended to source-caused PARTIALs, not to PARTIALs caused by your own limits (max charge, time budget, safety caps). Runs now fail when more than 20% of collected rows fail output validation. The schema-drift sentinel also catches value-level drift (a mapped field present but null/empty across a page, e.g. every estab_name null), with a stricter threshold on identity fields. More robust source parsing: delete_flag is read as deleted only for explicit affirmative values, violation gravity accepts full-word encodings ("Serious", "Willful", "Repeat") as well as the S/W/R codes, non-numeric penalty values are counted and reported instead of silently summed as $0, duplicate citation rows are deduplicated, the citation pagination cap notes itself, and the time budget is enforced during citation fetching too. Non-string inputs now fail with a clear message instead of crashing.
  • v0.2 (2026-10-26): The Actor now reads the DOL_API_KEY environment secret (the per-run dolApiKey input remains as an optional fallback); v0.1.6 as shipped required the input key and ignored the secret. Added per-row output schema validation with counted exclusions, a schema-drift sentinel on both DOL endpoints, a freshness check, the verbatim Issues call-to-action on PARTIAL statuses (including the charge-limit exit, now a proper PARTIAL), and an honest fail (instead of "no matches") when collected inspections must be dropped.
  • v0.1 (2026-10-23): Initial release with DOL Open Data API v4 inspection/violation join and Top-30 CFR standard label mapping.