CPSC Product Recalls API — US Consumer Product Recall Watch avatar

CPSC Product Recalls API — US Consumer Product Recall Watch

Pricing

from $1.00 / 1,000 recall returneds

Go to Apify Store
CPSC Product Recalls API — US Consumer Product Recall Watch

CPSC Product Recalls API — US Consumer Product Recall Watch

US product recalls from the CPSC database by product words and date, or only new and updated ones: products, hazards, injuries, remedy, firms and the recall page; failed or unchanged rows are never charged. Not affiliated with or endorsed by the U.S. Consumer Product Safety Commission (CPSC).

Pricing

from $1.00 / 1,000 recall returneds

Rating

0.0

(0)

Developer

COMPASS DEV

COMPASS DEV

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Categories

Share

Returns US consumer product recalls from the CPSC recall database, filtered by product words and recall date, or only new and updated recalls since your last run: recall number and date, products, hazards, injuries, remedy, firms and the recall page; failed or unchanged rows are never charged.

Give product words (helmet, power bank, crib, a model number) or none, and a window; get one flat row per recall of the U.S. Consumer Product Safety Commission (CPSC): the title, what the recall covers, the products and their types, the units recalled, the hazard, the injuries reported, the remedy (refund, replace, repair), the manufacturers, importers, distributors and retailers, where it was sold, the country of manufacture, photo links and the recall page on cpsc.gov. Built for retailers, marketplaces, importers, compliance and product-safety teams, newsrooms and AI agents that need US product recalls without polling cpsc.gov. Not affiliated with or endorsed by the U.S. Consumer Product Safety Commission (CPSC).

What it does

  • Export mode: every recall dated in the window (default: the last 90 days) whose title, product names, models, product types or description hold every word of an entry, newest first, one flat row per recall. No words: every recall of the window.
  • Watch mode (give a watch list name in stateName): remembers every recall it returned and gives only:
    • baseline: the first run of the list;
    • new: a recall the list did not have;
    • changed: CPSC updated the notice (its last publish date, title, products, hazard, remedy, units, injuries or firms; changedFields and previousValues say what and from what);
    • unchanged recalls are free and left out (includeUnchanged: true returns them as free rows).
    • A watch run with nothing new or updated returns exactly one free no_data row that says so.
  • No contacts, no personal data: the firms' phone numbers and email addresses are never returned (the notice's ConsumerContact is not read into any row, and a phone number or email address inside a text becomes "[phone on the recall page]" or "[email on the recall page]"; the recall page in url has them). A firm whose name is, or may be, a person's (for example a sole trader trading under their own name) is left out of the recall's fields: firmNamesOmitted is true, the name is removed from every text, a text that still holds a word of it is null, and a title that named it becomes a neutral title such as "Recall: Table Lamps". When in doubt, the name is removed. The recall itself is returned and charged like any other.
  • One read per run: the window is read once (one request; a window over a year, one request per year) and every entry is matched in it. A recall that matches two entries is returned and charged once, under the first.
  • You are never charged for failed results: failed, no_data and unchanged rows are free.

Quick start

Bike helmet recalls of the last 90 days:

{ "queries": ["helmet"] }

Watch every new or updated recall (the first run is the baseline; later runs return only new and updated recalls; run it daily with an Apify schedule):

{ "stateName": "cpsc-recalls", "sinceDays": 30 }

Recalls of power banks, cribs and space heaters in the first half of 2026:

{ "queries": ["power bank", "crib", "space heater"], "recalledFrom": "2026-01-01", "recalledTo": "2026-06-30" }

Input

FieldTypeDefaultDescription
querieslist of strings— (prefilled helmet)Product words, one entry per line: the recalls whose title, product names, models, product types or description hold every word of the entry (word starts, any case: helmet finds "Helmets"). Empty: every recall of the window. Never a URL
sinceDaysinteger 1–3,65090Recalls dated in the last N days, today included
recalledFromdate YYYY-MM-DD—A fixed window instead: the first recall date (then sinceDays is not used)
recalledTodate YYYY-MM-DDtodayThe last recall date of the window
modewatch or export—Empty: watch when stateName is given, otherwise export. An explicit mode wins
stateNamestring— (prefilled cpsc-recalls)Watch list name. Watch mode without a name uses the list default
includeUnchangedbooleanfalseWatch: also return unchanged recalls (free)
maxItemsinteger 1–100,0001000Most charged recalls per run; in watch mode the rest come in the next run

Changing the product words of a watch list starts a new baseline; changing sinceDays does not (the window moves with each run).

Output

