*** September 2026 Major Release ***Read and watch
Document type

Extracting data from OSHA logs

Employers keep OSHA's injury log on the official forms or on equivalent layouts from safety software, and summarize it on Form 300A each year. Insurers and contractor prequalification teams collect several years of summaries from every contractor they assess, as signed PDFs or scans.

Underwriters and prequalification reviewers need each case count, the days lost, average employees and total hours worked. Prequalification software turns those into DART and total recordable incidence rates, and scores each contractor against its industry average.

Page 1 of a sample OSHA Log, with extracted values outlined
3,969Markdown characters
74parse blocks
29fields extracted
The problem

What makes OSHA logs hard

Columns named by letter

Each count sits above a lettered column reference such as (H) or (K), under a multi-line caption that reads differently from the field name.

Two totals, one set of cases

Outcome counts in columns G to J and injury type counts in column M partition the same cases, so their totals must agree.

Example text beside blank lines

The industry description, SIC and NAICS lines print a sample entry beside each answer line, and many employers leave those lines blank.

How it works

Parse, extract, verify

1

Parse

Parse turns the document into reading-order Markdown and a hierarchy of blocks (text, tables, figures), and grounds each block to its exact location on the page.

2

Extract

You define the fields in a JSON schema, and Extract returns their values in a consistent, structured format, each linked back to where it appears in the Markdown.

3

Verify

Each value links back to where it appears, down to the character range in the Markdown, and the page and bounding box in the source document, so every result can be verified.

Worked example

One OSHA log, end to end

About this document: The completed Form 300A summary that the University of Wisconsin-Madison published to meet OSHA's posting requirement. One landscape page, generated from the university's safety records system: case counts, day totals and injury types on the left, establishment and employment details on the right. Page 1 is featured. The form holds aggregate counts only, so no redaction was needed.

Processing objective: The objective is to collect the inputs to a DART incidence rate. Cases with days away and cases with job transfer or restriction, multiplied by 200,000 and divided by hours worked, give the rate. Total days away shows how severe those cases were, and each value grounds to its own box.

Demonstration fields: Cases with days away from work (H), Cases with job transfer or restriction (I), Total days away from work (K), Annual average employees, Total hours worked

The document

1 page
  • Page 1 of the sample OSHA LogPage 1shown below

Where each value came from

Page 1 of the sample OSHA Log, with every featured field outlined
Cases with days away from work (H)number_of_cases.days_away_from_work
60
The region of the sample OSHA Log containing Cases with days away from work (H), with the extracted value outlined
extraction_metadata["number_of_cases.days_away_from_work"]
{
  "value": 60,
  "page": 1,
  "range": {
    "end": 1177,
    "start": 1175
  },
  "box": {
    "xmin": 0.10081,
    "ymin": 0.45211,
    "xmax": 0.19606,
    "ymax": 0.48816
  }
}
Cases with job transfer or restriction (I)number_of_cases.job_transfer_or_restriction
25
The region of the sample OSHA Log containing Cases with job transfer or restriction (I), with the extracted value outlined
extraction_metadata["number_of_cases.job_transfer_or_restriction"]
{
  "value": 25,
  "page": 1,
  "range": {
    "end": 1188,
    "start": 1186
  },
  "box": {
    "xmin": 0.19592,
    "ymin": 0.4521,
    "xmax": 0.31125,
    "ymax": 0.48817
  }
}
Total days away from work (K)number_of_days.days_away_from_work
938
The region of the sample OSHA Log containing Total days away from work (K), with the extracted value outlined
extraction_metadata["number_of_days.days_away_from_work"]
{
  "value": 938,
  "page": 1,
  "range": {
    "end": 1454,
    "start": 1451
  },
  "box": {
    "xmin": 0.02144,
    "ymin": 0.60635,
    "xmax": 0.13055,
    "ymax": 0.65413
  }
}
Annual average employeesemployment.annual_average_employees
34,321
The region of the sample OSHA Log containing Annual average employees, with the extracted value outlined
extraction_metadata["employment.annual_average_employees"]
{
  "value": 34321,
  "page": 1,
  "range": {
    "end": 3374,
    "start": 3368
  },
  "box": {
    "xmin": 0.79044,
    "ymin": 0.59046,
    "xmax": 0.94552,
    "ymax": 0.63317
  }
}
Total hours workedemployment.total_hours_worked
46,120,878
The region of the sample OSHA Log containing Total hours worked, with the extracted value outlined
extraction_metadata["employment.total_hours_worked"]
{
  "value": 46120878,
  "page": 1,
  "range": {
    "end": 3457,
    "start": 3447
  },
  "box": {
    "xmin": 0.79042,
    "ymin": 0.63287,
    "xmax": 0.9454,
    "ymax": 0.66247
  }
}

How to try it yourself

Everything on this page is reproducible. The sample, its schema, and the Parse and Extract API outputs are published. You can repeat the same two calls from whichever surface you already build on.

  • Claude Skilldescribe the job; the agent writes it
  • CLIno code at all
  • MCPexpose ADE docs as an agent tool
  • REST APIany language
  • Pythonlandingai-ade
  • TypeScriptlandingai-ade
Why LandingAI?

Documents into data

Accurate

The best accuracy on the difficult documents other tools get wrong, such as messy scans, complicated tables, checkboxes and handwriting.

Auditable

Every answer cites its sources. Values come back with an audit trail (page, bounding box, character range) so a human can review them.

Agentic

Applies multi-step reasoning, and plans before it acts. Handles documents it has never seen before and adapts to variations.

API-first

Composable APIs that drop into any tech stack and can be called from anywhere. Easy to build on and embed in your pipelines and products.

Affordable

Cost-competitive rates with complete price transparency. Spend controls before you run, and every job reports its exact cost.

Enterprise-grade

Built for production and scale from day one. Fully observable and monitored, running securely in our cloud or yours.

Built for high-volume, high-throughput production

  • Zero data retention
  • Priority rate limits
  • Enhanced support
  • VPC and on-prem deployment

Available on Team and Enterprise plans. VPC and on-prem deployment require an Enterprise plan.

Compare plans
Capabilities

OSHA Log processing highlights

Deaths and case outcomes
Days away and restricted
Six injury and illness types
Annual average employees
Total hours worked
Comma-grouped numbers as integers
Lettered column references
Establishment name and address
SIC and NAICS codes
Certification title and date
No per-software templates
Bounding box for every value
FAQs

Questions, answered

Yes. Define hours worked and average employees as integers in your schema. A figure printed with thousands separators comes back as a plain integer, ready to drop into an incidence rate calculation.

Yes. The outcome counts and the injury type counts come back as separate numbers, so a pipeline can sum each set and compare them. A mismatch points straight to the column to review.

No. A schema names the fields you want and describes them in plain language. Extraction reads the parsed form for meaning, so one schema covers the official form and the equivalent layouts that safety software prints.

Every extracted value carries the character range it was quoted from in the parsed Markdown. The Ground API maps that range to a page and a bounding box, so a reviewer sees each count above its column letter.

Start extracting OSHA log data

Reliable, structured outputs with full traceability in minutes