# CPSC and NHTSA recalls monitor (consumer products and vehicles) (`keepable_injera/cpsc-nhtsa-recalls-monitor`) Actor

Monitor consumer product recalls from CPSC and vehicle watchlist recalls from NHTSA.

- **URL**: https://apify.com/keepable_injera/cpsc-nhtsa-recalls-monitor.md
- **Developed by:** [Chee Chiaw Lim](https://apify.com/keepable_injera) (community)
- **Categories:** E-commerce, Business
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 results

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

## CPSC and NHTSA recalls monitor (consumer products and vehicles)

This Apify Actor returns CPSC consumer product recalls and NHTSA recalls for a vehicle watchlist. Both agencies use one output record shape.

### Coverage and source

The monitor combines a recent CPSC recall window with vehicle-specific NHTSA recall histories. Use it to track product keywords, manufacturers, and vehicles in one dataset. `onlyNew` supports repeated runs that emit each recall once per state store.

CPSC uses [SaferProducts recall data](https://www.saferproducts.gov/RestWebServices/Recall?format=json). NHTSA uses [recalls by vehicle](https://api.nhtsa.gov/recalls/recallsByVehicle?make=toyota\&model=camry\&modelYear=2020). Neither source requires an API key or proxy.

### Input

| Field | Default | Meaning |
| --- | --- | --- |
| `sources` | `["cpsc", "nhtsa"]` | Agencies to query, in the selected order. |
| `sinceDays` | 30 | CPSC recalls since midnight UTC this many days ago. Integer from 1 to 365. |
| `keywords` | `[]` | CPSC title, description, or product name contains any keyword, without case sensitivity. |
| `manufacturers` | `[]` | CPSC manufacturer, importer, or distributor name contains any filter, without case sensitivity. |
| `vehicles` | `["toyota\|camry\|2020"]` | Watchlist entries in `make\|model\|year` format. |
| `nhtsaSinceDays` | 0 | Zero includes all recalls for each vehicle. Positive values filter by report received date. Integer from 0 to 36500. |
| `onlyNew` | false | Skip recalls successfully emitted to the state store on earlier runs. |
| `maxItems` | 100 | Maximum emitted records after deduplication and onlyNew filtering. Integer from 1 to 10000. |
| `stateStoreName` | `cpsc-nhtsa-recalls-monitor-state` | Named key-value store for cross-run recall IDs. |

Empty filter lists select all CPSC recalls in the window. When both CPSC filters are set, a record must match both groups. CPSC keyword and manufacturer filters run locally after the API returns its array. Each vehicle produces one NHTSA request. Neither API uses paging. NHTSA campaign numbers are deduplicated across the watchlist within each run. The first matching vehicle supplies the record's product and query URL.

### Output

Each record contains recall details, products, manufacturers, hazard, remedy, source attribution, and monitoring metadata. Missing fields are null or empty arrays. CPSC units are joined text. NHTSA units retain the source value when present. NHTSA titles combine the vehicle name and component.

Example record follows.

```json
{
  "agency": "NHTSA",
  "recallId": "20V682000",
  "recallDate": "2020-04-11",
  "title": "TOYOTA CAMRY 2020 - FUEL SYSTEM, GASOLINE:DELIVERY:FUEL PUMP",
  "description": "Toyota Motor Engineering & Manufacturing (Toyota) is recalling certain 2018-2019 4Runner, 2019-2020 Avalon, 2019 Corolla Hatchback, 2017-2019 Highlander, 2018-2020 Camry, 2020 Corolla, 2018-2019 Land Cruiser, 2017-2020 Tacoma, 2019-2020 RAV4, 2019-2020 Sequoia, 2017-2020 Sienna, 2019-2020 Tundra, 2018-2020 Lexus ES350, 2017 Lexus GS200t, 2017-2019 Lexus GS350, 2019 Lexus GS300, 2018-2020 Lexus LC500h, 2019-2020 Lexus LS500, 2018-2019 Lexus GX460, 2017 Lexus IS200t, 2019 Lexus IS300, 2019 Lexus IS350, 2018-2020 Lexus LC500, 2018 Lexus LS500, 2019 Lexus LS500h, 2018-2019 Lexus LX570, 2017 Lexus RC200t, 2019 Lexus RC300, RC350, 2017 and 2019-2020 Lexus RX350, 2018-2020 RX350L, 2019 Lexus UX200, 2018-2019 Lexus NX300 vehicles.  The low-pressure fuel pump inside the fuel tank may fail.",
  "hazard": "If the fuel pump fails, the engine can stall while driving, increasing the risk of a crash.",
  "remedy": "Toyota will notify owners, and dealers will replace the fuel pump assembly with an improved one, free of charge.  Owners of specific models were notified that remedy parts were available starting January 21, 2021.  Owners of other models will be notified as remedy parts become available.  Remedy parts should be available for all affected vehicles by late March 2021.  Owners may contact Toyota customer service at 1-888-270-9371 or Lexus customer service at 1-800-255-3987.  Note: This recall is an expansion of recall 20V-012.  Toyota's number for this recall is 20TA02.  Lexus' number for this recall is 20LA01.",
  "products": [
    "TOYOTA CAMRY 2020"
  ],
  "manufacturers": [
    "Toyota Motor Engineering & Manufacturing"
  ],
  "component": "FUEL SYSTEM, GASOLINE:DELIVERY:FUEL PUMP",
  "unitsAffected": null,
  "parkIt": false,
  "parkOutSide": false,
  "recallUrl": "https://www.nhtsa.gov/recalls?nhtsaId=20V682000",
  "source": "U.S. National Highway Traffic Safety Administration (api.nhtsa.gov)",
  "sourceUrl": "https://api.nhtsa.gov/recalls/recallsByVehicle?make=toyota&model=camry&modelYear=2020",
  "licence": "NHTSA: public information, may be distributed or copied (https://www.nhtsa.gov/about-nhtsa/terms-use)",
  "disclaimer": "Not endorsed by CPSC or NHTSA. Images are not included.",
  "generatedId": "NHTSA:20V682000",
  "changeType": "new",
  "scrapedAt": "2026-10-30T00:00:00.000Z"
}
```

The dataset includes a table view of key fields. `RUN_SUMMARY` in the default key-value store records timestamps, fetched, eligible, and pushed counts, charge-limit status, and any error. Fetched counts represent mapped candidates yielded by the sources after source filters and NHTSA campaign deduplication.

### State and pricing

The state store contains agency-prefixed recall IDs under `SEEN_RECALL_IDS`. An absent ID gets `changeType: "new"`. A stored ID gets `"seen"`. Only successful pushes enter the set. With `onlyNew` false, stored recalls appear again. The monitor does not detect revisions to an existing recall ID. Use separate state stores for independent monitors.

If permission to open the named store is denied, the Actor warns, uses the default store, and disables `onlyNew` for that run.

Pricing is $0.002 per result, no start fee. Each emitted record uses the `result` billing event. Skipped recalls do not incur a result charge. The Actor stops at the available charge limit. Platform compute and storage charges may apply separately.

### Privacy

Images and image URLs are excluded because images may have third-party licences. Consumer contact fields and NHTSA notes are excluded. Remedy text is retained, including any phone numbers or email addresses within it. The Actor stores mapped records and recall IDs, rather than raw source rows.

### Licence and disclaimer

CPSC: public information, may be freely distributed and copied, credit CPSC ([CPSC privacy policy](https://www.cpsc.gov/About-CPSC/Policies-Statements-and-Directives/Privacy-Policy)).

NHTSA: public information, may be distributed or copied ([NHTSA terms of use](https://www.nhtsa.gov/about-nhtsa/terms-use)).

Every record carries the relevant licence text, agency source, API query URL, and this disclaimer.

Not endorsed by CPSC or NHTSA. Images are not included.

### Limits

Coverage follows the agency APIs and can contain delays or omissions. The vehicle watchlist does not check VINs or establish whether a particular vehicle needs a repair. Read the linked agency notice for recall instructions.

NHTSA report dates use month-first parsing. Dates whose first number exceeds 12 use day-first parsing, as found in the supplied fixture. Invalid dates are null and are excluded when a positive NHTSA lookback is active. Ambiguous dates follow MM/DD/YYYY.

CPSC runs first by default, so it can fill `maxItems` before NHTSA is queried. Reorder `sources` or run separate monitors when each agency needs its own result budget. CPSC downloads the full response array. Seen records do not consume `maxItems`.

Requests wait at least one second between starts per host. HTTP 429 and 5xx responses retry up to three times. Network errors stop the run and appear in `RUN_SUMMARY`.

### Local verification

Run `npm test` for offline tests. Use fresh local storage for a fixture-backed run with network access blocked.

```sh
CRAWLEE_STORAGE_DIR=./storage/verification APIFY_LOCAL_STORAGE_DIR=./storage/verification NODE_OPTIONS="--import ./scripts/offline-fixture.js" npm start
node scripts/verify-output.js ./storage/verification
```

The preload serves the supplied fixtures. It applies the CPSC start date but does not simulate different NHTSA vehicle responses. A normal run without the preload contacts the agency APIs.

# Actor input Schema

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

Agencies to query, in the selected order.

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

CPSC recalls since midnight UTC this many days ago.

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

Case-insensitive substring match on title, description, or product names. Any keyword matches.

## `manufacturers` (type: `array`):

Case-insensitive substring match on manufacturer, importer, or distributor names. Any filter matches.

## `vehicles` (type: `array`):

Each entry is make|model|year.

## `nhtsaSinceDays` (type: `integer`):

Zero includes all recalls for each vehicle. Positive values filter report received dates.

## `onlyNew` (type: `boolean`):

Skip recall IDs successfully emitted to the state store.

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

Maximum emitted results after duplicate and onlyNew filtering.

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

Named key-value store for cross-run recall IDs.

## Actor input object example

```json
{
  "sources": [
    "cpsc",
    "nhtsa"
  ],
  "sinceDays": 30,
  "keywords": [],
  "manufacturers": [],
  "vehicles": [
    "toyota|camry|2020"
  ],
  "nhtsaSinceDays": 0,
  "onlyNew": false,
  "maxItems": 100,
  "stateStoreName": "cpsc-nhtsa-recalls-monitor-state"
}
```

# Actor output Schema

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

No description

## `runSummary` (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 = {
    "sources": [
        "cpsc",
        "nhtsa"
    ],
    "sinceDays": 30,
    "keywords": [],
    "manufacturers": [],
    "vehicles": [
        "toyota|camry|2020"
    ],
    "nhtsaSinceDays": 0,
    "onlyNew": false,
    "maxItems": 100,
    "stateStoreName": "cpsc-nhtsa-recalls-monitor-state"
};

// Run the Actor and wait for it to finish
const run = await client.actor("keepable_injera/cpsc-nhtsa-recalls-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 = {
    "sources": [
        "cpsc",
        "nhtsa",
    ],
    "sinceDays": 30,
    "keywords": [],
    "manufacturers": [],
    "vehicles": ["toyota|camry|2020"],
    "nhtsaSinceDays": 0,
    "onlyNew": False,
    "maxItems": 100,
    "stateStoreName": "cpsc-nhtsa-recalls-monitor-state",
}

# Run the Actor and wait for it to finish
run = client.actor("keepable_injera/cpsc-nhtsa-recalls-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 '{
  "sources": [
    "cpsc",
    "nhtsa"
  ],
  "sinceDays": 30,
  "keywords": [],
  "manufacturers": [],
  "vehicles": [
    "toyota|camry|2020"
  ],
  "nhtsaSinceDays": 0,
  "onlyNew": false,
  "maxItems": 100,
  "stateStoreName": "cpsc-nhtsa-recalls-monitor-state"
}' |
apify call keepable_injera/cpsc-nhtsa-recalls-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,keepable_injera/cpsc-nhtsa-recalls-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/2hdCngcCz2uUsJ2cv/builds/0rx8MgmAvDMcKlE5R/openapi.json
