openFDA Enforcement (Recall) Monitor avatar

openFDA Enforcement (Recall) Monitor

Pricing

from $10.00 / 1,000 recall returneds

Go to Apify Store
openFDA Enforcement (Recall) Monitor

openFDA Enforcement (Recall) Monitor

Monitor FDA recall (enforcement) reports across drug, device and food. One normalized record per recall (number, Class I/II/III, status, firm, product, reason, dates), with type/class filters, a new-since-last-run mode, and change-detection flagging classification escalations. openFDA, CC0.

Pricing

from $10.00 / 1,000 recall returneds

Rating

0.0

(0)

Developer

ByteHaven Studios

ByteHaven Studios

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Monitor FDA recall (enforcement) reports across drug, device and food categories in a single run. Give it categories, classifications and/or a date window; it returns one normalized record per recall, with a new-since-last-run mode and change-detection that flags classification escalations (Class III→II→I) and termination events.

Clean REST/JSON — no browser, no proxy, no login, no API key required (an optional free key raises rate limits). Data source: FDA openFDA (U.S. public domain, CC0 1.0).

Status: scaffold (v0.1, in progress). This Actor is being built in slices; the runtime logic (src/openfda.js, src/filters.js, src/main.js) is landing incrementally. This README documents the intended product surface. See CHANGELOG.md for what's implemented so far.


What it does

For each run it queries the openFDA enforcement endpoints — /drug/enforcement.json, /device/enforcement.json, /food/enforcement.json — for the categories you select, filtered by a report_date window, normalizes all three schemas into one record shape, applies your filters, dedupes on recall_number, and pushes one dataset item per recall.

  • Recent recalls (default): recalls whose report_date is on/after reportedSince (or a recent trailing window if unset), across every selected category in one pass.
  • Cross-category edge: watching drug and device and food recalls together — normalized to one schema — is the moat. Incumbents grab the glamorous drug-label / adverse-event endpoints and leave the boring, weekly-lagged enforcement feeds un-normalized and un-joined.
  • New-recall monitor: monitorNewOnly persists the set of already-reported recall_numbers (in the Actor's key-value store) and, on the next scheduled run, returns only recalls not seen before.
  • Change-detection: detectChanges persists each recall's prior classification and status and, on later runs, flags recalls that escalated (Class III→II→I) or whose status changed (e.g. On-GoingTerminated). Change-detection over a weekly-refreshed corpus nobody else timestamps for first-seen.
  • Filters: by recallCategories (drug / device / food), classifications (Class I / II / III), and statuses.

Inputs

InputTypeNotes
recallCategoriesstring[]drug, device, food. Empty = all three
classificationsstring[]Class I, Class II, Class III. Empty = all classes
statusesstring[]e.g. On-Going, Completed, Terminated. Empty = all statuses
reportedSincestringYYYY-MM-DD — report_date on/after. Empty = recent trailing window
monitorNewOnlybooleanReturn only recall_numbers not seen in a previous run
detectChangesbooleanFlag classification escalations + status changes vs stored prior state (default on)
fieldsstring[]Override the kept output fields (empty = sensible default set)
maxResultsintegerCap total recalls returned (0 = no cap)
apiKeystringOptional openFDA api_key (raises daily rate limit; not required)
proxyConfigurationobjectOptional; the API is open and needs no proxy. Default: none

Output — one record per recall

{
"recall_number": "D-1234-2026",
"category": "drug",
"status": "Ongoing",
"classification": "Class II",
"product_type": "Drugs",
"product_description": "Atorvastatin Calcium Tablets, 40 mg, 90-count bottle",
"reason_for_recall": "Failed dissolution specifications at the 12-month stability time point.",
"recalling_firm": "Example Pharma Inc.",
"city": "Trenton",
"state": "NJ",
"country": "United States",
"voluntary_mandated": "Voluntary: Firm initiated",
"initial_firm_notification": "Letter",
"event_id": "90210",
"recall_initiation_date": "2026-06-15",
"center_classification_date": "2026-07-01",
"report_date": "2026-07-08",
"termination_date": null,
"isNew": true,
"change": null,
"fetchedAt": "2026-07-10T14:00:00.000Z"
}

category marks which endpoint the recall came from (drug / device / food). Date fields are the API's YYYYMMDD strings parsed best-effort to YYYY-MM-DD (null when absent). isNew is true when a recall_number was not seen in a previous run (only meaningful with monitorNewOnly). change is an object when detectChanges is on and the recall's classification escalated or status changed since a prior run — e.g. { "type": "classification-escalation", "from": "Class III", "to": "Class II" } or { "type": "status-change", "from": "Ongoing", "to": "Terminated" } — otherwise null.

Control records (not charged)

Two non-recall records may be pushed to signal run state. Neither triggers a recall-returned charge:

RecordWhenShape
_noDataThe API returned no recalls for the requested filters/window{ "_noData": true, "filters": {...}, "message": "...", "fetchedAt": "..." }
_errorThe fetch failed after retries, or normalization threw{ "_error": true, "filters": {...}, "message": "...", "fetchedAt": "..." }

_noData keeps a zero-result run green and auditable rather than pushing a silent empty dataset.

Pricing (pay-per-event)

One recall-returned event is charged per record pushed to the dataset. Cost scales with results, not runtime. Use recallCategories / classifications / statuses / maxResults / monitorNewOnly to keep spend proportional to signal. (Live price shown on the Store page; see docs/PRICING.md.)

Data source & attribution

openFDA content and data are public domain under a Creative Commons CC0 1.0 Universal dedication — free to copy, modify and redistribute, including commercially, without asking permission. No key and no attribution are required; we credit the FDA / openFDA as a courtesy. Full compliance record: ./COMPLIANCE.md.

openFDA is a research/informational service; recall data may be incomplete or lag the FDA's own systems and is not a substitute for the official recall notices. This Actor relays the data as published; it does not certify accuracy.

Maintenance notes

  • Three schemas drift independently — drug / device / food enforcement records carry overlapping-but-not-identical fields; the normalizer is defensive and the kept-field set is documented.
  • YYYYMMDD string dates — parsed best-effort to YYYY-MM-DD; the raw values are folded into the normalized fields, absent dates become null.
  • Weekly refresh — enforcement data updates weekly, so a monitoring schedule should overlap its report_date window run-to-run to avoid missing a late-posted recall.
  • Change churn — recalls get re-classified and terminated over time; detectChanges is what turns that churn into events. The openfda{} enrichment block is intermittently absent and is not relied on.
  • Rate limits — keyless access is 240 req/min and 1000/day per IP; large historical pulls should narrow by category/date or supply an apiKey rather than paging past the cap.