# FDA Recall & Enforcement Delta Monitor (`apex-nexus/fda-recall-delta-monitor`) Actor

Watches the openFDA enforcement API (drugs, medical devices, food) and emits one alert per newly detected or newly amended enforcement action matching the watchlist since the last run. Public openFDA data only; deterministic; no inference.

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

## Pricing

from $5.00 / 1,000 recall alerts

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

## FDA Recall & Enforcement Delta Monitor

Monitors the openFDA enforcement API (drugs, medical devices, food) for a
user-maintained watchlist of firms / products / product types and emits one
dataset item (alert) per newly detected or newly amended enforcement action
since the last run — "free when nothing changes."

### Who it is for

Compliance, quality-assurance, supply-chain, pharmacy and hospital-procurement
teams obliged to track recalls affecting products they carry, stock, dispense
or regulate. Instead of manually re-polling openFDA enforcement reports on a
schedule, run this Actor on a cadence and it only alerts on what is new or
amended.

### What makes it different

Existing Apify Store coverage of FDA recalls is tiny and all pay-per-record:
mediapro-tools/fda-recalls-monitor ($0.002 per recall record + $0.01 per new
recall alert), thoob/fda-food-recall-feed ($0.005 per record), veridra/
fda-recalls-monitor ($0.05 per record), plus factpipe/fda-recalls-monitor,
nexgendata/fda-recall-monitor and cloud9_ai/openfda-drug-scraper. Every
listing has 0 reviews, none combine a watchlist with a per-query checkpoint
and delta alerts ("new since last run"), and pay-per-event pricing bills even
on empty scans.

This Actor keeps a watchlist and remembers what it already reported, so
repeat runs emit only genuinely new or amended enforcement actions — free
when nothing changes.

### Data source

Public openFDA enforcement data only, no API key required:

- https://api.fda.gov/drug/enforcement.json
- https://api.fda.gov/device/enforcement.json
- https://api.fda.gov/food/enforcement.json

No credentials, no proxies, no scraping of anti-bot pages, no commercial
inference (no LLMs) inside the product.

### Input

See actor/.actor/input_schema.json. All fields optional; the default input
is:

```json
{ "productType": "Drugs", "lookbackDays": 30, "maxResults": 25 }
```

- `productType`: `"Drugs"` (default), `"Medical Devices"` or `"Food"` — picks
  the openFDA enforcement domain.
- `watchlist`: optional array of firm/product strings matched
  case-insensitively against the recalling firm, product description, product
  type, recall number and recall reason. Empty means every enforcement action
  in the chosen domain is in scope.
- `lookbackDays` (1-365, default 30): how far back to look on the first run;
  repeat runs only emit actions newer than the last checked state.
- `maxResults` (1-200, default 25): cap on alerts emitted in a single run.

### Output

One dataset item per new or amended enforcement action:

```json
{
  "recallNumber": "D-0041-2027",
  "reportDate": "20261021",
  "productType": "Drugs",
  "endpoint": "https://api.fda.gov/drug/enforcement.json",
  "recallingFirm": "Houston Rx LLC",
  "productDescription": null,
  "reasonForRecall": null,
  "classification": null,
  "status": "Ongoing",
  "newSinceLastRun": true,
  "changeType": "new",
  "watchlistMatched": null,
  "source": null
}
```

`source` is `null` in emitted items — the Actor never guesses a value it did not receive from openFDA. The queried openFDA enforcement endpoint is carried in the `endpoint` field instead.

`changeType` is `"new"` for a previously unseen recall number and `"amended"`
for a known recall number whose published content changed. Every field is
`null` when it could not be parsed from openFDA — the Actor never guesses.

### Checkpoint / delta behaviour

State (the last-checked `reportDate` high-water mark plus a content
fingerprint per recall number) is kept in the Actor default key-value store.
On each run the Actor queries openFDA for `report_date >= checkpoint`,
sorted newest first, deduplicates by recall number, and only pushes
previously unseen or content-changed actions. Resetting the store re-emits
actions within the lookback window.

### Limits

- Max 50 watchlist terms, 200 alerts per run, 365-day lookback.
- Up to 1,000 openFDA records scanned per run (sorted newest first, stops at
  the checkpoint).
- Checkpoints persist per `productType` + watchlist in the Actor key-value
  store.

### Verification

Run `pytest actor/tests` before release (builder acceptance criterion).

# Actor input Schema

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

openFDA enforcement domain to poll: Drugs (default), Medical Devices or Food.

## `watchlist` (type: `array`):

Case-insensitive substring filter matched against the recalling firm, product description, product type, recall number and recall reason. Empty means every enforcement action in the domain is in scope.

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

How far back to look for enforcement actions on the first run; repeat runs only emit actions newer than the last checked state.

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

Cap the number of new/amended enforcement actions emitted in a single run.

## Actor input object example

```json
{
  "productType": "Drugs",
  "watchlist": [],
  "lookbackDays": 30,
  "maxResults": 25
}
```

# Actor output Schema

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

Dataset items filtered by the overview view defined in the dataset schema.

## `results` (type: `string`):

All dataset items emitted by the Actor run (new/amended enforcement actions).

# 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 = {
    "productType": "Drugs",
    "watchlist": [],
    "lookbackDays": 30,
    "maxResults": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("apex-nexus/fda-recall-delta-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 = {
    "productType": "Drugs",
    "watchlist": [],
    "lookbackDays": 30,
    "maxResults": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("apex-nexus/fda-recall-delta-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 '{
  "productType": "Drugs",
  "watchlist": [],
  "lookbackDays": 30,
  "maxResults": 25
}' |
apify call apex-nexus/fda-recall-delta-monitor --silent --output-dataset

```

## MCP server setup

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