# openFDA Scraper · Drug Events, Recalls, Labels & Devices (`reapx/openfda-scraper`) Actor

Scrape FDA drug adverse events, drug and food recalls, product labels, the NDC directory, device events, device recalls and 510(k) clearances from the public openFDA API. No key required, no browser.

- **URL**: https://apify.com/reapx/openfda-scraper.md
- **Developed by:** [Tarek Etman](https://apify.com/reapx) (community)
- **Categories:** Developer tools, Business, Other
- **Stats:** 1 total users, 0 monthly users, 93.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.30 / 1,000 record returneds

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

![reapX — public sources in, addressable records out](https://reapx.dev/reapx.gif)

## openFDA Scraper · Drug Events, Recalls, Labels & Devices

Scrape **openFDA** - the FDA's public API - for drug adverse events, drug and food recalls,
product labels, the NDC directory, medical device events, device recalls and 510(k) clearances.
No API key required, no login, no headless browser. Run it empty and you get the newest drug
recalls; pick a different dataset and it returns that instead.

> Maintained by **reapX**. Every row cites the Apify run that produced it — nothing is
> inferred, modelled or filled in, and a field absent from the source is absent from the row.
> The extracted archive for this source is browsable at
> [reapx.dev/data/openfda-scraper/](https://reapx.dev/data/openfda-scraper/) and mirrored as an open dataset on
> [Hugging Face](https://huggingface.co/datasets/reapxdev/openfda-scraper) and
> [Kaggle](https://www.kaggle.com/datasets/reapxdev/openfda-scraper). Questions: reapxdev@proton.me

Eight FDA datasets, **over 46 million records**, every row keyed by its own FDA identifier.

### What this openFDA scraper returns

| Dataset | Records | Keyed by |
| --- | --- | --- |
| Drug recalls and enforcement | 17,800+ | Recall number |
| Drug adverse events (FAERS) | 20.3M | Safety report ID |
| Drug product labels (SPL) | 261,000+ | SPL set ID |
| NDC directory of marketed drugs | 136,000+ | Product NDC |
| Device recalls | 58,800+ | Product recall number |
| Device adverse events (MAUDE) | 25.3M | Report number |
| 510(k) device clearances | 175,000+ | K number |
| Food recalls and enforcement | 29,200+ | Recall number |

Every row carries `recordId`, `recordType`, `endpoint`, `primaryDate` and `scrapedAt`, plus the
fields that actually apply to that dataset - recall class and reason, reaction terms and
seriousness flags, label sections, ingredients and routes, applicant and review time.

Five named dataset views ship with it: **Records**, **Recalls**, **Adverse events**,
**Products & labels** and **510(k) clearances**.

### How to scrape openFDA

1. Pick a **dataset**. Leave everything else empty and you get the newest records.
2. Narrow by **product or brand name**, **company**, **recall class**, **status**, **state** or a **date window**.
3. For anything the plain-language filters do not cover, use the **raw openFDA query** field.
4. Set **Max records**. You are charged once per record returned, so that is your cost cap.

### What you can build with it

- **Recall monitoring** - run daily on drug, device or food recalls and diff by `recordId`.
- **Pharmacovigilance signals** - count reaction terms for a drug across FAERS over a date window.
- **Competitive device intelligence** - every 510(k) an applicant has cleared, with review times.
- **Label change tracking** - pull SPL labels by set ID and watch indications and warnings move.
- **Formulary and NDC datasets** - the marketed drug directory with ingredients, routes and DEA schedule.
- **Food safety alerting** - Class I food recalls by state, as they are published.
- **Regulatory RAG corpora** - label text and recall reasons with a citable FDA identifier on every row.

### Input configuration

Every field is optional. The prefilled values below are what runs if you press Start without changing anything.

#### What to read

Leave every filter below empty and the run returns the newest records in the chosen dataset.

| Field | Type | Accepts | What it does |
| --- | --- | --- | --- |
| `dataset` | string | one of 8: `drug-recalls`, `drug-adverse-events`, `drug-labels`, `drug-ndc-directory`, ... | Which openFDA endpoint to read. Each one returns a different kind of record, all keyed by their own FDA identifier. Prefilled with `"drug-recalls"`. |
| `searchTerm` | string | free text | Matches the product, brand or device name fields of the chosen dataset. |
| `firmName` | string | free text | Recalling firm, labeler, applicant or manufacturer, depending on the dataset. |

#### How much to fetch

Volume and ordering. You pay per record returned, so this decides the price of the run.

| Field | Type | Accepts | What it does |
| --- | --- | --- | --- |
| `maxRecords` | integer | 1 to 25000 | Hard cap on how many records the run returns. This is also your cost cap: you are charged once per record returned. openFDA serves at most 25,000 records for one query. Prefilled with `100`. |
| `sortBy` | string | `newest`, `oldest`, `none` | Ordering on the dataset's main date field. Prefilled with `"newest"`. |

#### Dates

All dates are YYYY-MM-DD and apply to whichever date field the chosen dataset uses.

| Field | Type | Accepts | What it does |
| --- | --- | --- | --- |
| `lastNDays` | integer | 1 to 20000 | Rolling window on the dataset's main date - recall initiation, report received, decision date or marketing start. Ignored if you set an explicit "From date". Note the adverse event datasets lag: FAERS is usually 3-5 months behind and MAUDE 1-2 months, so windows under 180 days can come back empty. |
| `dateFrom` | string | free text | Earliest date, YYYY-MM-DD. |
| `dateTo` | string | free text | Latest date, YYYY-MM-DD. |

#### Recall filters

These apply to the recall and enforcement datasets.

| Field | Type | Accepts | What it does |
| --- | --- | --- | --- |
| `classification` | string | `Class I`, `Class II`, `Class III` | Class I is the most serious (reasonable probability of serious harm), Class III the least. Applies to drug and food recalls. |
| `recallStatus` | string | one of 5: `Ongoing`, `Completed`, `Terminated`, `Pending`, ... | Where the recall stands today. Drug and food recalls use Ongoing/Completed/Terminated; device recalls use Open, Classified/Terminated/Completed. |
| `state` | string | free text | Two-letter state code of the recalling firm or applicant. |
| `country` | string | free text | Country of the recalling firm or applicant. |

#### Adverse event filters

These apply to the drug adverse event dataset.

| Field | Type | Accepts | What it does |
| --- | --- | --- | --- |
| `seriousOnly` | true/false | checkbox | Keep only adverse event reports FDA flagged as serious. Applies to drug adverse events. |
| `deathsOnly` | true/false | checkbox | Keep only adverse event reports where death was an outcome. |
| `reaction` | string | free text | MedDRA reaction term as FDA records it, in capitals, e.g. HEADACHE, NAUSEA, ANAPHYLACTIC REACTION. |

#### Advanced

Escape hatches for anything the plain-language filters above do not cover.

| Field | Type | Accepts | What it does |
| --- | --- | --- | --- |
| `searchQuery` | string | free text | Advanced. A raw openFDA search expression, combined with every other filter using AND. Example: openfda.pharm\_class\_epc:"Antibacterial". Full syntax at open.fda.gov/apis/query-syntax. |
| `apiKey` | string | free text | Optional and free from open.fda.gov/apis/authentication. Without one, openFDA allows 1,000 requests per day per IP; with one, 120,000. Only needed for very large runs. |

### Pricing

Pay per event. The primary event is **Record returned** (`record-returned`), charged at **$0.002 per event** on the free plan, falling to $0.0008 on the highest tier.

Charged once per complete openFDA record written to the default dataset. A rate-limited or unreachable API, a rejected query and a search that matches nothing are never charged.

Minimum charge cap per run: $0.002.

Tiered discounts apply automatically on every paid Apify plan. Platform usage is absorbed by the Actor, so the per-event price is the whole price.

### Usage examples

#### The prefilled run, which is what Start does with nothing changed

```json
{
  "dataset": "drug-recalls",
  "maxRecords": 100,
  "sortBy": "newest"
}
```

#### Filter by product or brand name

```json
{
  "dataset": "drug-recalls",
  "maxRecords": 100,
  "sortBy": "newest",
  "searchTerm": "insulin"
}
```

#### Filter by company or firm

```json
{
  "dataset": "drug-recalls",
  "maxRecords": 100,
  "sortBy": "newest",
  "firmName": "Medtronic"
}
```

#### Filter by in the last n days

```json
{
  "dataset": "drug-recalls",
  "maxRecords": 100,
  "sortBy": "newest",
  "lastNDays": 90
}
```

#### Filter by from date

```json
{
  "dataset": "drug-recalls",
  "maxRecords": 100,
  "sortBy": "newest",
  "dateFrom": "2026-01-01"
}
```

### Output example

One row, exactly as the actor wrote it to the dataset:

```json
{
  "recordId": "65585-361",
  "recordType": "drug-ndc",
  "endpoint": "drug/ndc",
  "primaryDate": "2026-07-31",
  "scrapedAt": "2026-08-03T01:57:36Z",
  "brandName": "WhiskCare 373",
  "genericName": "Alcohol",
  "labelerName": "Whisk Products, Inc.",
  "dosageForm": "SOLUTION",
  "routes": [
    "TOPICAL"
  ],
  "marketingCategory": "OTC MONOGRAPH DRUG",
  "productType": "HUMAN OTC DRUG",
  "applicationNumber": "505G(a)(3)",
  "activeIngredients": [
    "ALCOHOL 700 mL/L"
  ],
  "listingExpirationDate": "2027-12-31",
  "packageCount": 7
}
```

#### Fields on every row

| Field | Type | What it is |
| --- | --- | --- |
| `activeIngredient` | string | Active ingredient text from the label. Present on: drug-labels. |
| `activeIngredients` | list | Active ingredients with their strengths. Present on: drug-ndc-directory. |
| `adverseEventFlag` | string | Whether the report was flagged as an adverse event. Present on: device-adverse-events. |
| `advisoryCommittee` | string | FDA advisory committee that reviews this device area. Present on: device-510k-clearances. |
| `applicant` | string | Company that submitted the 510(k). Present on: device-510k-clearances. |
| `applicationNumber` | string | FDA application number, e.g. an NDA or ANDA. Present on: drug-ndc-directory. |
| `brandName` | string | Marketed brand name of the drug product. Present on: drug-ndc-directory. |
| `brandNames` | list | Brand names FDA associates with the product. Present on: drug-labels, drug-recalls. |
| `cfresId` | string | Internal FDA device recall record ID. Present on: device-recalls. |
| `city` | string | City of the firm on record. Present on: device-510k-clearances, device-recalls, drug-recalls, food-recalls. |
| `classification` | string | FDA seriousness class. Class I means a reasonable probability of serious harm. Present on: drug-recalls, food-recalls. |
| `clearanceType` | string | Type of 510(k) submission. Present on: device-510k-clearances. |
| `companyNumber` | string | Reporting company case number. Present on: drug-adverse-events. |
| `country` | string | Country of the firm on record. Present on: device-510k-clearances, drug-recalls, food-recalls. |
| `dateOfEvent` | string | Date the device event occurred, YYYY-MM-DD. Present on: device-adverse-events. |
| `datePosted` | string | Date the device recall was posted, YYYY-MM-DD. Present on: device-recalls. |
| `dateReceived` | string | Date FDA received the submission, YYYY-MM-DD. Present on: device-510k-clearances. |
| `deaSchedule` | string | Controlled substance schedule, when the drug is scheduled. Present on: drug-ndc-directory. |
| `decisionCode` | string | Short FDA code for the decision. Present on: device-510k-clearances. |
| `decisionDescription` | string | FDA decision on the submission. Present on: device-510k-clearances. |
| `deviceBrandNames` | list | Brand names of the devices in the report. Present on: device-adverse-events. |
| `deviceCount` | integer | How many devices this report covers. Present on: device-adverse-events. |
| `deviceGenericNames` | list | Generic names of the devices in the report. Present on: device-adverse-events. |
| `deviceName` | string | Trade name of the cleared device. Present on: device-510k-clearances. |
| `distributionPattern` | string | Where the product was distributed. Present on: device-recalls, drug-recalls, food-recalls. |
| `documentId` | string | Version-specific SPL document ID. The set ID in recordId is stable across versions. Present on: drug-labels. |
| `dosageAndAdministration` | string | Dosing instructions from the label. Present on: drug-labels. |
| `dosageForm` | string | Physical form of the product, e.g. TABLET. Present on: drug-ndc-directory. |
| `drugCount` | integer | How many drugs this report lists. Present on: drug-adverse-events. |
| `endpoint` | string | The api.fda.gov endpoint the row came from. |
| `eventId` | string | FDA enforcement event ID grouping related recall records. Present on: drug-recalls, food-recalls. |
| `eventType` | string | Nature of the device event, e.g. Malfunction or Injury. Present on: device-adverse-events. |
| `genericName` | string | Generic name of the drug product. Present on: drug-ndc-directory. |
| `genericNames` | list | Generic drug names FDA associates with the product. Present on: drug-labels, drug-recalls. |
| `indicationsAndUsage` | string | What the product is approved to treat, from the label. Present on: drug-labels. |
| `initialFirmNotification` | string | How the firm first told its customers. Present on: drug-recalls, food-recalls. |
| `kNumbers` | list | 510(k) clearance numbers linked to the recalled device. Present on: device-recalls. |
| `labelVersion` | string | Version number of this SPL label. Present on: drug-labels. |
| `labelerName` | string | Company that labels and markets the product. Present on: drug-ndc-directory. |
| `listingExpirationDate` | string | Date the NDC listing expires, YYYY-MM-DD. Present on: drug-ndc-directory. |
| `manufacturerNames` | list | Manufacturer names on the record. Present on: device-adverse-events, drug-labels. |
| `marketingCategory` | string | Regulatory pathway under which the product is marketed. Present on: drug-ndc-directory. |
| `medicinalProducts` | list | Drug products named in the report. Present on: drug-adverse-events. |
| `occurCountry` | string | Country where the event occurred. Present on: drug-adverse-events. |
| `packageCount` | integer | How many package configurations this NDC has. Present on: drug-ndc-directory. |
| `patientOnsetAge` | string | Patient age when the reaction began, as reported. Present on: drug-adverse-events. |
| `patientSex` | string | Patient sex as reported. Present on: drug-adverse-events. |
| `pharmClasses` | list | Established pharmacologic class terms. Present on: drug-ndc-directory. |
| `primaryDate` | string | The dataset’s main date, normalised to YYYY-MM-DD: recall initiation, report received, decision date or marketing start. |
| `productCode` | string | FDA three-letter device product code. Present on: device-510k-clearances, device-recalls. |
| `productCodes` | list | FDA device product codes in the report. Present on: device-adverse-events. |
| `productDescription` | string | Full description of the recalled or reported product as the firm filed it. Present on: device-recalls, drug-recalls, food-recalls. |
| `productNdcs` | list | National Drug Codes covered by this label. Present on: drug-labels. |
| `productQuantity` | string | How much product is covered by the recall, as filed. Present on: device-recalls, drug-recalls, food-recalls. |
| `productType` | string | Broad FDA product category. Present on: drug-ndc-directory, drug-recalls, food-recalls. |
| `purpose` | string | Purpose section of the label. Present on: drug-labels. |
| `reactionCount` | integer | How many distinct reactions this report lists. Present on: drug-adverse-events. |
| `reactions` | list | MedDRA reaction terms reported. Present on: drug-adverse-events. |
| `reasonForRecall` | string | Why the product was recalled, in the firm’s own words. Present on: device-recalls, drug-recalls, food-recalls. |
| `recallAction` | string | What the firm is doing about the recalled device. Present on: device-recalls. |
| `recallStatus` | string | Where the recall stands today. Present on: device-recalls, drug-recalls, food-recalls. |
| `recallingFirm` | string | Company that initiated or was ordered to conduct the recall. Present on: device-recalls, drug-recalls, food-recalls. |
| `receiptDate` | string | Date FDA most recently received information, YYYY-MM-DD. Present on: drug-adverse-events. |
| `recordId` | string | The FDA identifier for this record - recall number, NDC, 510(k) number, safety report ID or SPL set ID depending on the dataset. Stable, unique, and how the row is addressed downstream. |
| `recordType` | string | Which kind of FDA record this row is. |
| `reportDate` | string | Date FDA published the enforcement report, YYYY-MM-DD. Present on: drug-recalls, food-recalls. |
| `reportSource` | string | Who submitted the report. Present on: device-adverse-events. |
| `reviewDays` | integer | Days between FDA receiving the 510(k) and deciding it. Present on: device-510k-clearances. |
| `routes` | list | Routes of administration. Present on: drug-labels, drug-ndc-directory. |
| `scrapedAt` | string | UTC ISO 8601 timestamp of this run. |
| `serious` | true/false | FDA flagged the report as serious. Present on: drug-adverse-events. |
| `seriousnessDeath` | true/false | Death was an outcome of this report. Present on: drug-adverse-events. |
| `seriousnessHospitalization` | true/false | Hospitalisation was an outcome of this report. Present on: drug-adverse-events. |
| `seriousnessLifeThreatening` | true/false | The event was life threatening. Present on: drug-adverse-events. |
| `state` | string | Two-letter US state code of the firm on record. Present on: device-510k-clearances, device-recalls, drug-recalls, food-recalls. |
| `substanceNames` | list | UNII substance names on the label. Present on: drug-labels. |
| `terminationDate` | string | Date FDA terminated the recall, YYYY-MM-DD. Present on: food-recalls. |
| `voluntaryMandated` | string | Whether the firm initiated the recall or FDA required it. Present on: drug-recalls, food-recalls. |
| `warnings` | string | Warnings section of the product label. Present on: drug-labels. |

5 named dataset views ship with it: **Records**, **Recalls**, **Adverse events**, **Products & labels**, **510(k) clearances**. They drive the Output tab in Console and the Output block on the Actor's `.md` page.

### FAQ

#### How do I scrape openFDA data?

Pick a dataset and run. Everything comes from `api.fda.gov`, the FDA's own public API, which
needs no authentication for normal use.

#### Do I need an openFDA API key?

Not for most runs. Without a key openFDA allows 1,000 requests per day per IP; this actor pulls
1,000 records per request, so that is a great deal of data. For very large jobs, paste a free key
from open.fda.gov/apis/authentication into the optional **openFDA API key** field and the limit
rises to 120,000 requests per day.

#### How do I find Class I recalls?

Choose **Drug recalls** or **Food recalls**, set **Recall classification** to Class I, and
optionally add a date window. Class I means FDA judged there is a reasonable probability of
serious harm or death.

#### How do I search adverse events for one drug?

Choose **Drug adverse events (FAERS)** and put the drug name in **Product or brand name**. Add a
**Reaction term** such as `ANAPHYLACTIC REACTION` to narrow to one reaction, or turn on **Reports
involving death only**.

#### How far back does the data go?

It varies by dataset - FAERS runs from 2004, enforcement reports from 2012, 510(k) clearances
from 1976. Set **From date** as early as you like; the actor passes it straight through.

#### How many records can one run return?

Up to 25,000 for a single query, which is openFDA's own paging ceiling. Split a larger job into
date windows and run each one.

#### What identifies each row?

`recordId` - the recall number, safety report ID, SPL set ID, NDC, K number or device recall
number, depending on the dataset. It is FDA's own identifier and is stable across runs.

#### Can I use my own openFDA query syntax?

Yes. The **Raw openFDA query** field takes any expression the API accepts, for example
`openfda.pharm_class_epc:"Antibacterial"`, and it is combined with the other filters using AND.

#### Can an AI agent call this actor?

Yes. Every input and output field carries a title, description and example, and every row is
addressed by its FDA `recordId`, so an agent can fill the input and chain the output without
extra prompting.

***

Unofficial - not affiliated with the FDA. Collects public data only. reapx.
Contact reapxdev@proton.me.

### The full published archive

- **[openfda scraper archive](https://reapx.dev/data/openfda-scraper/)** — every entity this Actor has observed
- **[All reapx datasets](https://reapx.dev/data/)** — 20 sources, tens of thousands of pages
- **[llms.txt](https://reapx.dev/llms.txt)** · **[feed.json](https://reapx.dev/feed.json)** ·
  **[feed.xml](https://reapx.dev/feed.xml)** — the machine-readable index, for agents

Each archive page carries Dataset JSON-LD, a canonical URL and the identifiers used, so an agent
can resolve an entity without running anything. Nothing on those pages is estimated or modelled.

### 🧪 Example input

A real, runnable configuration — this is an actual input this Actor has run with.

```json
{
  "dataset": "drug-ndc-directory",
  "lastNDays": 365,
  "maxRecords": 500
}
```

### 📄 Sample output

One real row from a real run of this Actor, unedited.

```json
{
  "recordId": "65585-361",
  "recordType": "drug-ndc",
  "endpoint": "drug/ndc",
  "primaryDate": "2026-07-31",
  "scrapedAt": "2026-08-03T01:57:36Z",
  "brandName": "WhiskCare 373",
  "genericName": "Alcohol",
  "labelerName": "Whisk Products, Inc.",
  "dosageForm": "SOLUTION",
  "routes": [
    "TOPICAL"
  ],
  "marketingCategory": "OTC MONOGRAPH DRUG",
  "productType": "HUMAN OTC DRUG",
  "applicationNumber": "505G(a)(3)",
  "activeIngredients": [
    "ALCOHOL 700 mL/L"
  ],
  "listingExpirationDate": "2027-12-31",
  "packageCount": 7
}
```

### How it works

1. You set the filters below, or none at all.
2. The Actor calls the source's own public endpoint and pages through the results.
3. Every row is pushed to the dataset **as it is built**, not buffered to the end — so a
   run that hits its time limit still returns everything it collected up to that point.
4. You are charged per row returned, so the maximum-results field is also your cost cap.

### 💬 Your feedback

Found a bug, or need a field this does not return yet? Open an issue on the Actor's **Issues**
tab, or write to **reapxdev@proton.me**. Bugs get fixed and reasonable field requests get
added.

# Actor input Schema

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

Which openFDA endpoint to read. Each one returns a different kind of record, all keyed by their own FDA identifier.<br><br>Options: <code>drug-recalls</code>, <code>drug-adverse-events</code>, <code>drug-labels</code>, <code>drug-ndc-directory</code>, <code>device-recalls</code>, <code>device-adverse-events</code>.

## `searchTerm` (type: `string`):

Matches the product, brand or device name fields of the chosen dataset.<br><br>Leave this field empty to skip this filter.

## `firmName` (type: `string`):

Recalling firm, labeler, applicant or manufacturer, depending on the dataset.<br><br>Leave this field empty to skip this filter.

## `maxRecords` (type: `integer`):

Hard cap on how many records the run returns. This is also your cost cap: you are charged once per record returned. openFDA serves at most 25,000 records for one query.<br><br>The higher the number, the longer the run takes and the more you are charged, because you pay per row returned.

## `sortBy` (type: `string`):

Ordering on the dataset's main date field.<br><br>Options: <code>newest</code>, <code>oldest</code>, <code>none</code>.

## `lastNDays` (type: `integer`):

Rolling window on the dataset's main date - recall initiation, report received, decision date or marketing start. Ignored if you set an explicit "From date". Note the adverse event datasets lag: FAERS is usually 3-5 months behind and MAUDE 1-2 months, so windows under 180 days can come back empty.<br><br>The higher the number, the longer the run takes and the more you are charged, because you pay per row returned.

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

Earliest date, YYYY-MM-DD.

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

Latest date, YYYY-MM-DD.

## `classification` (type: `string`):

Class I is the most serious (reasonable probability of serious harm), Class III the least. Applies to drug and food recalls.<br><br>Options: <code>Class I</code>, <code>Class II</code>, <code>Class III</code>.

## `recallStatus` (type: `string`):

Where the recall stands today. Drug and food recalls use Ongoing/Completed/Terminated; device recalls use Open, Classified/Terminated/Completed.<br><br>Options: <code>Ongoing</code>, <code>Completed</code>, <code>Terminated</code>, <code>Pending</code>, <code>Open, Classified</code>.

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

Two-letter state code of the recalling firm or applicant.<br><br>Leave this field empty to skip this filter.

## `country` (type: `string`):

Country of the recalling firm or applicant.<br><br>Leave this field empty to skip this filter.

## `seriousOnly` (type: `boolean`):

Keep only adverse event reports FDA flagged as serious. Applies to drug adverse events.

## `deathsOnly` (type: `boolean`):

Keep only adverse event reports where death was an outcome.

## `reaction` (type: `string`):

MedDRA reaction term as FDA records it, in capitals, e.g. <code>HEADACHE</code>, NAUSEA, ANAPHYLACTIC REACTION.<br><br>Leave this field empty to skip this filter.

## `searchQuery` (type: `string`):

Advanced. A raw openFDA search expression, combined with every other filter using AND. Example: openfda.pharm\_class\_epc:"Antibacterial". Full syntax at open.fda.gov/apis/query-syntax.<br><br>Leave this field empty to skip this filter.

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

Optional and free from open.fda.gov/apis/authentication. Without one, openFDA allows 1,000 requests per day per IP; with one, 120,000. Only needed for very large runs.<br><br>Leave this field empty to skip this filter.

## Actor input object example

```json
{
  "dataset": "drug-recalls",
  "searchTerm": "insulin",
  "firmName": "Medtronic",
  "maxRecords": 100,
  "sortBy": "newest",
  "lastNDays": 90,
  "dateFrom": "2026-01-01",
  "dateTo": "2026-12-31",
  "classification": "Class I",
  "recallStatus": "Ongoing",
  "state": "CA",
  "country": "United States",
  "seriousOnly": true,
  "deathsOnly": true,
  "reaction": "ANAPHYLACTIC REACTION",
  "searchQuery": "openfda.route:\"INTRAVENOUS\"",
  "apiKey": "your-openfda-key"
}
```

# Actor output Schema

## `records` (type: `string`):

One row per FDA record with its identifier, type and main date.

## `recalls` (type: `string`):

Recall class, reason, status and the firm responsible.

## `adverseEvents` (type: `string`):

Reported reactions, seriousness and the products involved.

## `products` (type: `string`):

Marketed drug products, their ingredients and label sections.

## `clearances` (type: `string`):

Cleared devices, applicants and how long review took.

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

Every record this run produced, with all fields and no view applied. Field-level titles, types, descriptions and examples are declared in the dataset schema.

# 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 = {
    "dataset": "drug-recalls",
    "maxRecords": 100,
    "sortBy": "newest"
};

// Run the Actor and wait for it to finish
const run = await client.actor("reapx/openfda-scraper").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 = {
    "dataset": "drug-recalls",
    "maxRecords": 100,
    "sortBy": "newest",
}

# Run the Actor and wait for it to finish
run = client.actor("reapx/openfda-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "dataset": "drug-recalls",
  "maxRecords": 100,
  "sortBy": "newest"
}' |
apify call reapx/openfda-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=reapx/openfda-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/7I7mVgWEEjiCGTSNz/builds/agWfK2pz4TimsVxdd/openapi.json
