# Product Recall Monitor (CPSC, NHTSA, FDA, EU) (`jetlaunch/product-recall-monitor`) Actor

Search consumer product, vehicle, food, drug and device recalls from CPSC, NHTSA, FDA and EU Safety Gate open data, check VINs, and watch brands for new recalls.

- **URL**: https://apify.com/jetlaunch/product-recall-monitor.md
- **Developed by:** [Chris O'Byrne](https://apify.com/jetlaunch) (community)
- **Categories:** E-commerce, Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $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

### What does Product Recall Monitor do?

Product Recall Monitor watches official recall notices across four public sources and returns the same clean fields for each: the US Consumer Product Safety Commission (CPSC), the FDA (through openFDA), the EU Safety Gate rapid alert system for non-food products, and the US National Highway Traffic Safety Administration (NHTSA). Give it your brands and keywords once, schedule it, and each run returns only the recalls it has not shown you before.

It has three modes:

- **Watchlist**: a list of brands or keywords. Each run returns only new recalls since the previous run, so you can schedule it daily or weekly and act on what is new.
- **Recall search**: find recalls by keyword, brand, product category, agency and date range, across all selected agencies in one dataset.
- **VIN check**: a secondary mode that decodes up to 200 VINs and lists the NHTSA recall campaigns filed for each vehicle's make, model and model year.

Every recall comes back as one row with a recall ID, agency, date, product, brand, hazard, remedy, manufacturer, units affected, model or UPC where the source gives one, country, and a link to the official source. Results are available as JSON, CSV, Excel or through the Apify API.

#### Who is it for?

Retailers and marketplace sellers who must check their catalog against recalls, product compliance and quality teams, insurers and claims teams, fleet and used-car operators, recall-notification apps, and researchers who need recall data across agencies without writing four integrations.

#### How to use it

1. Open the Actor and choose a **Mode**.
2. For recall search, enter keywords and or brands, pick the agencies, and set **Max results**. For NHTSA also enter a vehicle make and model year, or a campaign number.
3. For a watchlist, enter the terms and a **Watchlist name**, run it once, then add a schedule in Apify to run it again.
4. For VIN check, paste your VINs, one per line.
5. Download the dataset or call it through the API.

#### Input examples

Recall search (the default prefill):

```json
{
  "mode": "recall-search",
  "keywords": ["stroller"],
  "agencies": ["cpsc", "fda", "eu_safety_gate"],
  "daysBack": 365,
  "maxResults": 20
}
```

Watchlist:

```json
{
  "mode": "watchlist",
  "watchlistTerms": ["stroller", "Graco", "crib"],
  "agencies": ["cpsc", "fda", "eu_safety_gate"],
  "watchlistName": "baby-products",
  "watchlistLookbackDays": 14
}
```

NHTSA search by vehicle:

```json
{
  "mode": "recall-search",
  "agencies": ["nhtsa"],
  "vehicleMake": "Ford",
  "vehicleModel": "F-150",
  "vehicleYear": 2022,
  "maxResults": 10
}
```

VIN check:

```json
{ "mode": "vin-check", "vins": ["1FTFW1E50NFA00001", "1HGCM82633A004352"] }
```

#### Output example

```json
{
  "record_type": "recall",
  "recall_id": "26639",
  "agency": "CPSC",
  "date": "2026-07-23",
  "title": "Peony Design Recalls Personalized Baby Bibs and Stroller Bags Due to Risk of Serious Injury or Death from Choking Hazard",
  "product": "Personalized Baby Bibs and Stroller Bags",
  "brand": null,
  "hazard": "The snap can detach from the recalled bibs and stroller bags, posing a risk of serious injury or death from a choking hazard to young children.",
  "remedy": "Consumers should take the recalled baby bibs and stroller bags away from children immediately, stop using them, and contact Peony Design to receive a full refund. Consumers will be asked to discard the recalled baby bibs and stroller bags.",
  "remedy_type": "Refund",
  "manufacturer": "Peony Design Co., of Howell, MI",
  "units": "About 52",
  "model": null,
  "upc": null,
  "category": null,
  "country": "United States",
  "source_url": "https://www.cpsc.gov/Recalls/2026/Peony-Design-Recalls-Personalized-Baby-Bibs-and-Stroller-Bags-Due-to-Risk-of-Serious-Injury-or-Death-from-Choking-Hazard"
}
```

Fields the source does not publish are returned as `null`. Some rows carry extra agency fields, for example FDA `classification` and `status`, EU `risk_level` and `notifying_country`, and NHTSA `park_it`. VIN check rows contain the decoded make, model, model year, trim, body class, plant country, and a `recalls` list.

#### How the dates and fields are defined

- CPSC: `date` is the recall date. `brand` is read from an "X-branded" phrase in the description when there is one, otherwise null. `manufacturer` falls back to the importer or distributor when no manufacturer is listed.
- NHTSA: `date` is the date the manufacturer reported the campaign. One row is returned per campaign, with the matching models merged. `units` is looked up per campaign.
- FDA: `date` is the enforcement report date, which is when the recall appears in openFDA. `recall_initiation_date` is when the firm began it. FDA does not publish a remedy field, so `remedy` is null. UPCs are read from the product description when it contains one.
- EU Safety Gate: `date` is the publication date of the weekly report that contains the alert. `remedy` holds the measures taken. `manufacturer` and `units` are not published.

#### Pricing

You pay per event. You pay only these event prices; platform usage is not billed to you separately.

| Event | Price | When it is charged |
| --- | --- | --- |
| Actor start | $0.00005 | Once per run (Apify platform event) |
| Recall record | $0.005 | Per recall row returned in recall search or watchlist mode |
| VIN check | $0.01 | Per VIN that was decoded and checked. VINs that are invalid or cannot be decoded are not charged |
| Watchlist run with new recalls | $0.02 | Per watchlist run that returns at least one new recall. Runs with nothing new are not charged |

Examples: the default prefill (up to 20 recalls) costs at most $0.10. A VIN check of 50 vehicles costs $0.50. A daily watchlist that finds 3 new recalls costs $0.035 that day and nothing on days with no news. You can set a maximum charge per run in the run options and the Actor stops at that limit.

#### Data sources and licences

- CPSC Recalls API, saferproducts.gov. US government public information. The CPSC API page does not publish a numeric rate limit or separate licence terms.
- NHTSA recalls API (api.nhtsa.gov) and vPIC VIN decoder (vpic.nhtsa.dot.gov). US government public information. NHTSA says vPIC applies automated traffic rate control.
- openFDA enforcement reports (api.fda.gov). Content is dedicated to the public domain under CC0 1.0 unless noted; the openFDA terms apply. Data provided by the U.S. Food and Drug Administration (https://open.fda.gov). openFDA limits unauthenticated use to 240 requests per minute and 1,000 per day per IP address. You can enter your own free openFDA key to raise the daily limit. The openFDA disclaimer applies: do not rely on this data to make decisions about medical care.
- EU Safety Gate weekly report XML, published by the European Commission as open data. The data.europa.eu catalogue lists this XML distribution under CC0 1.0. Other Safety Gate content is covered by the Commission reuse notice.

The Actor sends a descriptive User-Agent with a contact address, spaces its requests (at most about 3 per second per host, less for some hosts), retries politely on errors and honors Retry-After. It does not log in, use proxies or work around any limit.

This Actor is not affiliated with, endorsed by or sponsored by CPSC, NHTSA, FDA, the European Commission or any other agency named here. Agency names are used only to describe the data source.

#### Personal data

The Actor returns recall notices published by agencies. It does not output consumer contact details, retailer lists or street addresses. E-mail addresses and non toll-free phone numbers inside agency text are replaced with placeholders. Manufacturer names are business names as the agency published them. VINs you submit are processed only to call NHTSA and are written only to your own dataset.

#### FAQ

**Is a VIN check the same as an open recall check?**
No. NHTSA does not offer a public per-VIN API that says whether a recall repair was already done. The VIN check decodes the VIN and lists every NHTSA campaign filed for that make, model and model year. Confirm repair status with the manufacturer or on nhtsa.gov/recalls.

**Why does NHTSA need a make and model year?**
The NHTSA recalls API only searches by make, model and model year or by campaign number. It has no keyword search. If you give a make and year without a model, up to 40 models are searched.

**How does the watchlist know what is new?**
It stores the IDs it has returned and the last successful run date per agency in a key-value store named `product-recall-monitor-state` in your account. Change the **Watchlist name** to keep separate lists. Turn on **Reset watchlist state** to start over.

**How long does a run take?**
CPSC, FDA and NHTSA answer in seconds. EU Safety Gate is read from weekly report files, so a 365 day search reads about 50 files and takes about a minute.

**Why did a source return nothing?**
No recall in the date range matched your terms, or the source was unreachable. The key-value store record `RUN_SUMMARY` shows what each source returned and any error. If every selected source fails, the run fails and nothing is charged.

#### Limitations

- Keyword matching is plain text matching. CPSC matches on title, product name and description; FDA on product description, reason and firm name; EU Safety Gate on alert text.
- The EU Safety Gate data does not include manufacturer or units, and its dates are weekly report dates.
- Source data can lag the agencies' own websites and can contain errors. Always check the linked official notice before acting.
- openFDA allows 1,000 unauthenticated requests per day per IP address. Add your own key if you hit it.

#### Support

Use the Issues tab of this Actor to report a problem or request a source or field. Include the run ID and your input.

# Actor input Schema

## `mode` (type: `string`):

recall-search finds recalls by keyword, brand, category and date. vin-check decodes VINs and lists NHTSA recall campaigns for each vehicle. watchlist returns only recalls it has not returned before for your brand or keyword list.

## `keywords` (type: `array`):

Recall search: words or phrases to find in the product name, title, hazard or description. A recall matches if it contains any of them. Leave empty to browse by date.

## `brands` (type: `array`):

Recall search: brand or company names to look for. If you also give keywords, a recall must match both a keyword and a brand.

## `productCategory` (type: `string`):

Optional category text. CPSC: matched against the CPSC product type (for example toys). EU Safety Gate: matched against the alert category (for example Toys). FDA: matched against the product description.

## `agencies` (type: `array`):

Which sources to search. NHTSA has no free-text search, so it also needs a vehicle make and model year or a campaign number (see below).

## `daysBack` (type: `integer`):

Search recalls dated within this many days before the end date. Ignored when Date from is set.

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

Optional start date, YYYY-MM-DD. Overrides Days back.

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

Optional end date, YYYY-MM-DD. Defaults to today (UTC).

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

Maximum number of recalls returned in total, newest first. You are charged per recall returned.

## `fdaCenters` (type: `array`):

Which openFDA enforcement reports to search when FDA is selected.

## `openFdaApiKey` (type: `string`):

Optional. Without a key openFDA allows 240 requests per minute and 1,000 per day per IP address. A free key from open.fda.gov raises the daily limit.

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

For NHTSA recall search: vehicle make, for example Ford.

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

Optional model, for example F-150. If empty, up to 40 models of the make and year are searched.

## `vehicleYear` (type: `integer`):

Vehicle model year, for example 2022.

## `nhtsaCampaignNumber` (type: `string`):

Alternative to make and year: look up one NHTSA campaign, for example 20V682000.

## `vins` (type: `array`):

VIN check: up to 200 17-character VINs. Each VIN is decoded with the NHTSA vPIC service and matched to NHTSA recall campaigns for its make, model and model year.

## `watchlistTerms` (type: `array`):

Watchlist: brand or keyword terms. Each run returns only recalls not returned by an earlier run with the same watchlist name.

## `watchlistVehicles` (type: `array`):

Optional list of vehicles to watch, as JSON objects with make, model and year. Example: \[{"make":"Ford","model":"F-150","year":2022}]

## `watchlistName` (type: `string`):

Name of the saved state. Use different names for different watchlists. Letters, digits and hyphens.

## `watchlistLookbackDays` (type: `integer`):

On the first run of a watchlist, return recalls from this many days back. Later runs return what is new since the previous run.

## `resetWatchlist` (type: `boolean`):

Forget what this watchlist has already returned and start again with the first-run lookback.

## `stateStoreName` (type: `string`):

Name of the key-value store that holds watchlist state. Keep the default unless you manage several accounts of state.

## Actor input object example

```json
{
  "mode": "recall-search",
  "keywords": [
    "stroller"
  ],
  "agencies": [
    "cpsc",
    "fda",
    "eu_safety_gate"
  ],
  "daysBack": 365,
  "maxResults": 20,
  "fdaCenters": [
    "food",
    "drug",
    "device"
  ],
  "watchlistName": "default",
  "watchlistLookbackDays": 14,
  "resetWatchlist": false,
  "stateStoreName": "product-recall-monitor-state"
}
```

# Actor output Schema

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

No description

## `vinChecks` (type: `string`):

No description

## `summary` (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 = {
    "keywords": [
        "stroller"
    ],
    "agencies": [
        "cpsc",
        "fda",
        "eu_safety_gate"
    ],
    "daysBack": 365,
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("jetlaunch/product-recall-monitor").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 = {
    "keywords": ["stroller"],
    "agencies": [
        "cpsc",
        "fda",
        "eu_safety_gate",
    ],
    "daysBack": 365,
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("jetlaunch/product-recall-monitor").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 '{
  "keywords": [
    "stroller"
  ],
  "agencies": [
    "cpsc",
    "fda",
    "eu_safety_gate"
  ],
  "daysBack": 365,
  "maxResults": 20
}' |
apify call jetlaunch/product-recall-monitor --silent --output-dataset

```

## MCP server setup

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

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/3CQx1d70Seg3d1UF0/builds/OE9qowKsPaKtTjbg2/openapi.json