{
"status": "ok",
"attempts": 1,
"error": null,
"input": "helmet",
"mode": "export",
"watchList": null,
"dropReason": null,
"recallNumber": "26789",
"recallId": 10992,
"recallDate": "2026-09-24",
"lastPublishDate": "2026-09-24",
"title": "5Color Recalls Children’s Bicycle Helmet and Pads Sets Due to Risk of Serious Injury or Death from Head Injury; Violate Mandatory Standard for Bicycle Helmets",
"description": "This recall involves 5Color-branded bicycle helmet and pads sets. …",
"productNames": "5Color Children’s Bike Helmet and Pads Sets",
"productTypes": "Helmets & Helmet Accessories",
"models": null,
"numberOfUnits": "About 324",
"hazards": "The helmets in the recalled sets violate the mandatory safety standard for bicycle helmets … posing a serious risk of injury or death due to head injury.",
"injuries": "None reported",
"remedies": "Consumers should stop using the helmets immediately and contact 5Color for a full refund of the set. … email a photo of the destroyed helmet to [email on the recall page]. …",
"remedyOptions": "Refund",
"manufacturers": null,
"importers": null,
"distributors": null,
"retailers": "Hengqin Guangwei Consulting Co., Ltd., dba. 5Color, of China",
"whereSold": "Sold Online At: Amazon.com in May 2026 for between $25 and $26.",
"manufacturerCountries": "China",
"upcs": null,
"imageUrls": "https://cpsc.gov/s3fs-public/5Color1.jpg?VersionId=… | https://cpsc.gov/s3fs-public/5Color2.jpg?VersionId=…",
"jointRecallUrls": null,
"firmNamesOmitted": false,
"changeType": null,
"changedFields": null,
"previousValues": null,
"url": "https://cpsc.gov/Recalls/2026/5Color-Recalls-Childrens-Bicycle-Helmet-and-Pads-Sets-Due-to-Risk-of-Serious-Injury-or-Death-from-Head-Injury-Violate-Mandatory-Standard-for-Bicycle-Helmets",
"source": "CPSC Recalls API (U.S. Consumer Product Safety Commission). Source: CPSC (cpsc.gov), public information.",
"license": "Public information of a U.S. federal agency (CPSC): free to copy and distribute, credit CPSC",
"licenseUrl": "https://www.cpsc.gov/About-CPSC/Policies-Statements-and-Directives/Privacy-Policy",
"scrapedAt": "2026-10-04T18:40:00.000Z"
}
StatusMeaningCharged?
okA recall returnedExport: yes. Watch: baseline, new and changed yes; unchanged no
no_dataNo recall in the window matches the entry, or nothing new since the last runNo
failedAn invalid entry (a URL, no letters or digits), or no answer from CPSC after retries (error says why)No

The key-value store holds RUN_REPORT (counts, charged and free rows, stop reason) and, when something fails, the raw response without contacts (SNAPSHOT_*).

Output fields

Output fields

