# FDA Recall Monitor — Drugs, Devices & Food (`businessquik/fda-recall-monitor`) Actor

Watch FDA enforcement reports for the products you care about. Diff-based: each run reports only NEW recalls since the last check. 'Nothing new' is the product.

- **URL**: https://apify.com/businessquik/fda-recall-monitor.md
- **Developed by:** [Carlos Garcia](https://apify.com/businessquik) (community)
- **Categories:** Automation, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.05 / actor start

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/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

## FDA Recall Monitor — Drugs, Devices & Food

Schedule this Actor and stop checking FDA feeds by hand. It watches official FDA enforcement reports (openFDA) for the products you care about and — this is the point — **reports only what's new since your last check**. State is remembered between runs.

### Why diff-based beats a data dump

Raw recall data is free and several tools dump it. What costs you time is *watching* it. This Actor remembers every recall it has already shown you (per named monitor state), so a scheduled daily run gives you one of two answers:

- **"N new recalls"** — each as a full dataset record, Class I first
- **"Nothing new"** — a run-summary row confirming the check happened

Wire the run summary to an email/Slack alert in the Console and you have a recall desk for cents a day.

### Input

| Field | Description |
|---|---|
| `sectors` | `drug`, `device`, `food` — any combination |
| `searchTerms` | Matched against product descriptions ("insulin", "catheter", "infant formula"). Empty = whole sector |
| `classifications` | `Class I` (serious), `Class II`, `Class III` |
| `lookbackDays` | First-run scan window (default 90). Later runs diff against remembered state |
| `stateName` | Name your monitor — run several independent monitors side by side |
| `apiKey` | Optional free openFDA key for higher rate limits |

### Output record (new recall)

```json
{
  "is_new": true,
  "sector": "device",
  "recall_number": "Z-1544-2026",
  "classification": "Class II",
  "report_date": "20260318",
  "recalling_firm": "…",
  "product_description": "…",
  "reason_for_recall": "…",
  "distribution_pattern": "Nationwide",
  "code_info": "Lot …"
}
```

Every run also emits one `run_summary` row with `new_recalls`, `class_1_new`, and `total_tracked` counts — that's your alert hook and your audit trail.

### Who this is for

- **Med-device & pharma quality/regulatory teams** — competitor and component surveillance
- **Hospital supply chain & GPOs** — is anything we buy on this week's list?
- **Food safety teams & retailers** — ingredient and supplier watch
- **Litigation researchers & investors** — early signal on enforcement activity

### Suggested setup

Daily schedule, one monitor per product family, alert on `class_1_new > 0` and on run failure. First run seeds state (larger output); every run after is pure diff.

### Notes

- Data source: official openFDA enforcement API — public, no login, built for programmatic reuse.
- openFDA data lags FDA press releases by days in some cases; this is a monitoring layer, not an emergency-broadcast system.
- Output is provided as-is and is not regulatory or legal advice.

### Pricing

| Event | Price |
|---|---|
| Monitoring check (per run) | $0.05 |
| Per new recall surfaced | $0.02 |

A daily monitor that surfaces ~10 new recalls a month: **~$1.70/month**.

### FAQ

**How is this different from just checking the FDA website?**
State. The monitor remembers every recall it has shown you (per named monitor), so a scheduled run reports only what's new. The FDA site makes you re-read everything.

**How fresh is the data?**
It reads the official openFDA enforcement API, which can lag FDA press announcements by days. Treat it as reliable surveillance, not an emergency broadcast.

**Can I run separate monitors for different product lines?**
Yes — set a different `stateName` per monitor. Each remembers its own history.

**What should I schedule?**
Daily is typical. Alert on the run summary's `class_1_new > 0` for serious recalls, or on any `new_recalls > 0`.

**Do I need an API key?**
No. An optional free openFDA key raises rate limits for heavy use.

**What does it cost to run daily?**
\~$1.50/month for the checks plus $0.02 per new recall surfaced — a monitor surfacing 10 recalls/month costs about $1.70.

### Changelog

- **2026-08-22** — Demo mode for empty input; run summaries hardened for alerting.
- **2026-08-20** — Launch: diff-based monitoring across drug/device/food with named persistent monitors.

***

### More tools by Businessquik

Verified data tools built on official and public-mandate sources — no logins, no gray areas, no fragile scrapers:

- [Bank Statement Extractor — PDF statements to reconciled CSV/JSON](https://apify.com/businessquik/bank-statement-extractor)
- [Hospital Price File Normalizer — comparable hospital prices from CMS MRFs](https://apify.com/businessquik/hospital-mrf-normalizer)
- [Patent Signals — filing velocity, new entrants & expiry intel](https://apify.com/businessquik/patent-signals)
- [US Location Profile — economy, labor & weather in one call](https://apify.com/businessquik/location-profile)

**Support:** open an issue on this Actor's Issues tab — layout/format reports are usually fixed within days. Describe the *shape* of your file or query; never post real bank statements or sensitive data.

# Actor input Schema

## `sectors` (type: `array`):

Which FDA enforcement feeds to check.

## `searchTerms` (type: `array`):

Terms matched against product descriptions (e.g. "insulin", "catheter", "infant formula"). Empty = ALL recalls in the sector (high volume).

## `classifications` (type: `array`):

Class I = serious risk of harm; Class II = temporary/reversible; Class III = unlikely harm. Empty = all.

## `lookbackDays` (type: `integer`):

How far back to scan on the FIRST run (later runs diff against remembered state).

## `stateName` (type: `string`):

Name of the storage that remembers which recalls you've already seen. Use different names to run independent monitors.

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

Free key from open.fda.gov raises rate limits. Not required for typical monitoring.

## Actor input object example

```json
{
  "sectors": [
    "drug",
    "device"
  ],
  "searchTerms": [],
  "lookbackDays": 90,
  "stateName": "fda-recall-monitor-state"
}
```

# Actor output Schema

## `results` (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 = {
    "searchTerms": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("businessquik/fda-recall-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 = { "searchTerms": [] }

# Run the Actor and wait for it to finish
run = client.actor("businessquik/fda-recall-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 '{
  "searchTerms": []
}' |
apify call businessquik/fda-recall-monitor --silent --output-dataset

```

## MCP server setup

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