Getting started
- Create a free account — 50 lookups/month, no credit card required.
- Verify your email — your first API key is generated automatically.
- Create or rotate additional keys any time from your account page.
- Make your first API call:
curl -H "X-Api-Key: YOUR_API_KEY" \
"https://api.fastdol.com/v1/employers?name=walmart&state=CA"Data sources
Every employer profile is an aggregate over the data sources listed below. Source-specific fields use a consistent prefix — osha_*, whd_*, cms_* — so you can identify provenance from the field name alone.
| Source | Agency | What's in the data | Scale |
|---|---|---|---|
| OSHA | Occupational Safety and Health Administration | Inspections, violations, penalties, and fatality investigations — with inspection-type and severity breakdowns. | 2.7M+ inspections |
| WHD | Wage and Hour Division | Department of Labor wage-theft investigations with back wages owed and affected employee counts. | $4.6B in back wages |
| MSHA | Mine Safety and Health Administration | Mine safety violations, inspections, and assessed penalties across all U.S. mining operations. | 2.5M+ violations |
| EPA | Environmental Protection Agency | Clean Air, Clean Water, RCRA, and SDWA compliance via EPA ECHO — inspections, formal actions, and penalties. | $1.2B in EPA penalties |
| NLRB | National Labor Relations Board | Unfair labor practice charges and union-representation case history. | 1.7M+ cases |
| FMCSA | Federal Motor Carrier Safety Administration | DOT-regulated motor carrier registration, operation type, and safety-basic scores. | 107K+ DOT-registered carriers |
| OFLC | Office of Foreign Labor Certification | H-1B, H-2A, and H-2B labor condition applications with prevailing-wage ratios. | 37K+ LCAs |
| ITA | OSHA Injury Tracking Application | OSHA Form 300A self-reported DART and TRIR rates by establishment — employer-submitted. | 162K self-reported establishments |
| BLS | Bureau of Labor Statistics (SOII) | BLS SOII industry-wide TRIR/DART averages for peer-percentile ranking. | 1,285 NAICS covered |
| SAM | System for Award Management | Federal debarment, suspension, and ineligibility exclusions — governs who can win federal contracts. | 572 excluded employers |
| CMS | Centers for Medicare & Medicaid Services | Five-star ratings, deficiencies, civil money penalties, and staffing hours per resident per day. | 14.7K nursing facilities |
| USAspending | USAspending.gov | Federal prime-contract awards with a 25-year lookback — agency, NAICS, obligation, and action date. | $267B in prime contracts |
| CPSC | Consumer Product Safety Commission | Consumer product recalls tied to the responsible manufacturer or distributor. | 22K+ employers w/ recalls |
| NHTSA | National Highway Traffic Safety Administration | Vehicle recalls and defect complaints tied to OEMs and upfitters. | 6.6K manufacturers w/ recalls |
| SEC | Securities and Exchange Commission (XBRL companyfacts) | Per-public-reporter financial scale — revenue, net income, employee count, total assets — from XBRL-tagged 10-K filings. | 9K+ public-company filers |
| SEC | Securities and Exchange Commission (Litigation Releases) | Formal civil enforcement actions filed in federal court — defendant, date, summary, and penalty amount over a 5-year window. | 2.5K+ enforcement actions |
| UVA | UVA Corporate Prosecution Registry | Federal corporate prosecutions, plea agreements, DPAs and NPAs — compiled by UVA Law School. | 33K+ employers w/ prosecutions |
2026-04-28. Recently added fields (federal contracts, CMS, recalls, prosecutions, SAM exclusions) are backfilled historically — every employer profile reflects the full set of sources on every response.Authentication
Include your API key in the X-Api-Key header with every request. View existing keys (masked) and create new ones on the account page. Each account supports up to 5 active keys; rotating a key gives the old value a 48-hour grace period.
Endpoints
Search employers
| Param | Type | Description |
|---|---|---|
| name | string | Employer name (fuzzy match) |
| ein | string | Exact EIN match |
| state | string | 2-letter state code |
| zip | string | 5-digit ZIP code |
| naics | string | 4-digit NAICS prefix |
| parent_only | bool | Returns one result per parent company with aggregate stats. Default false. |
| limit | int | Results per page (1-100, default 20) |
| offset | int | Pagination offset |
Get employer detail
Lookup by EIN
Exact EIN lookup. Dashes are optional (94-3067788 or 943067788). When multiple locations share an EIN, add state to narrow. Returns 404 if no employer is found with that EIN.
Inspection history
Returns inspection records for an employer, ordered by date (newest first). Counts as 1 lookup against your quota.
Violation detail for an inspection
All citations issued on a single OSHA inspection. activity_nr is the numeric OSHA activity number returned by the inspection history endpoint.
Risk history
Parent company rollup
Aggregate risk across all locations of a parent company.
Batch lookup
# Up to 100 items per synchronous request
{
"lookups": [
{"name": "Walmart", "state": "ID", "zip": "83669"},
{"name": "Amazon", "state": "CA"},
{"name": "Target", "zip": "55403"}
]
}Each item can include name, ein, employer_id, state, zip, and city. The response wraps each input in an object with query, match (the employer profile or null), and confidence, plus top-level matched / unmatched counts. For batches over 100 items, use CSV upload (below), which supports up to 500 rows.
CSV upload
Upload a CSV with employer names. Returns a CSV with risk profiles appended. Max 500 rows, 5MB. Content-Type: multipart/form-data, field name file.
Industry benchmarks
Bulk export Enterprise
Pull up to 100,000 employer records matching a structured query — filter, threshold, and sort in a single request. Runs async: submit a job, poll for status, download the file. Requires the export:bulk scope. Contact sales to enable.
Request
{
"format": "csv", // "csv" or "json" (NDJSON)
"max_rows": 50000, // 1 - 100,000
"sort_by": "fatalities",
"sort_dir": "desc", // "asc" or "desc" (default desc)
"filters": {
"states": ["CA", "TX", "FL"],
"naics_codes": ["2361", "2362"],
"min_penalties": 100000,
"has_fatalities": true
}
}
→ 202 { "job_id": "...", "status": "queued", "poll_url": "..." }At least one filter is required. An unfiltered export would scan 2M+ rows and is refused.
Polling
GET /v1/export/{job_id}
→ {
"job_id": "...",
"status": "queued" | "running" | "finished" | "failed",
"row_count": 42187,
"file_size_bytes": 52428800,
"download_url": "...", // present only when status=finished
"expires_at": "2026-04-23T11:00:00Z"
}
GET /v1/export/{job_id}/download
→ streams the CSV or NDJSON file (24h retention)Response format
Each employer result includes flat fields plus nested objects for benchmarks, self-reported data, accident details, and analytics. The full response shape includes ~80 fields; the OpenAPI spec linked above has the complete schema.
{
"results": [
{
"employer_id": "uuid",
"employer_name": "WALMART",
"city": "STAR",
"state": "ID",
"naics_code": "452112",
"naics_description": "Discount Department Stores",
"risk_tier": "MEDIUM",
"risk_score": 12.5,
"trend_signal": "STABLE",
"confidence_tier": "HIGH",
"svep_flag": false,
"parent_name": "Walmart Inc.",
"location_count": 140,
"osha_inspections": 3,
"osha_violations": 7,
"osha_total_penalties": 15000.00,
"whd_cases": 1,
"whd_backwages_total": 5000.00,
"nlrb_cases": 2,
"epa_compliance_status": "Significant Violation",
"is_sam_excluded": false,
"federal_contracts_total_5yr": 0,
"agency_violation_count": 3,
"peer_violation_percentile": 87,
"peer_group_size": 342,
"industry_benchmark": { "avg_trir": 3.2, "avg_dart": 1.8, "source": "BLS SOII 2024" },
"self_reported": { "trir": 3.5, "dart_rate": 2.1, "source": "OSHA ITA Form 300A" },
"accident_summary": { "fatalities": 0, "hospitalizations": 1 },
"analytics": {
"agencies_with_activity": ["OSHA", "WHD", "EPA"],
"total_penalties_all_agencies": 22000,
"peer_penalty_percentile": 72
}
}
],
"total_count": 1,
"limit": 20,
"offset": 0
}Analytics object
The analytics object contains computed insights derived from raw enforcement data. All fields are optional — they appear only when the underlying data exists.
| Field | Type | Description |
|---|---|---|
| years_of_history | number | Years between first and most recent enforcement activity |
| days_since_last_activity | number | Days since the most recent inspection or enforcement case |
| inspection_velocity | number | Average OSHA inspections per year over history span |
| violation_velocity | number | Average violations per year over history span |
| osha_willful_pct | number | Percentage of violations classified as willful |
| osha_serious_pct | number | Percentage of violations classified as serious |
| osha_complaint_pct | number | Percentage of inspections triggered by complaints |
| osha_penalty_per_violation | number | Average OSHA penalty dollars per violation |
| whd_backwages_per_employee | number | Average WHD back wages per affected employee |
| agencies_with_activity | string[] | List of agencies with enforcement records |
| total_penalties_all_agencies | number | Sum across OSHA + WHD + MSHA + EPA |
| trir_vs_industry | number | Self-reported TRIR minus industry average (positive = worse) |
| peer_penalty_percentile | number | Penalty rank vs same NAICS + state peers (0-100) |
| peer_inspection_percentile | number | Inspection frequency rank vs same NAICS + state peers (0-100) |
Risk scoring
Risk scores range from 0–100 and combine:
- OSHA violations — willful (30 pts), repeat (15 pts), serious (3 pts)
- OSHA penalties — up to 15 pts based on dollar amount
- WHD enforcement — back wages (up to 8 pts), cases (up to 4 pts), employees violated (up to 3 pts)
Scores decay over time: full weight for last 3 years, 80% at 4 years, 60% at 5 years, 40% for older activity.
Risk tiers are derived from the score plus a few hard override conditions:
- HIGH: score ≥ 50, or any willful violation within 5 years, or 3+ repeat violations within 5 years.
- ELEVATED: score 20–49, or any workplace fatality investigation on record.
- MEDIUM: score 5–19, or any OSHA violations in the last 3 years, or enforcement actions across 2+ agencies.
- LOW: score 0–4 with no recent enforcement activity.
See methodology for the full per-component weighting and the time-decay table.
Data enrichment
Each employer profile aggregates data from 16 federal sources plus the UVA Corporate Prosecution Registry. Refresh cadences match the cron schedule in scripts/crontab.pipeline:
| Agency | Data | Refresh |
|---|---|---|
| OSHA | Inspections, violations, penalties, fatalities, inspection-type breakdown | Daily |
| WHD | Wage enforcement cases, back wages, employees affected | Weekly |
| MSHA | Mine safety violations and assessed penalties | Weekly |
| EPA ECHO | Environmental compliance, quarters noncompliant, formal actions | Daily |
| FMCSA | DOT number, carrier registration, operation type | Daily |
| NLRB | Unfair labor practice charges, union representation cases | Daily |
| SAM.gov | Federal exclusion / debarment list | Daily |
| OFLC | H-1B / H-2 visa applications, approval rates, wage ratios | Monthly |
| ITA | OSHA Form 300A self-reported DART / TRIR rates | Weekly |
| BLS | SOII industry benchmark TRIR / DART by NAICS | Annual (BLS release) |
| CMS | Nursing-home five-star ratings, deficiencies, civil money penalties | Monthly |
| USAspending | Federal prime contract awards, agencies, NAICS, obligations | Backfill |
| CPSC | Consumer product recalls | Weekly |
| NHTSA | Vehicle and equipment recalls | Weekly |
| UVA | Federal corporate prosecutions, plea agreements, DPAs / NPAs | Monthly |
Rate limits & quotas
Two limits apply on top of each other:
- Monthly quota. Your per-key allowance. Free keys get 50 lookups/month; higher tiers are per-contract. Every authenticated request that reaches a query handler counts as 1 lookup against the quota — including empty-result searches. Batch lookups count as 1 per item submitted. Current usage is visible on your account page and on every response via the
X-RateLimit-*headers. - IP-based request rate. 60 requests/minute per IP on the main search endpoints (
/v1/employers,/v1/employers/parent); 30/minute on inspection detail and per-state / per-NAICS aggregates; 10/minute on the industry metadata endpoints. Protects against scraping; applies before the monthly quota is checked.
When you exceed the rate limit you receive a 429 with {"error": "rate_limited"}. When you exceed the monthly quota you receive a 429 with {"error": "monthly_quota_exceeded"}. Both responses include a Retry-After header.
Errors
{
"detail": {
"error": "error_code",
"message": "Human-readable description"
}
}| Status | Meaning |
|---|---|
| 400 | Bad request — missing required parameter or invalid value (malformed UUID, invalid NAICS) |
| 401 | Missing or invalid API key |
| 403 | API key lacks the required scope for this endpoint |
| 404 | Direct lookup by ID/EIN not found (search returns 200 with empty list) |
| 422 | Parameter out of range (limit > 100, offset < 0) |
| 429 | Rate limit or monthly quota exceeded |
| 503 | Service degraded — pipeline freshness check or database unavailable |
200 with results: [] and a suggestions array — they are a normal response, not an error.Code examples
Python
import requests
API_KEY = "your_api_key"
BASE = "https://api.fastdol.com/v1"
# Search
r = requests.get(f"{BASE}/employers",
headers={"X-Api-Key": API_KEY},
params={"name": "Walmart", "state": "ID"})
print(r.json()["results"][0]["risk_tier"])
# Batch
r = requests.post(f"{BASE}/employers/batch",
headers={"X-Api-Key": API_KEY},
json={"lookups": [
{"name": "Walmart", "zip": "83669"},
{"name": "Amazon", "state": "CA"},
]})
for item in r.json()["results"]:
print(item["query"]["name"], "->",
item["match"]["risk_tier"] if item["match"] else "no match")JavaScript
const API_KEY = "your_api_key";
const BASE = "https://api.fastdol.com/v1";
const res = await fetch(
`${BASE}/employers?name=walmart&zip=83669`,
{ headers: { "X-Api-Key": API_KEY } }
);
const data = await res.json();
console.log(data.results[0].risk_tier);curl
# Search
curl -H "X-Api-Key: YOUR_KEY" \
"https://api.fastdol.com/v1/employers?name=walmart&zip=83669"
# CSV upload
curl -H "X-Api-Key: YOUR_KEY" \
-F "file=@employers.csv" \
"https://api.fastdol.com/v1/employers/upload-csv" \
-o results.csv