FieldTypeDescription
statusstring (or null)ok = recall returned (charged in export mode and for baseline, new and changed rows; free when unchanged); no_data = nothing to return (no recall in the window matches the entry, or nothing new since the last run) (free); failed = invalid input or no answer (free)
attemptsinteger (or null)Requests made for this row (retries included)
errorstring (or null)Why a row is no_data or failed; null on ok rows
inputstring (or null)The entry of product words this row came from ("all recalls" when no words were given), or the input that failed
modestring (or null)watch or export
watchListstring (or null)Watch list name (watch mode); null in export mode
dropReasonstring (or null)Always null for recalls: a firm name that may be a person's is left out of the recall's fields and the recall is kept (firmNamesOmitted)
recallNumberstring (or null)CPSC recall number
recallIdinteger (or null)CPSC recall database ID
recallDatestring (or null)Date of the recall notice (YYYY-MM-DD)
lastPublishDatestring (or null)Date the notice was last published or updated (YYYY-MM-DD)
titlestring (or null)Title of the recall notice (a neutral title when the original named a firm that may be a person)
descriptionstring (or null)What the recall covers: products, models, labels and dates
productNamesstring (or null)Recalled product names, joined with " / "
productTypesstring (or null)CPSC product types, joined with " / "
modelsstring (or null)Model numbers given in the product list, joined with " / " (often only in the description)
numberOfUnitsstring (or null)Number of units recalled, as CPSC writes it (e.g. "About 324")
hazardsstring (or null)The hazard, joined with " / " when there are several
injuriesstring (or null)Incidents and injuries reported (counts and kinds; no names)
remediesstring (or null)What consumers should do (contacts replaced by "[email on the recall page]" or "[phone on the recall page]")
remedyOptionsstring (or null)Refund, Replace, Repair …, joined with " / "
manufacturersstring (or null)Manufacturers as "
importersstring (or null)Importers as "
distributorsstring (or null)Distributors as "
retailersstring (or null)Retailer firms as "
whereSoldstring (or null)Where, when and for how much the product was sold
manufacturerCountriesstring (or null)Countries of manufacture, joined with " / "
upcsstring (or null)Product UPC codes, joined with " / "
imageUrlsstring (or null)Links to the recall's product photos on cpsc.gov, joined with " / "
jointRecallUrlsstring (or null)Pages of the same recall elsewhere (e.g. Health Canada), joined with " / "
firmNamesOmittedboolean (or null)True when a firm name that may be a person's was left out of every field of this recall (people filter)
changeTypestring (or null)Watch mode: baseline (first run of the list), new, changed or unchanged; null in export mode
changedFieldsstring (or null)Watch mode: the tracked fields that changed, comma-separated
previousValuesstring (or null)Watch mode: the changed fields' previous values, as JSON
urlstring (or null)The recall notice as CPSC links it, on cpsc.gov (it carries the firm's contacts); null when the record has no usable link (the recall is still returned)
sourcestring (or null)The data source and its credit line
licensestring (or null)The terms of the data
licenseUrlstring (or null)Where the terms are published
scrapedAtstring (or null)When the row was made (ISO 8601)

Pricing

Pay per event: one recall event per returned recall (export: every recall; watch: baseline, new and changed rows).

PlanPrice per recallPer 1,000 recalls
Free (no discount)$0.0015$1.50
Bronze$0.0013$1.30
Silver$0.00115$1.15
Gold (and Platinum, Diamond)$0.0010$1.00
  • Never charged: failed rows (an invalid entry, no answer from CPSC), no_data rows (no match, nothing new) and unchanged rows. You are never charged for failed results.
  • Apify also charges its small per-run start event. There are no usage fees on top, so the actor is eligible for x402 agent payments.

Use it from AI agents

One clear main input, queries (product words; empty for every recall); every row has status, error, recallNumber and scrapedAt, and url (the recall page) whenever CPSC gives one. Call it through the Apify API, the Apify MCP server (mouadapi/cpsc-product-recalls) or x402 agentic payments. Copy-paste call (your Apify token in place of YOUR_APIFY_TOKEN):

$curl -X POST "https://api.apify.com/v2/acts/mouadapi~cpsc-product-recalls/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" -H "Content-Type: application/json" -d '{"queries": ["power bank"], "sinceDays": 365}'
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('mouadapi/cpsc-product-recalls').call({ queries: ['crib', 'stroller'], stateName: 'baby-products' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Limits

  • One request at a time, at most one a second: CPSC publishes no rate limit, so this actor keeps well under any reasonable use. If the API answers HTTP 429, the run pauses 60, 120 and 240 seconds on the same connection, then stops with free failed rows. No other IP or proxy is ever tried.
  • The window is read by recall date: an update to a recall dated before the window is not seen. At most 5,000 recalls are read per run (CPSC publishes a few hundred a year).
  • Product words are matched in the recall's own text, by word starts (crib also finds "cribs"): a recall that names the product differently is not found. Leave queries empty to get every recall of the window.
  • US recalls by CPSC only (consumer products). Food, drugs, medical devices, cars and boats are recalled by other agencies (FDA, NHTSA, USCG) and are not here.

Known issues

  • CPSC's API sometimes answers with its own error ("Error retrieving Recalls: The underlying provider failed on Open.", HTTP 200; seen on 2 October 2026). The actor tries again after 1 and 2 seconds, then each entry is a free failed row that quotes it.
  • How names are handled: a firm trading under a person's name, and a firm name shaped like a person's name, are left out of the recall's fields (firmNamesOmitted: true; the test leans towards removing, so some company trading names are left out too). Such a recall can have a neutral title and null in a text field that repeated the name. RUN_REPORT counts these recalls (firmNamesOmitted) and the fields set to null (textFieldsNulled), never the names.
  • A few recalls have no usable page link in the API: such a recall is still returned (and charged), with url null. A relative cpsc.gov path gets the site's address, and a link on another host is kept as CPSC gives it. RUN_REPORT counts them (pageLinks).

FAQ

Does it include every CPSC recall? Every recall notice the CPSC Recalls API returns for the window. Use the recall page (url) for the firm's contact details and the full notice.

Why did a watch run return one no_data row? Nothing was new or updated since the last run of the watch list; the row says how many recalls were unchanged. It is free.

Data and licence

  • Source: the CPSC Recalls API (www.saferproducts.gov/RestWebServices), documented at https://www.cpsc.gov/Recalls/CPSC-Recalls-Application-Program-Interface-API-Information.
  • Terms: CPSC's Privacy and Security Notice, "Copyright": web page text "is public information. You may freely distribute, copy, or link to any of this information. However, the information may not be used in a way that states or implies CPSC endorsement. If you distribute, copy or link to any of this information, please credit CPSC." Every row credits CPSC in source.
  • This actor is not affiliated with, endorsed by or provided by the U.S. Consumer Product Safety Commission. It returns the recalls as published; always check the linked recall page before acting on it.