# US Product Recalls API: CPSC, FDA, NHTSA and USDA in One Schema (`landoz/us-product-recalls`) Actor

Product recall API that returns FDA recall, CPSC recall, NHTSA recall and USDA recall records from the four official US sources in one clean JSON schema, filterable by date, keyword, UPC, firm and class.

- **URL**: https://apify.com/landoz/us-product-recalls.md
- **Developed by:** [Landon Brewington](https://apify.com/landoz) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$5.00 / 1,000 recall records

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## US Product Recalls API: CPSC, FDA, NHTSA and USDA in One Schema

One call, four official US recall authorities, one clean JSON schema. This Actor is a product recall API that pulls CPSC recalls (consumer products), FDA enforcement reports (food, drug and medical device recalls from openFDA), NHTSA vehicle recalls and USDA FSIS meat, poultry and egg recalls, normalizes every record into the same fields, and lets you filter by date, keyword, UPC, firm and FDA class. Built for recall monitoring by people and by AI agents.

### What it does

- Queries the official government feeds directly: saferproducts.gov (CPSC), api.fda.gov (openFDA enforcement), api.nhtsa.gov (NHTSA) and fsis.usda.gov (USDA FSIS). No scraping of HTML, no login, no third-party data.
- Returns one record per recall with the same 20 fields no matter which agency published it: `id`, `source`, `recallNumber`, `title`, `productDescription`, `firm`, `hazard`, `classification`, `remedy`, `status`, `recallDate`, `reportDate`, `distribution`, `statesAffected`, `upcs`, `units`, `injuries`, `imageUrls`, `url`, plus `raw` with the untouched agency record.
- Date window (`since`, `until` or `sinceDays`), keyword search, UPC lookup, firm or brand filter, FDA Class I / II / III filter, and NHTSA lookup by vehicle make, model and year.
- Newest first, deduplicated, capped at `maxItems`. A run with no input returns the last 7 days from every source, at most 100 records.
- A failing or blocked source never fails the run: it is reported in the run summary (`SUMMARY` record in the key-value store) and the other sources still return data.

### Who it is for

- E-commerce and marketplace compliance teams that must pull recalled listings fast.
- Retail and supply-chain QA that check incoming goods against recall lists by UPC or supplier.
- Product liability, insurance and consumer-safety analysts who track recalls by hazard or class.
- Food safety and healthcare teams monitoring FDA and USDA Class I recalls.
- AI agents that need structured recall data as a tool call (see the MCP section).

### Quick start

1. Open the Actor in Apify Console and press Start. The default input returns the last 7 days from all sources.
2. For a daily monitor, schedule the Actor with `{"sinceDays": 1}`.
3. To check one product, pass `{"upc": "094922980045"}` or `{"query": "infant formula", "sinceDays": 365}`.
4. For a vehicle, pass `{"sources": ["nhtsa"], "vehicleMake": "Ford", "vehicleModel": "F-150", "vehicleYear": "2024"}`.
5. Read results from the default dataset (JSON, CSV or Excel) or the API: `https://api.apify.com/v2/datasets/<datasetId>/items`.

### Input example

```json
{
    "sources": ["cpsc", "fda_food", "fda_drug", "fda_device", "nhtsa", "usda_fsis"],
    "sinceDays": 30,
    "query": "listeria",
    "fdaClassification": "I",
    "maxItems": 200
}
```

All fields are optional.

| Field | Type | Default | Meaning |
|---|---|---|---|
| `sources` | array of strings | all six | Any of `cpsc`, `fda_food`, `fda_drug`, `fda_device`, `nhtsa`, `usda_fsis` |
| `sinceDays` | integer 1 to 365 | 7 | Look-back window when `since` is empty |
| `since` | ISO date | empty | Inclusive start date, overrides `sinceDays` |
| `until` | ISO date | today | Inclusive end date |
| `query` | string | empty | Case-insensitive keyword over title, product, firm and hazard |
| `upc` | string | empty | UPC / GTIN digits that must appear in the record |
| `firm` | string | empty | Company name fragment |
| `fdaClassification` | `any`, `I`, `II`, `III` | `any` | Applies to the three FDA sources |
| `vehicleMake`, `vehicleModel`, `vehicleYear` | strings | empty | All three are required for NHTSA results |
| `maxItems` | integer 1 to 5000 | 100 | Cap on records across all sources |
| `useProxyForUsda` | boolean | false | Retry USDA through Apify residential proxy if the feed refuses the request |

### Output example

A real record from a run (the `raw` object is shortened here):

```json
{
    "id": "usda_fsis:026-2026",
    "source": "usda_fsis",
    "recallNumber": "026-2026",
    "title": "Kayem Foods Inc. Recalls Meat and Poultry Products Due to Possible Temperature Abuse",
    "productDescription": "Full product list available in PDF format - Various RTE meat and poultry products bearing EST. M/P 7839, EST. P 20935A and EST. M 9520 inside the USDA mark of inspection.",
    "firm": "Kayem Foods Inc.",
    "hazard": "Processing Defect",
    "classification": "I",
    "remedy": "Consumers should not consume the product and should throw it away or return it to the place of purchase.",
    "status": "Active",
    "recallDate": "2026-10-17",
    "reportDate": "2026-10-17",
    "distribution": "Nationwide",
    "statesAffected": ["Nationwide"],
    "upcs": [],
    "units": 1584361,
    "injuries": "There have been no confirmed reports of illness due to consumption of these products.",
    "imageUrls": [],
    "url": "https://www.fsis.usda.gov/recalls-alerts/kayem-foods-inc--recalls-meat-and-poultry-products-due-possible-temperature-abuse",
    "raw": {
        "field_recall_number": "026-2026",
        "field_recall_type": "Active Recall",
        "field_risk_level": "High - Class I",
        "field_states": ["Nationwide"],
        "field_establishment": ["Kayem Foods Inc."],
        "field_recall_reason": ["Processing Defect"],
        "field_last_modified_date": "2026-10-17"
    }
}
```

Field notes:

- `id` is `<source>:<recallNumber>` and is stable across runs, so you can deduplicate against your own store.
- `classification` is `"I"`, `"II"` or `"III"` for FDA and USDA records and `null` for CPSC and NHTSA, which do not classify.
- `recallDate` is the agency's announcement or initiation date; `reportDate` is when the agency published or last updated the record. FDA records are selected by `reportDate`, the others by `recallDate`.
- `statesAffected` is parsed from free text. `["Nationwide"]` means the agency said nationwide. An empty array means the agency did not say.
- `upcs` holds codes the agency printed in the notice. Many recalls list none; search `productDescription` and `raw` for lot codes.
- `raw` is the full agency record, so nothing is lost by normalization.

### Pricing in plain words

This Actor uses pay-per-event pricing: $0.005 per recall record written to the dataset (the `result-item` event), plus Apify's standard tiny Actor start fee. There is no subscription. A default run (up to 100 records) costs at most 50 cents. Ten records cost 5 cents. You set the maximum you are willing to spend on each run; when the limit is reached the Actor stops writing records and still finishes successfully. Platform compute is included in the price.

### Limits and freshness per source

| Source | Coverage | Freshness | Limits |
|---|---|---|---|
| `cpsc` | All CPSC consumer product recalls, with product photos, retailers, units, hazards and remedies | Same day as the CPSC press release | Date filter is on the recall date. CPSC lists UPCs only for some recalls. |
| `fda_food`, `fda_drug`, `fda_device` | FDA enforcement reports (recalls classified by FDA) | openFDA updates weekly, usually on Wednesdays; `reportDate` is the weekly enforcement report date, so a recall can appear 1 to 6 weeks after the firm started it | Without a key openFDA allows 1,000 requests per day per IP; one run uses 1 request per 1,000 records per source. Set the `OPENFDA_API_KEY` environment variable on the Actor for 120,000 per day. |
| `nhtsa` | NHTSA vehicle safety recalls for one make, model and model year | Live NHTSA API | The public API has no "recalls since date" search, so this source returns results only when `vehicleMake`, `vehicleModel` and `vehicleYear` are all set, and the date window does not apply to it. |
| `usda_fsis` | USDA FSIS meat, poultry and egg product recalls and public health alerts since 2014 | Live feed; the full feed (about 1.7 MB) is downloaded once per run in under a second and cached in the run's key-value store | The feed sits behind a bot filter that sometimes refuses data-center requests. If that happens the run reports a warning for this source; turn on `useProxyForUsda` to retry through Apify residential proxy (billed to your account, about 2 MB per fetch). |

Other limits: records are capped at `maxItems` (max 5,000) after sorting newest first, so with a wide window and a low cap the newest source wins. Each run is independent; for a change feed, run daily with `sinceDays: 1` or `2` and deduplicate on `id`.

### Use it from an AI agent (Apify MCP server)

Connect your agent to `https://mcp.apify.com` (see the Apify MCP docs for Claude, Cursor, VS Code and others). Then:

1. Search for the tool: `search-actors` with the query "product recalls".
2. Read the schema: `fetch-actor-details` for this Actor returns the input fields above and the dataset schema.
3. Call it: `call-actor` with input `{"sinceDays": 3}` for a three-day recall digest, or `{"upc": "094922980045", "sinceDays": 365}` to check one product, or `{"sources": ["nhtsa"], "vehicleMake": "Toyota", "vehicleModel": "Camry", "vehicleYear": "2023"}` for a vehicle.
4. Read results with `get-dataset-items`. Every record has the same fields, so one parser handles all four agencies.

The Actor runs with limited permissions and charges only pay-per-event events, so it works with Apify's agentic payments.

### Data sources and attribution

- CPSC: U.S. Consumer Product Safety Commission Recall API, https://www.saferproducts.gov and https://www.cpsc.gov/Recalls. Public domain.
- FDA: openFDA enforcement endpoints for food, drug and device, https://open.fda.gov. openFDA data is provided as is; see https://open.fda.gov/terms/ and https://open.fda.gov/license/. Do not rely on it alone for medical decisions.
- NHTSA: National Highway Traffic Safety Administration Recalls API, https://www.nhtsa.gov/recalls. Public domain.
- USDA FSIS: Food Safety and Inspection Service Recall API, https://www.fsis.usda.gov/science-data/developer-resources/recall-api. Public domain.

This Actor is not affiliated with any of these agencies. Always confirm details on the official notice linked in `url` before acting on a recall.

### FAQ

**Why does a default run return only a handful of records?** The default window is the last 7 days. CPSC and USDA publish continuously, but openFDA publishes enforcement reports weekly, so a 7-day window can contain zero FDA rows. Use `sinceDays: 30` for a fuller picture.

**Can I look up one product?** Yes. Pass `upc` for a barcode match or `query` for a keyword match against title, product description, firm and hazard. Combine with `sinceDays: 365` to search a year.

**Why is NHTSA empty unless I give a vehicle?** NHTSA's public API has no date search, so vehicle recalls are returned only when `vehicleMake`, `vehicleModel` and `vehicleYear` are all set.

**Is the data official?** Every record comes straight from the agency's own API (saferproducts.gov, api.fda.gov, api.nhtsa.gov, fsis.usda.gov) and the untouched source record is kept in `raw`.

**What does it cost?** $0.005 per recall record plus Apify's tiny start fee. A default run never costs more than 50 cents. Failed sources are reported, not charged.

**How do I monitor recalls daily?** Schedule the Actor in Apify Console with `{"sinceDays": 1}` and connect a webhook or the Apify integration for Slack, email or Google Sheets.

### Support

Open an issue on the Actor's Issues tab in Apify Console. Include the run id and the input you used.

# Changelog

This Actor's version history is a separate document: https://apify.com/landoz/us-product-recalls/changelog.md

# Actor input Schema

## `sources` (type: `array`):

Which official recall feeds to query. Values: cpsc (consumer products, saferproducts.gov), fda_food, fda_drug, fda_device (openFDA enforcement reports), nhtsa (vehicles, needs vehicleMake + vehicleModel + vehicleYear), usda_fsis (meat, poultry and egg products). Leave empty for all six.

## `sinceDays` (type: `integer`):

How many days back from "until" (default today) to search when "since" is empty. 1 to 365. Default 7. Use 1 to 3 for a daily monitor, 30 for a monthly review.

## `since` (type: `string`):

Optional inclusive start date, format 2026-10-01. Overrides sinceDays. Compared against the recall date (CPSC, USDA) or the FDA report date.

## `until` (type: `string`):

Optional inclusive end date, format 2026-10-31. Defaults to today (UTC).

## `query` (type: `string`):

Optional keyword matched case-insensitively against the title, product description, firm and hazard, for example "listeria", "lithium battery" or "infant". Leave empty for everything.

## `upc` (type: `string`):

Optional UPC / GTIN digits. Returns only records that mention this code (CPSC product UPCs, FDA product descriptions and code info, USDA product lists).

## `firm` (type: `string`):

Optional company name fragment matched case-insensitively against the recalling firm, manufacturer or establishment, for example "Abbott" or "Kayem".

## `fdaClassification` (type: `string`):

Only for the fda\_\* sources. I = dangerous or defective products that could cause serious health problems or death. II = may cause temporary or reversible health problems. III = unlikely to cause harm. "any" returns all classes.

## `vehicleMake` (type: `string`):

Vehicle make for NHTSA, for example "Ford" or "Toyota". NHTSA vehicle recalls are returned only when vehicleMake, vehicleModel and vehicleYear are all set; the date window does not apply to them.

## `vehicleModel` (type: `string`):

Vehicle model for NHTSA, for example "F-150" or "Camry".

## `vehicleYear` (type: `string`):

Four-digit model year for NHTSA, for example "2024".

## `maxItems` (type: `integer`):

Upper bound on records written to the dataset across all sources, newest first. Default 100, maximum 5000. Each record costs one result-item event.

## `useProxyForUsda` (type: `boolean`):

The USDA FSIS feed sits behind a bot filter. If a direct request is refused (HTTP 403), retry once through Apify residential proxy. Off by default because residential proxy traffic is billed to your account (about 2 MB per fetch).

## Actor input object example

```json
{
  "sources": [
    "cpsc",
    "fda_food",
    "fda_drug",
    "fda_device",
    "nhtsa",
    "usda_fsis"
  ],
  "sinceDays": 7,
  "fdaClassification": "any",
  "maxItems": 100,
  "useProxyForUsda": false
}
```

# Actor output Schema

## `recalls` (type: `string`):

All normalized recall records from the run.

## `summary` (type: `string`):

Date window, per-source counts and warnings.

# 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 = {
    "sources": [
        "cpsc",
        "fda_food",
        "fda_drug",
        "fda_device",
        "nhtsa",
        "usda_fsis"
    ],
    "query": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("landoz/us-product-recalls").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 = {
    "sources": [
        "cpsc",
        "fda_food",
        "fda_drug",
        "fda_device",
        "nhtsa",
        "usda_fsis",
    ],
    "query": "",
}

# Run the Actor and wait for it to finish
run = client.actor("landoz/us-product-recalls").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 '{
  "sources": [
    "cpsc",
    "fda_food",
    "fda_drug",
    "fda_device",
    "nhtsa",
    "usda_fsis"
  ],
  "query": ""
}' |
apify call landoz/us-product-recalls --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,landoz/us-product-recalls"
        }
    }
}
```

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/dxFMESsPlfFQbdsEH/builds/0hUhT2P69qbSRetSX/openapi.json
