How to Download FDA Recall Data (Drugs, Devices and Food)
If you work in regulatory affairs, quality, or market intelligence, sooner or later someone asks for "all the FDA recalls for X." The data is public and free. The hard part is knowing which of FDA's several publications you actually want, and how to get it into a spreadsheet or dataframe without losing records. This guide walks through the free options first.
First: "recall" means three different things
FDA publishes recall-related information in more than one place:
- Enforcement reports. FDA's weekly Enforcement Report lists recalls after FDA has classified them (Class I, II or III). These cover drugs, devices, food (including cosmetics and dietary supplements) and are the most consistent structured source.
- Device recall records. The device recall database has extra device-specific fields such as product code and root-cause text.
- Press releases and company announcements. Narrative web pages. Useful for reading, not for analysis.
For almost any analysis you want the first two. Both are exposed through openFDA.
Option 1: The openFDA API
openFDA (https://open.fda.gov) offers JSON endpoints:
https://api.fda.gov/drug/enforcement.jsonhttps://api.fda.gov/device/enforcement.jsonhttps://api.fda.gov/food/enforcement.jsonhttps://api.fda.gov/device/recall.json
A simple query:
https://api.fda.gov/drug/enforcement.json?search=classification:"Class I"&limit=100
You can get a free API key, which raises the daily request limit. Without one you can still make requests at a lower rate (check openFDA's authentication page for current limits).
Gotchas:
limittops out at 1,000 per request, andskipcan't go past a fixed ceiling, so you can't page through everything with skip alone. See our separate guide on pagination.- Dates such as
report_dateandrecall_initiation_datecome asYYYYMMDDstrings. Convert them before sorting. - The
openfdasub-object (brand names, NDCs, etc.) is often empty for enforcement records, because not every record maps to a product label.
Option 2: openFDA bulk downloads
For whole datasets, openFDA publishes zipped JSON files at https://open.fda.gov/data/downloads/. Each endpoint has one or more files, refreshed on the schedule shown on the page (enforcement weekly, many device files monthly).
Steps:
- Fetch the manifest at
https://api.fda.gov/download.json. It lists every file URL and its export date. - Download the files for the endpoint you want.
- Unzip and load with Python:
import json, zipfile, pandas as pd
with zipfile.ZipFile("drug-enforcement-0001-of-0001.json.zip") as z:
data = json.load(z.open(z.namelist()[0]))
df = pd.json_normalize(data["results"])
df["report_date"] = pd.to_datetime(df["report_date"], format="%Y%m%d")
This is the most reliable free route for a complete pull. It's what we recommend if you only need a one-off snapshot and you're comfortable with Python.
Option 3: FDA's Enforcement Report web search
FDA's own Enforcement Report site lets you search and export results to a spreadsheet. It's good for a quick one-off ("all Class I device recalls for firm X this year"). It's not good for repeatable analysis: you click through filters every time, and there's no history of how records changed.
Cleaning steps almost everyone needs
Whichever route you take, plan for:
- Combining product types. Drug, device and food enforcement are separate files with nearly the same fields. Add a
product_typecolumn and concatenate. - De-duplication. Use
recall_numberas the key. Some records appear in more than one weekly export. - Normalising classification and status text. Values are mostly clean, but check for stray whitespace and case.
- Free-text fields.
reason_for_recallandproduct_descriptionare long free text. Keep them, but don't try to join on them. - Firm names.
recalling_firmisn't standardised: "Acme Inc." and "ACME, INC" are different strings. Build a simple normalisation (uppercase, strip punctuation and suffixes) before grouping.
A caution about what this data is for
openFDA states that enforcement report data shouldn't be used to issue alerts to the public, and that a record isn't a live view of a recall's status. Use it for analysis, trend reporting and research: counts by class, by firm, by product code, by year. For current recall status, go to the FDA notice or the firm.
When a cleaned feed saves time
If you need this regularly, three things become tedious:
- Re-running the download and cleaning every week.
- Knowing what changed since last week. openFDA updates records in place, so last week's version is gone unless you saved it.
- Joining enforcement to 510(k)/PMA clearances and drug shortages.
That's the gap the Apex US Regulatory Events Feed fills. It's a cleaned, de-duplicated weekly change history of FDA's published records, with a weekly_changes table, delivered as CSV or through Delta Sharing for pandas, Spark and Power BI. There are free 100-row samples at https://apex-feed.pages.dev/#samples. The full feed (records from 2024 onwards, updated weekly) is a $50 one-time snapshot, $39/month or $390/year at https://apex-feed.pages.dev.
If you only need a single pull, Option 2 above is free and works well.
Summary
| Need | Best route |
|---|---|
| Quick lookup | FDA Enforcement Report web search |
| Full one-off dataset | openFDA bulk downloads |
| Filtered programmatic pulls | openFDA API |
| Weekly history and changes | Your own snapshots, or a cleaned feed |
Source: U.S. FDA via openFDA. Apex is not affiliated with or endorsed by the U.S. Food and Drug Administration. Not medical or legal advice. Verify current API limits on open.fda.gov before relying on them.