# Product Recall API: EU Safety Gate, CPSC & FDA Recalls (`yourevenings/product-recalls`) Actor

Search and monitor product recalls from official EU Safety Gate, US CPSC and FDA feeds. Filter by keyword, brand, barcode or risk. One JSON schema, no API key.

- **URL**: https://apify.com/yourevenings/product-recalls.md
- **Developed by:** [Your Evenings](https://apify.com/yourevenings) (community)
- **Categories:** E-commerce, Business, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 1,000 recall record returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Product Recall API: EU Safety Gate, CPSC & FDA Recalls

![Product Recall API: EU Safety Gate, CPSC and FDA recalls](https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/3aJAAcuntBUjxtHMh-actor-kf5jcpweOARz4PH2x-p7jPNrzegX-product-recalls-512.png)

**Product Recall API** returns product recalls and safety alerts from three official public feeds as clean JSON rows in **one schema**, with **no API key needed**:

- **EU Safety Gate**: the European Commission's rapid alert system for dangerous non-food products (EU/EEA), read from its weekly-report XML feed.
- **US CPSC**: U.S. Consumer Product Safety Commission recalls, from the SaferProducts.gov recalls API.
- **US FDA**: food, drug and medical device recall enforcement reports, from openFDA.

Each row has the source's recall ID, dates, product name and description, brand, models, batch numbers and barcodes where published, the hazard, a normalised risk level, the remedy or measures taken, companies named by the source, countries, image links, the official link, and the source's licence and attribution. Filter by **keyword**, **brand or company**, **barcode** and **risk level**, or turn on **monitor mode** and schedule it to get only recalls you haven't had before.

Use it as a **product recall API** and **recall monitor**: search **CPSC recalls**, **EU Safety Gate** alerts and **FDA recalls** (openFDA enforcement reports for food, drugs and medical devices) in one schema, run a **barcode recall check** against your catalogue, or schedule a weekly **product recall monitor**. Export rows as CSV, JSON or Excel.

> **Not affiliated with the European Commission, CPSC or FDA.** This Actor is independent and is not affiliated with, endorsed by or sponsored by any of them. It reads their official public feeds. Each row carries the source's licence and attribution (see *Data sources and licences*).

### Why use this product recall API?

- **Official feeds, not scraped web pages.** Safety Gate comes from the Commission's own XML download, CPSC and FDA from their public APIs, so a redesign of a search website doesn't break it.
- **One schema for three sources.** The same field names and one `riskLevel` scale (`serious`, `moderate`, `low`, `other`, `unknown`), with each source's own wording kept in `riskLevelDetail` and source-specific fields in `extra`.
- **Barcode matching that works across regions.** Digits are compared, so a 12-digit UPC matches the same 13-digit EAN with a leading 0.
- **Only new recalls when you want them.** Monitor mode remembers which recall IDs it has returned and returns only new ones. A run with nothing new gets a free `no_new_recalls` row.
- **Clear answers when nothing is found.** Each source with nothing in range gets a free `no_matches` row, a source that fails gets a free `source_error` row while the others carry on, and a run that stops early says why.
- **You choose how much comes back.** `maxResults` caps the whole run, `maxResultsPerSource` caps each source, and the Actor stops before your run's maximum cost.
- **Product and company data only.** Consumer contact fields are never copied, and emails and phone numbers are removed from free text.
- **Polite to the sources.** Requests are paced per source, retried after rate-limit or server errors, and identify the Actor.

### How do I search product recalls? Quick start

Press **Start** with the prefilled input, or paste this into the **JSON** view of the Input tab. It finds chargers and power banks recalled in the last 14 days, at most 3 per source.

```json
{
  "publishedWithinDays": 14,
  "keywords": ["charger", "power bank"],
  "maxResultsPerSource": 3
}
```

In our test run on 30 October 2026 it returned 4 recalls (3 from EU Safety Gate, 1 from CPSC) and a free `no_matches` row for each FDA dataset.

EU and CPSC recalls listing one barcode in the last year:

```json
{
  "sources": ["EU_SAFETY_GATE", "US_CPSC"],
  "publishedWithinDays": 365,
  "barcodes": ["5907481111094"],
  "maxSafetyGateReports": 52
}
```

Weekly monitor of FDA food recalls mentioning peanut or milk:

```json
{
  "sources": ["US_FDA"],
  "fdaProductTypes": ["food"],
  "keywords": ["peanut", "milk"],
  "publishedWithinDays": 14,
  "monitorMode": true
}
```

### Who it's for

- **Retailers, marketplaces and importers** checking their catalogue against new recalls by brand, barcode or keyword.
- **Product safety, compliance and quality teams** watching their product categories across the EU and US.
- **Data teams and journalists** who want one table of recalls from three regulators.

### What can I do with product recall data?

1. **Catalogue check.** Pass your barcodes and get any recall that lists them.
2. **Weekly safety digest.** Schedule monitor mode with your keywords and get only new recalls each week.
3. **Brand watch.** Follow recalls naming your brands or suppliers.
4. **Category research.** Pull every serious-risk alert in a category over a date range.

### What does the recall data look like?

The rows from the Quick start input (run on 30 October 2026), shortened:

| Source | Recall ID | Published | Risk level | Title | Barcodes |
|---|---|---|---|---|---|
| EU_SAFETY_GATE | SR/03027/26 | 2026-10-30 | serious | Football with LED lights, Coolstuff, LED Football | |
| EU_SAFETY_GATE | SR/03069/26 | 2026-10-30 | serious | Charger, vhbw, Power Supply | 250667382315 |
| EU_SAFETY_GATE | SR/03044/26 | 2026-10-30 | serious | USB charger, X-start, Dual USB-C Charger | 5907481111094 |
| US_CPSC | 27056 | 2026-10-29 | unknown | HAIARA Power Banks Recalled Due to Risk of Serious Injury or Death from Fire and Burn Hazards… | |

### Input: how do I filter recalls?

Every field is optional. Leave everything empty for all recalls from all three sources in the last 7 days (up to 50 rows).

#### Sources (`sources`)

`EU_SAFETY_GATE`, `US_CPSC`, `US_FDA`. All three by default.

#### Published in the last N days (`publishedWithinDays`)

Recalls published in the last N days, today included. Default 7, up to 3,660. EU Safety Gate publishes weekly reports (usually Fridays); CPSC is filtered by recall date and FDA by report date.

#### Published since (`publishedSince`)

Optional start date (`YYYY-MM-DD`) instead of the last N days. At most 3,660 days per run.

#### Published until (`publishedUntil`)

Optional end date (`YYYY-MM-DD`). Default today.

#### Keywords (`keywords`)

Any of these words in the title, product name or description, category, hazard, brand, model or company name. Case and accents are ignored; words are matched from their start, so `lead` doesn't match "pleaded".

#### Brands or companies (`brands`)

Any of these brands or companies (brand, company names, title or product name).

#### Barcodes (UPC / EAN / GTIN) (`barcodes`)

Any of these UPC / EAN / GTIN codes, compared as digits (UPC-A matches its EAN-13 form). Only recalls that publish a barcode can match.

#### Risk levels (`riskLevels`)

Only these normalised risk levels: `serious`, `moderate`, `low`, `other`, `unknown`. CPSC doesn't grade recalls, so CPSC rows are `unknown`.

#### FDA product types (`fdaProductTypes`)

`food`, `drug`, `device`. All three by default.

#### Max recalls (whole run) (`maxResults`)

Most recall rows per run. Default 50; 0 means no limit.

#### Max recalls per source (`maxResultsPerSource`)

Most recall rows per source. Default 0 (no cap). Sources are read in the order EU Safety Gate, CPSC, FDA, so set this if you want rows from every source.

#### Max Safety Gate weekly reports (`maxSafetyGateReports`)

Most Safety Gate weekly reports read per run, newest first. Default 8, up to 260.

#### Monitor mode (`monitorMode`)

Return only recalls you haven't had before. See *How do I monitor new product recalls?* below.

#### Return recalls on the first monitor run (`emitBaselineOnFirstRun`)

Default on. See *How do I monitor new product recalls?* below.

#### Monitor state store name (`stateStoreName`)

Named key-value store for monitor state. Use a different name per watch list. See *How do I monitor new product recalls?* below.

### Output: what fields does each recall row have?

Every row has `rowType`. A **recall** row (`recall`) has `source`, `sourceName`, `region`, `recallId`, `recallDate`, `publishedDate`, `title`, `productName`, `productDescription`, `productCategory`, `productType`, `brands`, `models`, `batchNumbers`, `barcodes`, `hazard`, `hazardTypes`, `riskLevel`, `riskLevelDetail`, `remedy`, `recallStatus`, `companies` (`name`, `role`), `soldAt`, `countries` (`notifying`, `origin`, `distribution`), `units`, `images`, `officialUrl`, `extra`, `licence`, `licenceUrl`, `attribution`, `disclaimer`, `changeType` and `retrievedAt`. Fields a source doesn't publish are `null` or empty. Values shortened:

```json
{
  "rowType": "recall",
  "source": "EU_SAFETY_GATE",
  "recallId": "SR/03044/26",
  "publishedDate": "2026-10-30",
  "title": "USB charger, X-start, Dual USB-C Charger",
  "brands": ["X-start"],
  "barcodes": ["5907481111094"],
  "productCategory": "Electrical appliances and equipment",
  "hazard": "The product lacks adequate insulation between the primary and secondary circuits. The USB ports and the connected cable can become live under mains voltage. …",
  "riskLevel": "serious",
  "riskLevelDetail": "Serious risk",
  "remedy": "Recall of the product from end users, by distributor, from 01/09/2026; …",
  "countries": { "notifying": "Hungary", "origin": ["People's Republic of China"], "distribution": null },
  "officialUrl": "https://ec.europa.eu/safety-gate-alerts/screen/webReport/alertDetail/10119402",
  "extra": { "weeklyReport": "Report-2026-43" },
  "licence": "CC0 1.0 (the weekly-report XML distribution, as listed on data.europa.eu); …"
}
```

How the sources map:

| Field | EU Safety Gate | US CPSC | US FDA |
|---|---|---|---|
| `recallId` | Case number | Recall number | Recall number |
| `publishedDate` | Weekly report date | Last published date | Enforcement report date |
| `riskLevel` | Serious risk → `serious`, Other risk levels → `other` | `unknown` (not graded) | Class I → `serious`, II → `moderate`, III → `low` |
| `companies` | none published | manufacturers, importers, distributors | recalling company (FDA's `recalling_firm` field) with city, state and country |
| `barcodes` | as published | product UPCs, plus codes in the description when it mentions UPC/EAN/GTIN | codes in the product or code text when it mentions UPC/EAN/GTIN/NDC/UDI |
| `officialUrl` | alert page | recall page | openFDA API query for the recall number (FDA enforcement reports have no per-recall web page) |

`extra.onlineListings` (Safety Gate) lists marketplace names and listing IDs where the product was found online.

**Status** rows (`status`, free): `no_matches`, `no_new_recalls`, `scan_limit`, `source_error` or `budget_reached`, each with a plain-English `message`.

The **SUMMARY** record in the default key-value store lists the input, rows per source, status counts, request counts and each source's licence, attribution and disclaimer. The dataset has views for Overview, Monitor: new recalls, and Status rows.

### How do I monitor new product recalls?

Set `monitorMode` to `true` and schedule a saved task with your filters. The Actor remembers each recall ID it returns in the named key-value store `stateStoreName` (for 400 days) and, on later runs, returns only recalls it hasn't returned before (`changeType: "new"`). Updates to a recall already returned are not re-sent.

- `emitBaselineOnFirstRun` (default `true`) returns current matches on the first run. Set it to `false` to remember them silently, without charge, and get only later recalls.
- Use a different `stateStoreName` for each watch list.
- Set the date window to cover the gap between runs plus a margin (for example 14 days for a weekly run).

### How much does it cost to search product recalls?

Pay per event:

| Event | Price |
|---|---|
| Recall record returned | $0.002 |
| Alert run with new recalls (monitor mode only, once per run that returns at least one) | $0.01 |
| Actor start | $0.00005 |

Higher Apify plans get lower prices (shown on the Pricing tab). Status rows, the SUMMARY record and monitor runs with nothing new are free of record and alert charges. Set **Maximum cost per run** in the run options: the Actor stops before going over it and adds a free `budget_reached` row.

### Data sources, licences and attribution

Every row carries its source's `licence`, `licenceUrl` and `attribution`. Rows are normalised by this Actor (field names, risk levels, dates, contact details removed), so they are modified from the original records. Product photos are linked, not copied; they may carry third-party rights.

| Source | Feed | Licence or terms | Attribution (in every row's `attribution`) |
|---|---|---|---|
| EU Safety Gate | [Weekly-report XML](https://ec.europa.eu/safety-gate-alerts/api/download/weeklyReport/list/xml/en) ([data.europa.eu dataset](https://data.europa.eu/data/datasets/rapex-rapid-alert-system-non-food)) | [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/) for the XML distribution; [Commission reuse notice (Decision 2011/833/EU)](https://eur-lex.europa.eu/eli/dec/2011/833/oj) | Alerts from the Rapid Alert System for dangerous non-food products, published free of charge on the Safety Gate website (https://ec.europa.eu/safety-gate-alerts) © European Union, 2005 – 2026 |
| US CPSC | [Recalls API](https://www.cpsc.gov/Recalls/CPSC-Recalls-Application-Program-Interface-API-Information) | US federal government work, public domain in the US (17 U.S.C. § 105) | Source: U.S. Consumer Product Safety Commission recalls (cpsc.gov). Not endorsed by CPSC. |
| US FDA | [openFDA enforcement reports](https://open.fda.gov/apis/food/enforcement/) | [openFDA licence (CC0)](https://open.fda.gov/license/) and [openFDA terms](https://open.fda.gov/terms/) | Data provided by the U.S. Food and Drug Administration (https://open.fda.gov). Not endorsed by FDA. |

#### openFDA disclaimer

openFDA asks that its disclaimer goes with its data. Every FDA row carries it in `disclaimer`:

> Do not rely on openFDA to make decisions regarding medical care. While we make every effort to ensure that data is accurate, you should assume all results are unvalidated. We may limit or otherwise restrict your access to the API in line with our Terms of Service.

### Product and company data only

Rows hold product and company data. CPSC's consumer contact field is never copied, recalling companies' street addresses and postcodes are not copied from FDA records, and emails and phone numbers are removed from free text. Company names are returned as the source publishes them; a small recalling company can be a sole trader trading under its own name.

### What are the limits?

- **Sources:** EU Safety Gate (non-food), US CPSC and US FDA only. UK and EU food alerts are not included.
- **Date range:** up to 3,660 days per run. EU Safety Gate is read one weekly report at a time (`maxSafetyGateReports`, default 8, up to 260), and a free `scan_limit` row says when older reports in the range were not read.
- **FDA:** at most 2,000 records per FDA dataset per run outside monitor mode (4,000 in monitor mode); keyword and brand filters are applied by openFDA first, so filtered runs read far fewer.
- **Freshness:** Safety Gate publishes weekly reports (usually Fridays) and FDA adds enforcement reports weekly, so the newest days can be empty for those sources. CPSC publishes recalls as they are announced.
- **Pacing:** CPSC and FDA are called at most once a second and Safety Gate once every 2 seconds.

### Use the product recall API from code, spreadsheets or an AI agent

Run it with the Apify API or client libraries, schedule it, or connect it to Make, Zapier, Google Sheets or webhooks through Apify integrations. AI agents can call it through Apify's MCP server.

The examples below return at most 10 recalls (plus any free status rows) and set a maximum cost of $0.05 for the run, so trying them costs a few cents at most. Read your API token from an environment variable (`APIFY_TOKEN`) rather than pasting it into code.

#### JavaScript (Node.js)

```js
// npm install apify-client
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('yourevenings/product-recalls').call(
  {
    "publishedWithinDays": 14,
    "keywords": [
      "charger",
      "power bank"
    ],
    "maxResults": 10
  },
  { maxTotalChargeUsd: 0.05 },
);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
## pip install "apify-client>=3"
import os
from decimal import Decimal
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("yourevenings/product-recalls").call(
    run_input={
        "publishedWithinDays": 14,
        "keywords": [
            "charger",
            "power bank"
        ],
        "maxResults": 10
    },
    max_total_charge_usd=Decimal("0.05"),
)
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)
```

#### HTTP API (cURL)

```bash
curl -X POST "https://api.apify.com/v2/acts/yourevenings~product-recalls/run-sync-get-dataset-items?maxTotalChargeUsd=0.05" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"publishedWithinDays": 14, "keywords": ["charger", "power bank"], "maxResults": 10}'
```

#### AI agents (MCP)

Add Apify's MCP server with just this Actor as a tool. On first connection your browser opens so you can sign in to Apify and approve access.

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=yourevenings/product-recalls"
    }
  }
}
```

### FAQ

**Why is the CPSC risk level `unknown`?** CPSC doesn't grade recalls by risk. Read the `hazard` field, or filter by keyword.

**Why did FDA return nothing for the last few days?** FDA adds enforcement reports weekly, so a short date window can fall between two updates. The `no_matches` row says so; widen the window to 14 days or more.

**What happens if openFDA limits requests?** openFDA is used without a key, and its limits are counted per IP address, which can be shared on Apify. If openFDA answers with a rate-limit error after retries, you get a free `source_error` row for FDA and the other sources carry on.

**Does a barcode always find a recall?** Only when the source publishes the barcode. Safety Gate and CPSC often do; FDA only when the code is written in the product or code text.

**How do I get recalls from one source only?** Set `sources` to the feeds you want, for example `["US_CPSC"]`. For FDA, `fdaProductTypes` picks food, drug or device recalls.

**Can I add another source?** Open an issue with the source you need. A source is added only if it publishes official recall data that allows reuse without a login.

### Feedback

Found a problem or need a source? Open an issue on the Issues tab.

# Changelog

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

# Actor input Schema

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

Which official feeds to read. All three by default.

## `publishedWithinDays` (type: `integer`):

Recalls published in the last N days, today included. Ignored when <b>Published since</b> is set. EU Safety Gate publishes weekly reports (usually Fridays); CPSC is filtered by recall date and FDA by report date.

## `publishedSince` (type: `string`):

Optional start date. Overrides <b>Published in the last N days</b>. At most 3,660 days per run.

## `publishedUntil` (type: `string`):

Optional end date. Default today.

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

Return recalls whose title, product, category, hazard, brand, model or company contains any of these words (case- and accent-insensitive, matched at the start of a word). Empty = all recalls in the date range.

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

Return recalls naming any of these brands or companies (brand, company names, title or product name).

## `barcodes` (type: `array`):

Return recalls listing any of these barcodes. Digits only are compared, and a 12-digit UPC matches the same 13-digit EAN with a leading 0. Only recalls that publish a barcode can match: Safety Gate and CPSC often do, FDA only when the barcode is in the product text.

## `riskLevels` (type: `array`):

Only return recalls with these normalised risk levels. Empty = all. CPSC does not grade recalls, so CPSC rows are always <code>unknown</code>.

## `fdaProductTypes` (type: `array`):

Which openFDA recall enforcement datasets to read.

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

Stop after this many recall rows across all sources. 0 means no limit. You are charged per recall row returned.

## `maxResultsPerSource` (type: `integer`):

Optional cap per source so one busy feed doesn't use up the whole run. 0 means no cap.

## `maxSafetyGateReports` (type: `integer`):

EU Safety Gate is read one weekly report at a time, newest first. Reports beyond this number in the date range are not read and you get a free <code>scan_limit</code> row.

## `monitorMode` (type: `boolean`):

Remember each recall ID returned and, on later runs, return only recalls you haven't had before. Schedule it (for example weekly) with the same filters. A run with nothing new gets a free <code>no_new_recalls</code> row.

## `emitBaselineOnFirstRun` (type: `boolean`):

Off: the first monitor run only records what exists (no rows, no charges).

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

Named key-value store for monitor state. Use a different name per watch list.

## Actor input object example

```json
{
  "sources": [
    "EU_SAFETY_GATE",
    "US_CPSC",
    "US_FDA"
  ],
  "publishedWithinDays": 14,
  "keywords": [
    "charger",
    "power bank"
  ],
  "fdaProductTypes": [
    "food",
    "drug",
    "device"
  ],
  "maxResults": 50,
  "maxResultsPerSource": 3,
  "maxSafetyGateReports": 8,
  "monitorMode": false,
  "emitBaselineOnFirstRun": true,
  "stateStoreName": "product-recalls-monitor"
}
```

# Actor output Schema

## `overview` (type: `string`):

Overview view of the dataset.

## `changes` (type: `string`):

Monitor: new recalls view of the dataset.

## `status` (type: `string`):

Status rows (free) view of the dataset.

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

SUMMARY record: input, counts per source, status rows, request counts and timings, and each source's licence, attribution and disclaimer.

# 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": [
        "EU_SAFETY_GATE",
        "US_CPSC",
        "US_FDA"
    ],
    "publishedWithinDays": 14,
    "keywords": [
        "charger",
        "power bank"
    ],
    "maxResults": 50,
    "maxResultsPerSource": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("yourevenings/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": [
        "EU_SAFETY_GATE",
        "US_CPSC",
        "US_FDA",
    ],
    "publishedWithinDays": 14,
    "keywords": [
        "charger",
        "power bank",
    ],
    "maxResults": 50,
    "maxResultsPerSource": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("yourevenings/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": [
    "EU_SAFETY_GATE",
    "US_CPSC",
    "US_FDA"
  ],
  "publishedWithinDays": 14,
  "keywords": [
    "charger",
    "power bank"
  ],
  "maxResults": 50,
  "maxResultsPerSource": 3
}' |
apify call yourevenings/product-recalls --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,yourevenings/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/kf5jcpweOARz4PH2x/builds/Pz90YF44Ipvv3ZLvb/openapi.json
