Skip to main content
OSHA publishes its data one workplace at a time, and most of them have no FEIN. Effective groups those rows into employers, so you can read one employer’s safety history in a few calls. Use it to check a risk before you quote, and again at renewal. Everything here is read-only. Agents can make the same calls over MCP; see Use with Claude.

Before you start

Follow connection setup first. Your organization also needs the OSHA dataset turned on. Until it is, every request returns 403 dataset_not_enabled with "dataset": "osha". Ask your Effective contact, or email [email protected], to have it turned on.

How employers and sites work

OSHA’s datasets don’t share a common key, so Effective links them in two steps:
  • A site is one workplace. OSHA rows join a site when they share a street address, a ZIP code and the first word of the name.
  • An employer is a group of sites. Sites join by FEIN when OSHA has one. Otherwise they join by a FEIN found under the same name in the same state, or by the same name in the same state.
Employer IDs look like emp_8356d81fe525d4a7971c, and site IDs look like site_3f9a1c27b4e8d05a6c12. Save these IDs. A FEIN is a good way to find an employer, but it isn’t the ID. Effective rebuilds these groups after each weekly OSHA load, and dataVersion changes when it does. IDs stay the same as long as the name, address and FEIN behind them don’t change. If a saved ID ever returns 404, match the employer again.

The journey

The examples follow Sunshine Roofing, a fictional Florida roofer with three sites.

Find the employer

Send a FEIN, a name, or both. Dashes in the FEIN are fine. Add address, city, state, zip or naics (a 2–6 digit prefix) to help rank the candidates.
Response
  • confidence runs from 0 to 1. Use it to rank candidates; it isn’t a probability.
  • matchedOn lists what agreed: any of fein, name, address, zip, city, state and naics.
  • If the FEIN isn’t on file, matching still tries the name and address.
  • You get up to 5 candidates, or up to 20 with limit. Candidates under 0.3 are left out.
  • An empty candidates list means nothing on file matched. It isn’t a clean record.
Copy employer.id. To read the same summary later, call GET /insurance/employers/{employerId}.

Read the OSHA profile

The profile sums up an employer’s recent years in one response. years sets how many, from 1 to 10 (default 5):
Response

Yearly injury rates

years runs newest first and ends at the latest year of Form 300A summaries Effective has loaded. Form 300A is the yearly injury summary that many employers file with OSHA.
  • "coverage": "filed" means at least one site filed for that year. sitesFiled says how many.
  • "coverage": "notOnFile" means OSHA has no summary on file for that year, so the figures are null. Many small employers never have to file. It isn’t a clean record.
  • trcRate is recordable cases × 200,000 ÷ hours worked. For 2023 that’s 12 × 200,000 ÷ 174,720 = 13.74.
  • dartRate is the same rate for cases with days away from work or restricted work.
These are OSHA’s standard rates per 100 full-time workers, so you can compare employers of any size.

Inspections, citations and penalties

The other figures cover window, from 1 January of the first year to today.
  • inspections.byType counts inspections by OSHA’s reason, such as planned, complaint or fatalityOrCatastrophe.
  • citations counts serious, willful, repeat and other citations.
  • penalties are in US dollars. initial is what OSHA first proposed, and current reflects settlements.
  • fatalities.byReportingSource keeps each OSHA source separate. The same death can appear in an accident investigation and in a yearly summary, so don’t add them together.
Every path is an API path, relative to /api/v2, that lists the OSHA rows behind that number. Use it to show your work. Add siteId to read the profile for one workplace.

See what happened, and when

Events put an employer’s OSHA activity on one timeline, newest first. Filter with types (comma-separated), since and until (inclusive event dates), and siteId:
Response
  • type is annual_summary, severe_injury, inspection, citation or accident.
  • severity is fatal, severe, serious or other. Willful and repeat citations count as serious.
  • path reads the OSHA row behind the event. Read OSHA’s own rows explains those rows.
  • An accident that reached more than one of an employer’s sites is still one event. Filter by any of those sites and it’s there, with that siteId.
Lists return 25 items by default, and up to 100 with limit. While nextCursor isn’t null, send it as cursor with the same filters. Pagination and recovery has the details.

Look at each workplace

Response (first of three sites)
A site can carry more than one OSHA establishment ID, because OSHA sometimes issues a new one for the same workplace. Read one site with GET /insurance/employers/{employerId}/sites/{siteId}.

Compare with its industry

Industry rates use every Form 300A filed in an industry, so you can see how an employer compares with its peers:
For 2023, Florida employers in NAICS 2381, which includes roofing, had a trcRate of 4.07. Sunshine Roofing’s is 13.74. See Compare with industry rates for the full response.

What OSHA data covers

  • Form 300A summaries come only from workplaces OSHA requires to file online: generally those with 20 or more employees in designated industries, or with 250 or more.
  • Case detail (Forms 300 and 301) starts with 2023 filings.
  • Inspections, severe injury reports and accident investigations cover employers of any size. They carry no EIN, so Effective places them by name and address.
  • No OSHA data means nothing is on file. It isn’t a clean record.

Handle errors

See Errors for the rest.