# US Supplier Due Diligence 🇺🇸 (OSHA, FDA, WARN, SEC) (`tagadanar/us-supplier-due-diligence`) Actor

One risk report per US vendor from five federal sources: federal awards (USAspending), OSHA inspections and violations, FDA warning letters, WARN layoff notices and SEC EDGAR filings, resolved to one company with the name-match score printed next to every record. No API key, no government signup.

- **URL**: https://apify.com/tagadanar/us-supplier-due-diligence.md
- **Developed by:** [Tagada Data](https://apify.com/tagadanar) (community)
- **Categories:** Lead generation, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $21.00 / 1,000 company reports

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## US Supplier Due Diligence 🇺🇸 (OSHA, FDA, WARN, SEC)

Everything the federal government publishes about your vendor, in one run.

Paste a list of US company names. Get back one consolidated report per company:
what the federal government has awarded them, their OSHA inspection and
violation history, any FDA warning letters, WARN layoff notices, and their SEC
EDGAR filings. Plus a match-confidence score that shows exactly how each record
was tied to the name you gave.

Five official federal sources, one row per vendor, no API key, no signup with
any government site. Platform usage is included in the price.

### Why not just buy a report

A Dun & Bradstreet business information report starts at $139.99 for a single
company and answers the credit question: who owns it, do they pay their bills.
LexisNexis will quote you for a supplier-risk subscription. Neither one is the
federal-record question, which is what a procurement policy actually asks:
does this vendor take government money, has OSHA cited them, has the FDA
written to them, are they laying people off, do they file with the SEC.

All of that is free public data. The work is finding it in five places and
deciding whether the "TYSON FOODS INC." in one of them is the "Tyson Foods,
Inc." on your row. That is the work this actor does.

The Store sells those sources one at a time. Prices read off each actor's own
Store page on 17 August 2026.

| Source | Buy it on its own | Here |
| --- | --- | --- |
| Federal awards | `parseforge/usaspending-scraper`, $0.16 per run plus $12 per 1,000 rows | included |
| OSHA inspections and violations | `scrapebench/osha-violation-risk`, $20 per 1,000 rows | included |
| OSHA plus permits, two sources | `fortuitous_pirate/compliance-data-scraper`, $0.05 per run plus $3 per 1,000 rows | included |
| FDA warning letters | our own feed actor, one source | included |
| State WARN layoff notices | our own feed actor, one source | included |
| SEC EDGAR filings | our own monitor actor, one source | included |
| **One row per vendor, entity-resolved, with a match score** | nobody sells this | **this actor** |

Buying the row dumps separately leaves you with five datasets keyed on five
different spellings of a company name, which is the part that costs the
afternoon. One flat price per company report here, and a company whose name was
too short or too generic to join safely is not charged at all.

### What one row contains

| Section | Fields you get |
|---|---|
| **Verdict** | `verdict`, `matchConfidence` (0-100), `matchConfidenceBand`, `riskFlags` |
| **Identity** | `matchedEntityName`, `uei`, `duns`, `cik`, `registeredCity`, `registeredState`, `matchType`, `nameMatchScore` |
| **Federal awards** | `federalAwardCount`, `federalAwardedUsd`, `firstAwardDate`, `lastAwardDate`, `topAwardingAgencies`, `topNaics`, `lifetimeFederalTransactionsUsd`, `recipientBusinessTypes`, `recipientParentName`, `awards[]`, `usaspendingUrl` |
| **OSHA** | `oshaInspectionCount`, `oshaInspectionsWithViolations`, `oshaTotalViolations`, `oshaLastInspectionDate`, `oshaStates`, `oshaInspections[]` with a link to each inspection |
| **FDA** | `fdaWarningLetterCount`, `fdaOpenWarningLetters`, `fdaLastLetterDate`, `fdaPrograms`, `fdaWarningLetters[]` with the letter, the response and the close-out |
| **WARN layoffs** | `warnNoticeCount`, `warnEmployeesAffected`, `warnLastNoticeDate`, `warnStatesCovered`, `warnNotices[]` |
| **SEC EDGAR** | `isSecReportingCompany`, `secLegalName`, `secTickers`, `secExchanges`, `secSicDescription`, `secStateOfIncorporation`, `secFilingCount`, `secFilingsByForm`, `secRecentMaterialFilings[]`, `edgarUrl` |
| **Provenance** | `sourcesAnswered`, `sourcesUnavailable`, `confidenceBreakdown`, `confidenceReasons`, `minScoreApplied`, `awardsExcludedOtherRecipients`, `billed` |

Nulls where a fact is genuinely absent. Never a guess.

### Risk flags

`osha-violations`, `osha-inspection-recent`, `fda-warning-letter`,
`fda-warning-letter-open`, `warn-layoff`, `warn-layoff-recent`,
`sec-late-filing`, `sec-deregistration`, `ambiguous-match`, `state-mismatch`,
`uei-mismatch`, `cik-mismatch`, `generic-name`, `name-too-short-to-join`,
`source-unavailable`, `no-federal-record`, `no-award-or-inspection-history`.

Filter the dataset on `riskFlags` and you have your escalation list.

### Who this is for

**Procurement and vendor management.** You are onboarding forty suppliers and
your policy says each one gets checked. Doing that by hand means five government
websites per vendor, each with its own search box and its own idea of how a
company name is spelled. This does all forty in one run and hands you a
spreadsheet.

**Supply-chain risk teams.** Run your approved-vendor list monthly. A new open
FDA warning letter, a fresh WARN notice or a jump in OSHA violations shows up as
a flag on the row, so you only read the rows that changed.

**GovCon business development.** Look up a prime, a teaming partner or a
competitor: how much federal money they take, from which agencies, under which
NAICS codes, whether they file with the SEC, and whether they have an
enforcement history you would rather know about before the capture meeting.

**Investors and lenders doing US diligence.** Federal awards concentration,
OSHA and FDA enforcement, layoff notices and SEC filing behaviour, sourced from
the primary records rather than a data broker's copy.

**Journalists and researchers.** Every field links back to the government page
it came from, so a finding is checkable.

### The hard part is the name matching, so here is how it works

A vendor list carries "Tyson Foods, Inc.". USAspending carries "TYSON FOODS
INC.", OSHA carries "Tyson Foods Inc", the WARN feed carries "Tyson Foods", and
EDGAR carries "TYSON FOODS, INC." Meanwhile "Delta" is an airline, a faucet
maker, a dental plan and two hundred local contractors.

So every record has to earn its place in the report:

1. Names are normalized (case, accents, punctuation, `&` to "and"), then split
   into a legal form ("Inc", "LLC", "Corporation") and an identity-carrying
   core. Dotted acronyms stay one token, so "P.L.C." never reads as three
   letters.
2. Each candidate is scored on a ladder with a name: exact, same words in a
   different order, exact once the legal form is set aside, name inside a name,
   fuzzy. The score is in the output, per section and per row.
3. **Short and common names are held to a higher bar than you asked for.** A
   one-word name has to be near-exact; a name whose only word is generic
   ("Delta", "Summit", "Premier") is refused rather than joined. Those rows are
   not billed.
4. **A state you supply corroborates the identity. It never filters the
   findings.** A national vendor's worst inspection is rarely at its registered
   address, so scoping the search to one state would hide exactly what a
   due-diligence report exists to surface.
5. **A supplied UEI or CIK that resolves to a different entity is flagged, not
   quietly ignored.** That mismatch usually means the row in your own system is
   wrong.
6. Every award row returned by USAspending's free-text search is re-checked
   against the matched entity before it can enter a total. `awardsExcludedOtherRecipients`
   tells you how many were thrown out.

When nothing clears the bar, the report says "No federal record found under this
name" and every section is zero. It never invents a match to fill the row.

### Coverage, stated plainly

- **Federal awards**: USAspending.gov, contracts and financial assistance, back
  to the start of your lookback window (the API itself goes to October 2007).
- **OSHA**: the federal IMIS establishment database, all states. Inspection
  dates, types, scope, NAICS and violation counts, with a link to each
  inspection detail page. State-plan states that do not report to IMIS are
  therefore thinner than federal-jurisdiction states.
- **FDA**: the published warning-letter table on fda.gov, which currently holds
  about 3,600 letters going back roughly five years. Older letters are not
  published there.
- **WARN**: there is no national WARN database. Every state publishes its own
  file, in its own format. This actor reads seven feeds that parse
  deterministically: California, New Jersey, Maryland, Indiana, Alaska, South
  Dakota and the District of Columbia. `warnStatesCovered` names the ones that
  answered on your run. A vendor with no notice has no notice **in those
  states**, which is what the field says.
- **SEC**: every exchange-listed issuer, plus non-listed filers found through
  EDGAR's own entity index (Form D issuers, funds, foreign private issuers).

### Input

```json
{
  "companies": [
    { "companyName": "Tyson Foods, Inc.", "state": "AR" },
    { "companyName": "Lockheed Martin Corporation", "state": "MD" },
    { "companyName": "Koven Technologies, Inc.", "state": "MO" }
  ],
  "lookbackYears": 5,
  "minMatchScore": 88,
  "maxCompanies": 200
}
```

Plain names work too:

```json
{
  "companies": ["General Dynamics Corporation", "The Boeing Company"]
}
```

With identifiers, when you have them:

```json
{
  "companies": [
    { "companyName": "Tyson Foods, Inc.", "uei": "DX7AU4JMLPC7", "state": "AR" },
    { "companyName": "Lockheed Martin Corporation", "cik": "936468" },
    { "companyName": "General Dynamics", "ticker": "GD" }
  ],
  "lookbackYears": 10
}
```

From another run's dataset, or from a CSV your procurement system exported:

```json
{
  "companiesDatasetId": "aBcD1234efGh5678",
  "lookbackYears": 5
}
```

```json
{
  "companiesCsvUrl": "https://example.com/approved-vendors.csv"
}
```

Column and key names are picked up automatically: `companyName`, `company`,
`vendor`, `supplier`, `name`, `state`, `city`, `uei`, `duns`, `cik`, `ticker`,
`ein`. An `ein` is echoed back so your CRM join still works, and is never used
for matching, because none of the five federal sources is searchable by EIN.

### Pricing

Pay per company report. A company whose name was too short or too generic to
join on safely is not charged, and neither is a company for which no source
answered. Platform usage (compute) is included, so the price on the card is the
price you pay.

### FAQ

**How do I check a US vendor for OSHA violations?**
Put the company name in `companies`. `oshaTotalViolations`,
`oshaInspectionsWithViolations` and `oshaInspections[]` come back with a link to
each inspection on osha.gov.

**How do I find out how much a company has been paid by the US government?**
`federalAwardedUsd` and `awards[]` come from USAspending.gov, filtered to the
matched recipient. `topAwardingAgencies` shows who is paying.

**Does this need a SAM.gov, USAspending or SEC API key?**
No. All five sources are public and keyless. There is nothing to sign up for.

**What is a UEI and do I need one?**
The Unique Entity ID replaced the DUNS number as the US government's vendor
identifier. You do not need it. If you have it, supply it and the match becomes
exact instead of name-based.

**Can I screen a whole vendor list at once?**
Yes. Paste up to 2,000 companies, or point `companiesDatasetId` at another run,
or `companiesCsvUrl` at a CSV export.

**Why does one of my vendors say "No federal record found"?**
Most US companies have never held a federal contract, never been inspected by
OSHA, never had an FDA letter, never filed a WARN notice and do not file with
the SEC. An empty report is the normal, correct answer for a small private
supplier. Check `sourcesUnavailable` to be sure it is not a source outage.

**Why is the confidence 46 when the name matched exactly?**
Read `confidenceReasons`. The usual causes are an ambiguous register (two
different companies share the name), a state that no federal record supports, or
a source that did not answer on that run.

**Can I use this for continuous monitoring?**
Yes. Schedule it on your approved-vendor list and diff `riskFlags` and the
`last*Date` fields between runs.

**Does it cover state contracts, state OSHA plans or non-US companies?**
No. This is federal US data. A non-US company will correctly come back with no
records.

### Related actors

Need one source in full depth rather than a per-company summary? These are the
scrapers this report is built on:

- [USAspending Federal Awards](https://apify.com/tagadanar/usaspending-federal-awards): every award matching a watchlist, not just one company's
- [OSHA Inspection Leads](https://apify.com/tagadanar/osha-inspection-leads): full inspection detail pages, citations and penalties
- [FDA Warning Letters](https://apify.com/tagadanar/fda-warning-letters): the whole warning-letter feed, monitored
- [US WARN Layoffs](https://apify.com/tagadanar/us-warn-layoffs): every state notice, as a feed
- [SEC EDGAR Monitor](https://apify.com/tagadanar/sec-edgar-monitor): Form 4, 8-K and 13D/G watching by ticker
- [US Grants Monitor](https://apify.com/tagadanar/us-grants-monitor): grants.gov opportunities

Screening companies outside the US? [B2B Lead Verifier](https://apify.com/tagadanar/b2b-lead-verifier)
does the same shape of job against the French, UK and German company registers,
with insolvency and sanctions screening.

***

US supplier due diligence, vendor screening, supplier risk assessment, federal
contractor lookup, OSHA violation check, FDA warning letter search, WARN notice
lookup, SEC EDGAR company search, UEI lookup, USAspending recipient search,
third-party risk management, vendor onboarding checks, GovCon competitor
research, supply chain risk monitoring.

# Actor input Schema

## `companies` (type: `array`):

Your vendor list. Each entry can be a plain company name, or an object with any of <code>companyName</code>, <code>state</code>, <code>city</code>, <code>uei</code>, <code>cik</code>, <code>ticker</code>, <code>duns</code>, <code>ein</code>. A state, a UEI or a CIK makes the match far more reliable when several companies share a name. Output from another scraper can be pasted in as-is.

## `companiesDatasetId` (type: `string`):

Screen the output of another run instead of pasting it. Paste the dataset ID of any run whose rows carry a company name. Company name, state and city are picked up automatically from the usual field names.

## `companiesCsvUrl` (type: `string`):

A public, direct link to a CSV export from your procurement system or CRM. The header row names the columns; comma and semicolon files both work. Columns such as <code>vendor</code>, <code>supplier</code>, <code>company</code>, <code>state</code>, <code>uei</code> are recognised automatically.

## `lookbackYears` (type: `integer`):

How far back to look for awards, inspections, layoff notices and filings. Five years is the usual procurement window; ten shows the long-term pattern.

## `minMatchScore` (type: `integer`):

How close a federal record's name has to be to yours before it goes in the report, from 80 (loose) to 100 (the exact name only). 88 keeps "Tyson Foods, Inc." matching "TYSON FOODS INC" while keeping unrelated companies out. Short or very common names are held to a higher bar automatically.

## `maxCompanies` (type: `integer`):

Stop after this many companies. Use it to cap what a run can cost.

## Actor input object example

```json
{
  "companies": [
    {
      "companyName": "Tyson Foods, Inc.",
      "state": "AR"
    },
    {
      "companyName": "Lockheed Martin Corporation",
      "state": "MD"
    },
    {
      "companyName": "Zzqx Nonexistent Holdings",
      "state": "TX"
    }
  ],
  "lookbackYears": 5,
  "minMatchScore": 88,
  "maxCompanies": 200
}
```

# Actor output Schema

## `reports` (type: `string`):

One row per company: federal awards, OSHA record, FDA warning letters, WARN notices, SEC filings, risk flags and a match-confidence score.

# 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 = {
    "companies": [
        {
            "companyName": "Tyson Foods, Inc.",
            "state": "AR"
        },
        {
            "companyName": "Lockheed Martin Corporation",
            "state": "MD"
        },
        {
            "companyName": "Zzqx Nonexistent Holdings",
            "state": "TX"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("tagadanar/us-supplier-due-diligence").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 = { "companies": [
        {
            "companyName": "Tyson Foods, Inc.",
            "state": "AR",
        },
        {
            "companyName": "Lockheed Martin Corporation",
            "state": "MD",
        },
        {
            "companyName": "Zzqx Nonexistent Holdings",
            "state": "TX",
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("tagadanar/us-supplier-due-diligence").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "companies": [
    {
      "companyName": "Tyson Foods, Inc.",
      "state": "AR"
    },
    {
      "companyName": "Lockheed Martin Corporation",
      "state": "MD"
    },
    {
      "companyName": "Zzqx Nonexistent Holdings",
      "state": "TX"
    }
  ]
}' |
apify call tagadanar/us-supplier-due-diligence --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tagadanar/us-supplier-due-diligence"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/IDi0V7hgNVTyD8y96/builds/4J0KMswjqaek0DF0w/openapi.json
