# US CPSC Product Recalls Scraper (`crawlerbros/us-cpsc-product-recalls-scraper`) Actor

Scrape US CPSC SaferProducts.gov recalls via the free official REST API, no key required. Search by title, product, category, date range, hazard, manufacturer, retailer, importer, distributor, or remedy type. Full product, hazard, injury, remedy, and image data included.

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

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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 CPSC Product Recalls Scraper

Scrape the US Consumer Product Safety Commission's (CPSC) **SaferProducts.gov** recall database — the official, free, public REST API. No login, no API key, no cookies, no proxy required. Search by recall title, product name, product category, date range, hazard keyword, manufacturer, retailer, importer, distributor, remedy type, or country of manufacture — or fetch specific recalls directly by their official recall number.

### What this actor does

- **Two modes:** `search` (filtered recall search) and `byRecallNumber` (direct lookup by one or more official recall numbers)
- **Rich filtering:** title, product name, product category (free-text substring match against CPSC's full ~645-value category taxonomy), description keyword, recall date range, last-updated date range, hazard keyword, injury keyword, manufacturer, retailer, importer, distributor, manufacturer country, remedy type, and "injuries reported only"
- **Full recall detail:** affected products, hazard descriptions, injury reports, remedies offered, companies involved (manufacturer/retailer/importer/distributor), country of manufacture, product photos, and cross-agency related-recall links (e.g. Health Canada)
- **Empty fields are omitted** — no nulls, no placeholder text in the dataset output

### Output per recall

| Field | Type | Description |
|---|---|---|
| `recallId` | integer | Internal CPSC record ID |
| `recallNumber` | string | Official CPSC recall number (e.g. `26639`) |
| `recallDate` | string | Date the recall was announced (YYYY-MM-DD) |
| `lastPublishDate` | string | Date the recall record was last updated (YYYY-MM-DD) |
| `title` | string | Full recall title |
| `description` | string | Full recall description |
| `url` | string | Official CPSC recall page URL |
| `consumerContact` | string | How affected consumers can reach the company |
| `products` | array of objects | Recalled products `{name, type, numberOfUnits}` |
| `productNames` | array of strings | Flat list of recalled product names |
| `productTypes` | array of strings | Flat list of CPSC product category names |
| `productUpcs` | array of strings | UPC codes, when published |
| `hazards` | array of strings | Hazard description sentences |
| `injuries` | array of strings | Reported injury/incident descriptions (only when real injury data was reported — "None reported" style entries are omitted) |
| `remedies` | array of strings | Remedy description sentences |
| `remedyOptions` | array of strings | Remedy categories offered (`Refund`, `Repair`, `Replace`, etc.) |
| `manufacturers` | array of strings | Manufacturer names |
| `retailers` | array of strings | Retailer names |
| `importers` | array of strings | Importer names (published for a subset of recalls) |
| `distributors` | array of strings | Distributor names (published for a subset of recalls) |
| `manufacturerCountries` | array of strings | Countries of manufacture |
| `images` | array of objects | Recall photos `{url, caption}` |
| `relatedRecallUrls` | array of strings | Links to related recalls from other agencies (e.g. Health Canada) when CPSC publishes them |
| `recordType` | string | Always `"recall"` |
| `scrapedAt` | string | ISO 8601 UTC timestamp when the record was scraped |

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search` / `byRecallNumber` |
| `recallTitle` | string | *(empty — form shows `stroller` as an example)* | Filter recalls whose title contains this text. Leave blank to search across all titles. |
| `productName` | string | – | Filter recalls whose product name contains this text |
| `productType` | string | – | Filter by CPSC product category, case-insensitive substring match against the full ~645-value taxonomy (e.g. `Toy`, `Bicycles`, `Batteries and Chargers`) |
| `recallDateFrom` / `recallDateTo` | string | – | Recall-announced date range (YYYY-MM-DD) |
| `lastPublishDateFrom` / `lastPublishDateTo` | string | – | Last-updated date range (YYYY-MM-DD) |
| `hazardKeyword` | string | – | Filter by hazard keyword (e.g. `choking`, `fire`, `laceration`) |
| `descriptionKeyword` | string | – | Filter by keyword in the full recall description (e.g. `lithium`, `lead paint`) |
| `injuryKeyword` | string | – | Filter by keyword in the reported-injury text (e.g. `hospitalized`, `burn`) |
| `manufacturer` | string | – | Filter by manufacturer name |
| `retailer` | string | – | Filter by retailer name |
| `importer` | string | – | Filter by importer name |
| `distributor` | string | – | Filter by distributor name |
| `manufacturerCountry` | string | – | Filter by country of manufacture (e.g. `China`, `United States`) |
| `remedyOption` | string (select) | – | `Refund` / `Repair` / `Replace` / `New Instructions` / `Dispose` / `Label` / `Inspect` / `No Remedy Available` |
| `injuriesReportedOnly` | boolean | `false` | Only return recalls with a real reported injury |
| `recallNumbers` | array | `["26639"]` | Recall numbers to fetch directly (mode=byRecallNumber) |
| `maxItems` | integer | `50` | Maximum records to return (1–500) |
| `proxyConfiguration` | object | Apify `AUTO` (free datacenter) | Rotates outbound IP per retry to recover from CPSC's occasional multi-minute IP blocks. Free, no residential proxy involved. Can be disabled with `{"useApifyProxy": false}`. |

#### Example: search for battery recalls with injuries reported

```json
{
  "mode": "search",
  "recallTitle": "battery",
  "injuriesReportedOnly": true,
  "maxItems": 25
}
```

#### Example: look up specific recall numbers

```json
{
  "mode": "byRecallNumber",
  "recallNumbers": ["26639", "26692"]
}
```

#### Example: browse recalls in a product category with a date range

```json
{
  "mode": "search",
  "productType": "Bicycles & Accessories",
  "recallDateFrom": "2025-01-01",
  "recallDateTo": "2026-08-18",
  "maxItems": 100
}
```

#### Example: recalls of products manufactured in a specific country with a chosen remedy

```json
{
  "mode": "search",
  "manufacturerCountry": "China",
  "remedyOption": "Refund",
  "maxItems": 50
}
```

### Use cases

- **Product safety & compliance teams** — monitor new recalls in the categories your company sells or imports
- **E-commerce marketplaces** — cross-check catalog listings against active recalls to flag or delist affected products
- **Insurance & risk analysis** — track recall volume, hazard types, and injury rates by manufacturer or category over time
- **Consumer advocacy & journalism** — research recall trends, remedy patterns, or specific hazard types (choking, fire, lead) for reporting
- **Parents & consumer researchers** — check whether a specific product, brand, or manufacturer has an open recall before buying
- **Retailers & distributors** — audit recall history for a given supplier, manufacturer, or country of origin before onboarding

### FAQ

**What is SaferProducts.gov?**
It's the US Consumer Product Safety Commission's official public database of consumer product recalls and safety incident reports. This actor reads directly from CPSC's public recall data — no CPSC login or account is needed to access it.

**Is this actor affiliated with the CPSC?**
No. This is an independent, third-party actor that reads CPSC's publicly published recall data. It is not operated or endorsed by the US government.

**How far back does the data go, and how fresh is it?**
CPSC's recall database covers the full history of published recalls (thousands of records going back decades). Each request reads live from CPSC, so results reflect whatever is currently published — typically within a day of an official recall announcement.

**Why are some fields like `productUpcs` or `importers` missing from certain recalls?**
CPSC only publishes those details when they're available for that specific recall. A handful of fields documented in CPSC's schema (a product description separate from the title, a model number, a "sold at" label, and a hazard-type code) are never published by CPSC for any recall, so they're never in the output.

**Can I search by UPC or model number?**
No — CPSC does not offer a working search by UPC or model number in its public data, so this isn't exposed as a filter.

**How does the product category filter work if there's no dropdown?**
CPSC publishes over 600 distinct product category names, too many for a fixed list. `productType` matches any part of the category name (case-insensitive), so short keywords like "Toy" or "Bicycles" work just as well as full category names.

**What happens if I don't set any filters?**
The actor returns recalls across CPSC's entire published history, most recent first, up to your `maxItems` limit.

**Does this actor need a proxy or login?**
No. It reads a public government API with no authentication. A free Apify datacenter proxy is used automatically in the background to stay reliable; you don't need to configure anything or pay for a residential proxy.

# Actor input Schema

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

Search recalls with filters, or fetch specific recalls by their official recall number.

## `recallTitle` (type: `string`):

Filter recalls whose title contains this text (e.g. "stroller", "heater"). Leave blank to search across all recall titles. Used in search mode.

## `productName` (type: `string`):

Filter recalls whose product name contains this text. Used in search mode. Combine with Recall Title for a narrower search.

## `productType` (type: `string`):

Filter by official CPSC product category (case-insensitive substring match, sent server-side, e.g. "Toy", "Bicycles", "Batteries and Chargers", "Clothing (Children)"). CPSC publishes 600+ distinct category names — too many for a dropdown — so type any category name or keyword. Common examples: Clothing (Children), Bicycles & Accessories, Toy Animals Stuffed/Not Stuffed, Candles & Candle Holders, Adapter/Power Supply/Charger/Battery, Cribs, All Terrain Vehicles (ATVs), Electric Heaters, Grills Smokers & Accessories, Lawn Mowers & Accessories, Strollers & Accessories, Hair Dryers, Swing Sets, Batteries and Chargers, Furniture. Used in search mode.

## `recallDateFrom` (type: `string`):

Only include recalls announced on or after this date. Format: YYYY-MM-DD. Used in search mode.

## `recallDateTo` (type: `string`):

Only include recalls announced on or before this date. Format: YYYY-MM-DD. Used in search mode.

## `lastPublishDateFrom` (type: `string`):

Only include recalls last updated/published on or after this date. Format: YYYY-MM-DD. Used in search mode.

## `lastPublishDateTo` (type: `string`):

Only include recalls last updated/published on or before this date. Format: YYYY-MM-DD. Used in search mode.

## `hazardKeyword` (type: `string`):

Filter recalls whose hazard description contains this keyword (e.g. "choking", "fire", "laceration", "fall"). Used in search mode.

## `descriptionKeyword` (type: `string`):

Filter recalls whose full recall description contains this keyword (e.g. "lithium", "lead paint", "entrapment"). Sent to CPSC as a server-side search term, so it narrows the fetch itself rather than only filtering already-downloaded results. Used in search mode.

## `injuryKeyword` (type: `string`):

Filter recalls whose reported-injury text contains this keyword (e.g. "hospitalized", "laceration", "burn", "death"). Different from "Only recalls with reported injuries" below — this searches the injury narrative text itself. Used in search mode.

## `manufacturer` (type: `string`):

Filter recalls whose manufacturer name contains this text. Used in search mode.

## `retailer` (type: `string`):

Filter recalls whose retailer name contains this text. Used in search mode.

## `importer` (type: `string`):

Filter recalls whose importer name contains this text. Only populated for a subset of recalls. Used in search mode.

## `distributor` (type: `string`):

Filter recalls whose distributor name contains this text. Only populated for a subset of recalls. Used in search mode.

## `manufacturerCountry` (type: `string`):

Filter recalls by country of manufacture (e.g. "China", "United States", "Vietnam"). Used in search mode.

## `remedyOption` (type: `string`):

Filter by the remedy offered to consumers (e.g. "Refund", "Repair"). Sent to CPSC as a server-side search term, so it narrows the fetch itself rather than only filtering already-downloaded results. Used in search mode.

## `injuriesReportedOnly` (type: `boolean`):

When enabled, only return recalls where at least one injury was reported to CPSC.

## `recallNumbers` (type: `array`):

One or more official CPSC recall numbers to fetch directly (e.g. "26639", "24-001"). Used in byRecallNumber mode.

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

Maximum number of recall records to return.

## `proxyConfiguration` (type: `object`):

Uses Apify's free datacenter (AUTO) proxy group by default to rotate outbound IPs. CPSC's WAF occasionally blocks a single IP for several minutes at a time; rotating through the free AUTO group on retries recovers from this without any paid proxy. No residential proxy is needed. Leave enabled unless you have a specific reason to disable it.

## Actor input object example

```json
{
  "mode": "search",
  "recallTitle": "stroller",
  "remedyOption": "",
  "injuriesReportedOnly": false,
  "recallNumbers": [
    "26639"
  ],
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Dataset containing all scraped CPSC recall records.

# 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 = {
    "mode": "search",
    "recallTitle": "stroller",
    "remedyOption": "",
    "injuriesReportedOnly": false,
    "recallNumbers": [
        "26639"
    ],
    "maxItems": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/us-cpsc-product-recalls-scraper").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 = {
    "mode": "search",
    "recallTitle": "stroller",
    "remedyOption": "",
    "injuriesReportedOnly": False,
    "recallNumbers": ["26639"],
    "maxItems": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/us-cpsc-product-recalls-scraper").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 '{
  "mode": "search",
  "recallTitle": "stroller",
  "remedyOption": "",
  "injuriesReportedOnly": false,
  "recallNumbers": [
    "26639"
  ],
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call crawlerbros/us-cpsc-product-recalls-scraper --silent --output-dataset

```

## MCP server setup

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

```

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/4OCUsGcN8fkVDBluU/builds/O6ryvJZzU5Bn2x1d4/openapi.json
