# FDA Recalls Monitor: Food, Drug and Device Recalls (`veridra/fda-recalls-monitor`) Actor

Get FDA recall and enforcement reports for food, drugs and medical devices from openFDA. Filter by date, Class I-III, status, firm, state or keyword.

- **URL**: https://apify.com/veridra/fda-recalls-monitor.md
- **Developed by:** [Veridra Computer Technology](https://apify.com/veridra) (community)
- **Categories:** Business, Developer tools, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.20 / 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.
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

### What does FDA Recalls Monitor do?

**FDA Recalls Monitor** pulls recall and enforcement reports for **food, drugs and medical devices** straight from the official openFDA API, so you can track new recalls without checking FDA pages by hand. It returns what the FDA publishes; it does not add or change recall decisions.

It collects data from **[openFDA (U.S. Food and Drug Administration)](https://open.fda.gov/apis/)** and returns clean, structured results you can download or pull through the **Apify API**.

### Why use FDA Recalls Monitor?

- **Retail and e-commerce compliance:** check whether products you sell, or their suppliers, appear in recent recalls.
- **Supplier and brand monitoring:** filter by recalling firm or keyword and schedule daily runs to catch new recalls early.
- **Safety, quality and regulatory teams:** pull Class I recalls for a period and export them to a spreadsheet or BI tool.
- **Research and journalism:** build datasets of recalls by reason, state, class or product type.
- **AI agents:** clean, consistent JSON with a verification link on every record, ready to use in agent workflows.
- Runs on the Apify platform: schedule runs, call it through the API, connect it to integrations, and get notified when a run fails.

### What data can FDA Recalls Monitor extract?

| Field | Type | Description |
| --- | --- | --- |
| `recallNumber` | string | FDA recall number, unique per recalled product. |
| `category` | string | Which enforcement report the record came from: food, drug or device. |
| `productType` | string | FDA product type as published (Food, Drugs, Devices). |
| `classification` | string | Recall class: Class I (most serious), Class II or Class III. |
| `status` | string | Recall status: Ongoing, Completed, Terminated or Pending. |
| `recallingFirm` | string | Company that initiated the recall. |
| `productDescription` | string | Description of the recalled product as published by the FDA. |
| `reasonForRecall` | string | Why the product was recalled. |
| `productQuantity` | string | Quantity of product affected, as published. |
| `codeInfo` | string | Lot numbers, codes and dates that identify the affected product. |
| `distributionPattern` | string | Where the product was distributed. |
| `voluntaryMandated` | string | Whether the recall was voluntary or FDA-mandated. |
| `initialFirmNotification` | string | How the firm first notified customers. |
| `recallInitiationDate` | string | Date the firm started the recall (YYYY-MM-DD). |
| `centerClassificationDate` | string | Date the FDA classified the recall (YYYY-MM-DD). |
| `reportDate` | string | Date the recall appeared in the FDA enforcement report (YYYY-MM-DD). |
| `terminationDate` | string | Date the recall was terminated, if it has been (YYYY-MM-DD). |
| `eventId` | string | FDA recall event ID; one event can cover several products. |
| `address` | string | Street address of the recalling firm. |
| `city` | string | City of the recalling firm. |
| `state` | string | State of the recalling firm. |
| `postalCode` | string | Postal code of the recalling firm. |
| `country` | string | Country of the recalling firm. |
| `brandNames` | array | Brand names from openFDA's product annotations, when available (mostly drugs). |
| `genericNames` | array | Generic names from openFDA's product annotations, when available. |
| `manufacturerNames` | array | Manufacturer names from openFDA's product annotations, when available. |
| `sourceUrl` | string | openFDA API link that returns this exact record, for verification. |
| `scrapedAt` | string | When this result was collected (UTC, ISO 8601). |

### How to use FDA Recalls Monitor

1. Open the actor and select **Try for free**.
2. Fill in **Product types**, **Days back**. The prefilled example works as a first test.
3. Set **Maximum results** to control how much data, and cost, a run produces.
4. Select **Start** and wait for the run to finish.
5. Download the results as JSON, CSV, Excel or HTML, or fetch them through the API.

### How much does it cost to use FDA Recalls Monitor?

You pay per result: **$6.00 per 1,000 results** ($0.006 each), plus Apify's small start fee of $0.0001 per run. For example, 1,000 results cost about $6.00. You can set a maximum cost per run in the run options, and the actor stops cleanly when it is reached.

Subscribers to Apify's paid plans pay less per result: 10% off on Bronze, 20% off on Silver and 30% off on Gold and higher plans.

### Get only new results

Turn on **Only new results** and schedule the actor (for example daily) to use it as a monitor: each run skips what earlier runs already returned, so you get a feed of new records and pay only for those. The first run returns everything that matches. The memory lives in your own Apify account; give runs the same **Monitor name** to share it when you change other inputs.

### Use it from AI agents

AI agents can find and run FDA Recalls Monitor as a tool through Apify's MCP server (mcp.apify.com) or the Apify API, and get the same structured results, billed per result. Without code, Apify's Zapier, Make and n8n integrations can start it and send each new result to a sheet, CRM or chat.

### Input

See the **Input** tab for every option. The main fields:

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `categories` | array | \["food", "drug", "device"] | Which FDA enforcement reports to search: food, drugs, medical devices, or any combination. |
| `daysBack` | integer | 30 | Look back this many days from today. Ignored when a start date is set. |
| `dateFrom` | string | "" | Only recalls on or after this date (YYYY-MM-DD). Leave empty to use Days back. |
| `dateTo` | string | "" | Only recalls on or before this date (YYYY-MM-DD). Leave empty for today. |
| `dateField` | string | "report_date" | Report date is when the FDA published the recall in its weekly enforcement report; initiation date is when the firm started the recall. |
| `classification` | array | \[] | Recall severity. Class I is the most serious. Leave empty for all classes. |
| `status` | array | \[] | Recall status. Leave empty for any status. |
| `keyword` | string | "" | Phrase to find in the product description or the reason for recall, for example peanut or listeria. |
| `recallingFirm` | string | "" | Company name, or part of it, as it appears in FDA records. |
| `state` | string | "" | Two-letter US state code of the recalling firm, for example CA. |
| `apiKey` | string | - | Your free openFDA API key raises the daily request limit. Most runs do not need one. |
| `maxResults` | integer | 1000 | Stop after this many results. Each result costs $0.006, so this also caps the cost of a run. Use 0 for no limit. Keep it low for a first test. |
| `onlyNew` | boolean | false | Monitoring mode: skip results this monitor returned in earlier runs, so a scheduled run returns, and bills, only what is new. The first run returns everything that matches. |
| `monitorName` | string | "" | Runs with the same name share one memory of returned results, even if you change other inputs. Leave empty to keep a separate memory for each distinct input. |

Example input:

```json
{
  "categories": [
    "food",
    "drug",
    "device"
  ],
  "daysBack": 60,
  "maxResults": 20
}
```

### Output

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. Example items:

```json
[
  {
    "recallNumber": "H-1407-2026",
    "category": "food",
    "productType": "Food",
    "classification": "Class I",
    "status": "Ongoing",
    "recallingFirm": "TODD'S SEEDS LLC",
    "productDescription": "Todd's Seeds Salad Sprouting Mixture - Broccoli, Mustard, Alfalfa and Cabbage, packaged in heat-sealed resealable bags in the following sizes: 1/4 lb., 1/2 lb., and 1 lb.",
    "reasonForRecall": "Products contain alfalfa seed recalled by the supplier and may be contaminated with E. coli and/or Salmonella (downstream recall)",
    "productQuantity": "37,481 retail units (TOTAL)",
    "codeInfo": "Lot No: TS-633-2 Use By: 12/31/2029",
    "distributionPattern": "Nationwide; through Amazon or direct to consumer",
    "voluntaryMandated": "Voluntary: Firm initiated",
    "initialFirmNotification": "E-Mail",
    "recallInitiationDate": "2026-09-11",
    "centerClassificationDate": "2026-09-30",
    "reportDate": "2026-10-07",
    "terminationDate": null,
    "eventId": "99887",
    "address": "1011 Volunteer Dr",
    "city": "Cookeville",
    "state": "TN",
    "postalCode": "38506-5026",
    "country": "United States",
    "brandNames": [],
    "genericNames": [],
    "manufacturerNames": [],
    "sourceUrl": "https://api.fda.gov/food/enforcement.json?search=recall_number:%22H-1407-2026%22",
    "scrapedAt": "2026-10-19T18:38:52+00:00"
  },
  {
    "recallNumber": "H-1402-2026",
    "category": "food",
    "productType": "Food",
    "classification": "Class II",
    "status": "Ongoing",
    "recallingFirm": "Galil Importing Corp",
    "productDescription": "Lior brand Cinnamon Ground Seasoning; 90g transparent plastic container; UPC 794711005484.",
    "reasonForRecall": "Product contains elevated levels of lead.",
    "productQuantity": "162 cases",
    "codeInfo": "GAP11304 printed on the side of the container under the ingredient line.",
    "distributionPattern": "NY, NJ, PA, TX, FL, IL",
    "voluntaryMandated": "Voluntary: Firm initiated",
    "initialFirmNotification": "Press Release",
    "recallInitiationDate": "2026-09-24",
    "centerClassificationDate": "2026-09-29",
    "reportDate": "2026-10-07",
    "terminationDate": null,
    "eventId": "99954",
    "address": "45 Gilpin Ave",
    "city": "Hauppauge",
    "state": "NY",
    "postalCode": "11788-4755",
    "country": "United States",
    "brandNames": [],
    "genericNames": [],
    "manufacturerNames": [],
    "sourceUrl": "https://api.fda.gov/food/enforcement.json?search=recall_number:%22H-1402-2026%22",
    "scrapedAt": "2026-10-19T18:38:52+00:00"
  }
]
```

### Tips

- Set Days back to 7 and schedule the actor weekly to get only new recalls; the FDA publishes enforcement reports weekly.
- Use Classification = Class I to focus on the most serious recalls.
- If you run many large queries, add your free openFDA API key under Advanced to raise the daily request limit.
- Schedule the actor to keep a dataset fresh, and use the API or integrations to send new results where you need them.

### FAQ, disclaimers, and support

#### Where does the data come from?

From openFDA (U.S. Food and Drug Administration) (api.fda.gov). Data is used under: U.S. federal government data (public domain under 17 U.S.C. 105), published by openFDA under its license at https://open.fda.gov/license/. See the source's terms: https://open.fda.gov/terms/

#### Is it legal to use this data?

This actor only collects publicly available data from openFDA (U.S. Food and Drug Administration) and does not collect personal data about private individuals. Check that your use complies with the source's terms and the laws that apply to you. This actor is not affiliated with or endorsed by openFDA (U.S. Food and Drug Administration).

#### How fresh is the data?

As fresh as openFDA: enforcement reports are published weekly, and openFDA updates its data shortly after. The actor queries the live API on every run.

#### Can I rely on this data for medical decisions?

No. openFDA states that its data should not be relied on to make decisions regarding medical care and that results should be assumed unvalidated. Always confirm with the FDA or the manufacturer.

#### What does each recall class mean?

Class I: a reasonable probability that the product will cause serious health problems or death. Class II: may cause temporary or medically reversible problems. Class III: unlikely to cause adverse health consequences.

#### Why do some fields come back empty?

The FDA does not fill every field for every recall, and product annotations (brand, generic and manufacturer names) exist mainly for drugs.

#### Something is not working

Open an issue in the **Issues** tab with your run link and we will look at it. For programmatic access, see the **API** tab.

# Changelog

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

# Actor input Schema

## `categories` (type: `array`):

Which FDA enforcement reports to search: food, drugs, medical devices, or any combination.

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

Look back this many days from today. Ignored when a start date is set.

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

Only recalls on or after this date (YYYY-MM-DD). Leave empty to use Days back.

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

Only recalls on or before this date (YYYY-MM-DD). Leave empty for today.

## `dateField` (type: `string`):

Report date is when the FDA published the recall in its weekly enforcement report; initiation date is when the firm started the recall.

## `classification` (type: `array`):

Recall severity. Class I is the most serious. Leave empty for all classes.

## `status` (type: `array`):

Recall status. Leave empty for any status.

## `keyword` (type: `string`):

Phrase to find in the product description or the reason for recall, for example peanut or listeria.

## `recallingFirm` (type: `string`):

Company name, or part of it, as it appears in FDA records.

## `state` (type: `string`):

Two-letter US state code of the recalling firm, for example CA.

## `apiKey` (type: `string`):

Your free openFDA API key raises the daily request limit. Most runs do not need one.

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

Stop after this many results. Each result costs $0.006, so this also caps the cost of a run. Use 0 for no limit. Keep it low for a first test.

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

Monitoring mode: skip results this monitor returned in earlier runs, so a scheduled run returns, and bills, only what is new. The first run returns everything that matches.

## `monitorName` (type: `string`):

Runs with the same name share one memory of returned results, even if you change other inputs. Leave empty to keep a separate memory for each distinct input.

## Actor input object example

```json
{
  "categories": [
    "food",
    "drug",
    "device"
  ],
  "daysBack": 60,
  "dateFrom": "",
  "dateTo": "",
  "dateField": "report_date",
  "classification": [],
  "status": [],
  "keyword": "",
  "recallingFirm": "",
  "state": "",
  "maxResults": 20,
  "onlyNew": false,
  "monitorName": ""
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing all results

# 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 = {
    "categories": [
        "food",
        "drug",
        "device"
    ],
    "daysBack": 60,
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("veridra/fda-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 = {
    "categories": [
        "food",
        "drug",
        "device",
    ],
    "daysBack": 60,
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("veridra/fda-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 '{
  "categories": [
    "food",
    "drug",
    "device"
  ],
  "daysBack": 60,
  "maxResults": 20
}' |
apify call veridra/fda-recalls-monitor --silent --output-dataset

```

## MCP server setup

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