# MSHA Mining Safety & Health Data (`ryanclinton/msha-mining-safety`) Actor

Comprehensive mining safety intelligence from the **Mine Safety and Health Administration (MSHA)**. Searches 86,000+ mines across the US and joins data from **5 DOL API datasets** — mines, violations, inspections, accidents, and assessments — with automated **risk scoring** based on fatalities, S...

- **URL**: https://apify.com/ryanclinton/msha-mining-safety.md
- **Developed by:** [Ryan Clinton](https://apify.com/ryanclinton) (community)
- **Categories:** Other, AI
- **Stats:** 5 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$30.00 / 1,000 result returneds

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/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

## MSHA Mining Safety & Health Data

Comprehensive mining safety intelligence from the **Mine Safety and Health Administration (MSHA)**. Searches 86,000+ mines across the US and joins data from **5 DOL API datasets** — mines, violations, inspections, accidents, and assessments — with automated **risk scoring** based on fatalities, S\&S violations, withdrawal orders, and penalty history.

### What It Does

This actor queries the DOL Open Data Portal API to build rich mine safety profiles:

1. **Searches mines** by name, operator, controller, state, type (Coal/Metal), status, or commodity
2. **Joins violations** — citations, orders, safeguards with S\&S flags, negligence levels, and penalties
3. **Joins inspections** — regular, spot, complaint, impact inspections with violations found and on-site hours
4. **Joins accidents** — fatalities, injuries, lost workdays with narratives and classifications
5. **Calculates risk scores** — weighted algorithm considering fatalities (40pts), orders (10pts each), S\&S violations (3pts each), high negligence (8pts each), large penalties, and violation-to-employee ratios

### Key Features

- **Multi-dataset joining** — Automatically correlates data across 5 MSHA datasets by mine\_id
- **Risk scoring** — Four-tier risk assessment (Critical/High/Medium/Low) with detailed risk factor breakdown
- **Comprehensive summaries** — Violation, inspection, and accident summaries with breakdowns by type
- **Flexible filtering** — Search by any combination of mine name, operator, state, type, commodity, date range
- **Rate limit handling** — Exponential backoff with staggered parallel requests to respect DOL API limits
- **Dry run mode** — Returns realistic sample data without API calls (default behavior)

### Input Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `apiKey` | string | — | DOL API key ([register free](https://dataportal.dol.gov/registration)) |
| `dryRun` | boolean | true | Return sample data without API calls |
| `mineName` | string | — | Search by mine name (partial match) |
| `operatorName` | string | — | Search by operator name (partial match) |
| `controllerName` | string | — | Search by controller/parent company |
| `mineId` | string | — | Exact MSHA mine ID (7 digits) |
| `state` | string | — | Two-letter state code (WV, WY, PA, etc.) |
| `mineType` | string | — | `C` = Coal, `M` = Metal/Non-Metal |
| `mineStatus` | string | — | Active, Abandoned, NonProducing, etc. |
| `commodity` | string | — | Primary commodity (Bituminous, Gold, Limestone, etc.) |
| `dateFrom` | string | — | Filter related data from date (YYYY-MM-DD) |
| `dateTo` | string | — | Filter related data to date (YYYY-MM-DD) |
| `includeViolations` | boolean | true | Join violation records |
| `includeInspections` | boolean | true | Join inspection records |
| `includeAccidents` | boolean | true | Join accident records |
| `maxResults` | integer | 100 | Max mines to return (1-5000) |
| `maxViolationsPerMine` | integer | 100 | Max violations per mine (1-1000) |
| `maxInspectionsPerMine` | integer | 50 | Max inspections per mine (1-500) |
| `maxAccidentsPerMine` | integer | 50 | Max accidents per mine (1-500) |

### Output Format

Each mine record includes:

```json
{
    "mineId": "4601432",
    "mineName": "EAGLE BUTTE MINE",
    "mineType": "Coal",
    "mineClassification": "Surface",
    "operatorName": "EAGLE SPECIALTY MATERIALS LLC",
    "controllerName": "EAGLE SPECIALTY MATERIALS LLC",
    "state": "WY",
    "county": "CAMPBELL",
    "latitude": 44.21,
    "longitude": -105.38,
    "status": "Active",
    "employeeCount": 320,
    "hoursPerYear": 640000,
    "sicDescription": "Bituminous Coal and Lignite Surface Mining",
    "primaryCommodity": "Bituminous",

    "violations": [
        {
            "violationNumber": "8765432",
            "section": "77.1607(b)",
            "sectionTitle": "Loading and haulage - moving equipment",
            "citationOrderSafeguard": "Citation",
            "significantAndSubstantial": true,
            "negligence": "Moderate",
            "proposedPenalty": 4416
        }
    ],
    "violationSummary": {
        "total": 2,
        "citations": 1,
        "orders": 1,
        "significantAndSubstantial": 2,
        "totalProposedPenalties": 27872,
        "byNegligence": { "Moderate": 1, "High": 1 }
    },

    "inspections": [
        {
            "eventNumber": "E001234",
            "beginDate": "2024-11-10",
            "inspectionTypeDescription": "Regular Safety/Health",
            "violationsFound": 2,
            "onSiteHours": 48
        }
    ],

    "accidents": [
        {
            "accidentDate": "2024-06-12",
            "degreeOfInjuryDescription": "Days Away From Work (DAFW)",
            "classification": "Powered Haulage",
            "daysLost": 45,
            "narrative": "Employee was struck by a loaded haul truck..."
        }
    ],

    "riskScore": 37,
    "riskLevel": "Medium",
    "riskFactors": [
        "1 withdrawal order(s) (+10)",
        "2 S&S violation(s) (+6)",
        "1 high negligence violation(s) (+8)"
    ]
}
```

### Risk Scoring Algorithm

| Factor | Points | Cap |
|--------|--------|-----|
| Fatality | +40 each | None |
| Permanent disability | +20 each | None |
| Withdrawal order | +10 each | 80 |
| S\&S violation | +3 each | 60 |
| High negligence / Reckless disregard | +8 each | 40 |
| Penalties > $100K | +25 | — |
| Penalties > $50K | +15 | — |
| High violation volume (>50) | +15 | — |
| Contested violations > 10 | +10 | — |
| Days lost > 100 | +15 | — |
| Violation/employee ratio > 2 | +20 | — |
| Violation/employee ratio > 1 | +10 | — |

**Risk levels:** Critical (≥100) · High (≥60) · Medium (≥30) · Low (<30)

### Example Searches

**Find all active coal mines in West Virginia:**

```json
{
    "apiKey": "YOUR_KEY",
    "dryRun": false,
    "state": "WV",
    "mineType": "C",
    "mineStatus": "Active",
    "maxResults": 200
}
```

**Look up a specific mine with full history:**

```json
{
    "apiKey": "YOUR_KEY",
    "dryRun": false,
    "mineId": "4601432",
    "maxViolationsPerMine": 500,
    "maxInspectionsPerMine": 200,
    "maxAccidentsPerMine": 200
}
```

**Search gold mines with recent violations only:**

```json
{
    "apiKey": "YOUR_KEY",
    "dryRun": false,
    "commodity": "Gold",
    "mineType": "M",
    "dateFrom": "2024-01-01",
    "maxResults": 50
}
```

**Find mines by operator:**

```json
{
    "apiKey": "YOUR_KEY",
    "dryRun": false,
    "operatorName": "PEABODY",
    "includeAccidents": true,
    "maxResults": 100
}
```

### Data Sources

This actor queries 5 datasets from the [DOL Open Data Portal](https://dataportal.dol.gov/):

| Dataset | Records | Updated | Description |
|---------|---------|---------|-------------|
| Mines | 86,000+ | Weekly | All coal and metal/non-metal mines since 1970 |
| Violations | Millions | Weekly | Citations, orders, safeguards from inspections |
| Inspections | Millions | Weekly | Every MSHA inspection since 1983 |
| Accidents | 300,000+ | Weekly | Injuries, illnesses, fatalities since 1983 |
| Assessed Violations | Millions | Weekly | Penalty assessments for violations since 1995 |

Additional supporting datasets available: contractor/operator employment, controller history, commodity lookup.

### API Key

Register for a **free** DOL API key at [dataportal.dol.gov/registration](https://dataportal.dol.gov/registration). The key provides access to all DOL Open Data Portal datasets (MSHA, OSHA, WHD, etc.).

### Use Cases

- **Mining company due diligence** — Assess safety records before acquisition or investment
- **Insurance underwriting** — Evaluate mining operations for workers' comp and liability policies
- **Regulatory compliance** — Monitor violation trends and inspection frequency
- **Investigative journalism** — Research mine safety records and fatality patterns
- **Legal research** — Find citation and penalty history for mining litigation
- **ESG analysis** — Environmental, Social, Governance scoring for mining companies
- **Government oversight** — Track enforcement patterns across mining districts

### Technical Notes

- The DOL API has aggressive rate limits. The actor uses 500ms delays between requests and exponential backoff on 429 responses.
- Violation, inspection, and accident fetches are staggered (1s apart) to avoid concurrent rate limiting.
- Mines are sorted by employee count descending (largest mines first) when no specific search criteria is provided.
- Results are sorted by risk score descending after processing.
- The `mine_id` field is the primary join key across all datasets.

# Actor input Schema

## `apiKey` (type: `string`):

Your DOL Open Data Portal API key. Register free at https://dataportal.dol.gov/registration

## `dryRun` (type: `boolean`):

Return sample data without calling the API. Default: true (unless apiKey provided)

## `mineName` (type: `string`):

Search by mine name (partial match). e.g., 'EAGLE BUTTE' or 'NORTH ANTELOPE'

## `operatorName` (type: `string`):

Search by current mine operator (partial match). e.g., 'PEABODY' or 'ARCH'

## `controllerName` (type: `string`):

Search by current mine controller/parent company (partial match)

## `mineId` (type: `string`):

Exact MSHA mine identification number (7 digits). e.g., '4601432'

## `state` (type: `string`):

Two-letter state abbreviation. e.g., 'WV', 'WY', 'PA', 'KY'

## `mineType` (type: `string`):

Coal or Metal/Non-Metal

## `mineStatus` (type: `string`):

Filter by mine operational status

## `commodity` (type: `string`):

Search by primary commodity/SIC description. e.g., 'Bituminous', 'Gold', 'Limestone', 'Sand and Gravel'

## `dateFrom` (type: `string`):

Filter violations/inspections/accidents from this date (YYYY-MM-DD)

## `dateTo` (type: `string`):

Filter violations/inspections/accidents up to this date (YYYY-MM-DD)

## `includeViolations` (type: `boolean`):

Join violation records for each mine

## `includeInspections` (type: `boolean`):

Join inspection records for each mine

## `includeAccidents` (type: `boolean`):

Join accident/injury records for each mine

## `maxResults` (type: `integer`):

Maximum number of mines to return (1-5000)

## `maxViolationsPerMine` (type: `integer`):

Maximum violations to fetch per mine (1-1000)

## `maxInspectionsPerMine` (type: `integer`):

Maximum inspections to fetch per mine (1-500)

## `maxAccidentsPerMine` (type: `integer`):

Maximum accident records to fetch per mine (1-500)

## Actor input object example

```json
{
  "dryRun": true,
  "includeViolations": true,
  "includeInspections": true,
  "includeAccidents": true,
  "maxResults": 100,
  "maxViolationsPerMine": 100,
  "maxInspectionsPerMine": 50,
  "maxAccidentsPerMine": 50
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("ryanclinton/msha-mining-safety").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("ryanclinton/msha-mining-safety").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call ryanclinton/msha-mining-safety --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=ryanclinton/msha-mining-safety",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/83Dvn8xZubP7nfDnI/builds/TA0RmNiPvwqDAPUq4/openapi.json
