FDA Drug Safety Signals avatar

FDA Drug Safety Signals

Pricing

from $3.00 / 1,000 results

Go to Apify Store
FDA Drug Safety Signals

FDA Drug Safety Signals

Screen FDA FAERS adverse event reports for drug safety signals with PRR, ROR, chi-squared and 95% confidence intervals. Flags signals missing from the FDA label and joins recall history. Export data, run via API, schedule and monitor runs, or integrate with other tools.

Pricing

from $3.00 / 1,000 results

Rating

0.0

(0)

Developer

Skootle

Skootle

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

FDA Drug Safety Signals turns 20.3 million FAERS adverse event reports into ranked, explainable safety signals for any drug you name. It is built for pharmacovigilance teams, regulatory affairs, pharma competitive intelligence, health-tech products, and AI agents that need defensible numbers instead of a raw record dump.

Three ways to run it:

  1. Paste a drug name and press Start. The prefilled input screens OZEMPIC and returns signals in under a minute.
  2. Schedule it weekly on your product portfolio and watch for new unlabeled signals as FDA refreshes FAERS each quarter.
  3. Call it from the API or an agent. Every row carries agentMarkdown, so an LLM can read a result without any extra prompt engineering.

FDA Drug Safety Signals

TL;DR

You give it a list of drugs. It gives you back two kinds of rows.

Safety signal rows, one per drug and reaction pair, with the fields that make a signal defensible: drug, reaction, reportCount, drugTotalReports, reactionTotalReports, databaseTotalReports, prr, prrLower95, prrUpper95, ror, rorLower95, rorUpper95, chiSquaredYates, meetsEvansCriteria, signalStrength, signalRationale, isLabeledReaction, labelMatchSection, labelMatchMethod, labelMatchConfidence, isUnlabeledSignal, seriousReportCount, deathReportCount, hospitalizationReportCount, seriousSharePct, sourceQueryUrl, dataAsOf, fieldCompletenessScore, agentMarkdown.

Drug summary rows, one per drug, with the portfolio view: totalReports, signalsFound, strongSignalCount, unlabeledSignalCount, topUnlabeledSignals, topReactions, seriousReports, deathReports, hospitalizationReports, seriousSharePct, hasBoxedWarning, openRecallCount, recallClassI, recallClassII, recallClassIII, mostRecentRecallDate, mostRecentRecallReason, isZeroMatch, sourceStatus.

The pain it kills: pulling FAERS yourself means writing the openFDA query layer, building the 2x2 contingency table against a 20 million report denominator, getting the confidence intervals right, then reconciling every hit against the product label by hand. That is a week of work per analyst, repeated every quarter. This runs it in about a minute.

If this Actor saves you a day of work, a short review helps other people find it: leave a review.

What does this Actor actually do?

It runs the standard disproportionality screen that pharmacovigilance teams use, against the live openFDA FAERS database.

For every drug you give it, the Actor:

  1. Counts every FAERS report naming that drug, across brand name, generic name, active substance, and free-text product name.
  2. Counts that drug's most reported adverse reactions.
  3. Counts how often each of those reactions appears across the entire database, so it has a true background rate.
  4. Builds the 2x2 contingency table and computes PRR, ROR, 95% confidence intervals on both, and a Yates-corrected chi-squared.
  5. Applies the Evans screening criteria and grades each result NONE, WEAK, MODERATE, or STRONG.
  6. Pulls the product's own FDA label and checks whether each signal is already documented there.
  7. Pulls the product's FDA recall history and folds it into the summary.

Nothing in the output is model generated. Every statistic is reproducible from four integers that come straight from public openFDA count queries, and every row ships the sourceQueryUrl that produced it.

Why does the unlabeled signal flag matter?

This is the field most buyers end up filtering on.

A statistical signal for a reaction that is already printed in the drug's label is expected. Nausea on a GLP-1 is not news. The reactions worth an analyst's time are the ones that clear the screening threshold and are not in the label yet.

So every signal row carries isLabeledReaction, labelMatchSection, labelMatchMethod, labelMatchConfidence, and the derived isUnlabeledSignal. Sort by isUnlabeledSignal and you have your review queue.

Being honest about the limit: MedDRA preferred terms and FDA label prose do not use identical wording. FAERS says IMPAIRED GASTRIC EMPTYING, the label says gastroparesis. The Actor handles this with a clinical synonym layer covering the common divergences, and it reports which method produced each match:

  • exact_phrase, high confidence: the preferred term appears verbatim in the label.
  • synonym_phrase, medium confidence: known label wording for the same clinical event.
  • all_tokens, medium confidence: every meaningful word appears in the section.
  • none, medium confidence: no match found, so the signal is flagged unlabeled.
  • label_unavailable, low confidence: openFDA had no label for this product.

You can audit every one of those decisions. That is the point.

Worked examples from real verification runs

OZEMPIC safety signals, real output from a verification run

The chart above is the actual dataset from cloud run 6xkb8MZQgfR9EXuyC, not a mockup. Amber bars are signals the label check did not find in the FDA label. Every number below came out of the verification runs used to release this Actor. Nothing is illustrative or rounded for effect. Data as of the FDA refresh on 2026-04-28, against a database total of 20,328,575 reports.

Example 1: metformin, LACTIC ACIDOSIS

{
"drug": "metformin",
"reaction": "LACTIC ACIDOSIS",
"reportCount": 19938,
"drugTotalReports": 455084,
"prr": 79.983,
"prrLower95": 78.151,
"prrUpper95": 81.858,
"ror": 83.602,
"chiSquaredYates": 550003,
"signalStrength": "STRONG",
"meetsEvansCriteria": true,
"isLabeledReaction": true,
"labelMatchSection": "boxed_warning",
"labelMatchMethod": "exact_phrase",
"isUnlabeledSignal": false,
"seriousReportCount": 19878,
"deathReportCount": 3809,
"hospitalizationReportCount": 14875,
"fieldCompletenessScore": 94
}

This is the control case. Metformin carries a boxed warning for lactic acidosis, and the Actor finds it with a PRR near 80 and matches it straight to boxed_warning. It is correctly not flagged as an unlabeled signal. If a screening tool cannot reproduce this, do not trust anything else it says.

Example 2: metformin, BLOOD GLUCOSE INCREASED, an unlabeled signal

{
"reaction": "BLOOD GLUCOSE INCREASED",
"reportCount": 29012,
"prr": 8.157,
"prrLower95": 8.058,
"prrUpper95": 8.257,
"ror": 8.645,
"chiSquaredYates": 154913.75,
"signalStrength": "STRONG",
"isLabeledReaction": false,
"labelMatchMethod": "none",
"isUnlabeledSignal": true,
"seriousReportCount": 11086,
"deathReportCount": 403
}

A strong disproportionality signal that the label check did not find in the product label. This is exactly the row a safety team wants surfaced. Note the reading it deserves: for a glycaemic control drug, reports of the underlying condition worsening are often confounded by indication. The Actor gives you the number and the provenance, you supply the clinical judgment.

Example 3: metformin, ACUTE KIDNEY INJURY, caught by the synonym layer

{
"reaction": "ACUTE KIDNEY INJURY",
"reportCount": 18627,
"prr": 6.319,
"ror": 6.546,
"chiSquaredYates": 73376.61,
"signalStrength": "STRONG",
"isLabeledReaction": true,
"labelMatchSection": "boxed_warning",
"labelMatchMethod": "synonym_phrase",
"isUnlabeledSignal": false
}

The label discusses renal impairment, not the MedDRA term acute kidney injury. Naive text matching would have reported a false unlabeled signal here. The synonym layer resolves it and tells you it did, via labelMatchMethod.

Example 4: OZEMPIC, IMPAIRED GASTRIC EMPTYING

{
"drug": "OZEMPIC",
"reaction": "IMPAIRED GASTRIC EMPTYING",
"reportCount": 2775,
"drugTotalReports": 62990,
"prr": 102.868,
"prrLower95": 98.635,
"prrUpper95": 107.283,
"ror": 107.563,
"chiSquaredYates": 212157.08,
"signalStrength": "STRONG",
"isLabeledReaction": true,
"labelMatchSection": "warnings_and_cautions",
"labelMatchMethod": "synonym_phrase",
"seriousReportCount": 2738,
"hospitalizationReportCount": 1678,
"seriousSharePct": 98.7
}

The highest PRR in the OZEMPIC run, and 98.7 percent of those reports were flagged serious. The label calls it gastroparesis, so the synonym layer marks it labeled rather than raising a false alarm.

Example 5: the OZEMPIC drug summary row

{
"recordType": "drug_safety_summary",
"drug": "OZEMPIC",
"totalReports": 62990,
"databaseTotalReports": 20328575,
"reportShareOfDatabasePct": 0.3,
"reactionsAnalyzed": 15,
"signalsFound": 12,
"strongSignalCount": 3,
"unlabeledSignalCount": 5,
"topUnlabeledSignals": [
"BLOOD GLUCOSE INCREASED (PRR 4.93, n=2782)",
"WEIGHT DECREASED (PRR 4.62, n=3836)",
"WRONG TECHNIQUE IN PRODUCT USAGE PROCESS (PRR 4.202, n=2527)",
"PRODUCT USE IN UNAPPROVED INDICATION (PRR 3.957, n=2841)",
"OFF LABEL USE (PRR 2.461, n=6343)"
],
"seriousReports": 34186,
"deathReports": 1242,
"hospitalizationReports": 14094,
"seriousSharePct": 54.3,
"hasBoxedWarning": true,
"openRecallCount": 2,
"recallClassII": 2,
"mostRecentRecallDate": "2021-06-02",
"mostRecentRecallReason": "CGMP Deviations: Intermittent exposure to temperature excursion during storage."
}

One row that answers the question a director actually asks: how exposed are we, what is new, and has this product been recalled. Two of the top unlabeled signals here are medication-use problems rather than pharmacology, which is itself a finding worth acting on.

Example 6: the metformin summary, portfolio scale

{
"drug": "metformin",
"totalReports": 455084,
"reactionsAnalyzed": 30,
"signalsFound": 9,
"strongSignalCount": 4,
"unlabeledSignalCount": 3,
"seriousReports": 306171,
"deathReports": 37536,
"hospitalizationReports": 159577,
"seriousSharePct": 67.3,
"hasBoxedWarning": true,
"openRecallCount": 43,
"recallClassII": 38,
"mostRecentRecallDate": "2025-04-16",
"mostRecentRecallReason": "CGMP Deviations"
}

455,084 reports screened, 30 reactions tested, 9 signals, 3 of them unlabeled. Runtime for this drug was under 30 seconds.

Example 7: an honest zero

A drug name with no reports returns a summary that says so, explicitly, rather than a silent empty dataset:

{
"drug": "ZZZQXNOTAREALDRUG",
"totalReports": 0,
"signalsFound": 0,
"isZeroMatch": true,
"sourceStatus": "openFDA responded HTTP 200 with zero matching reports",
"dataAsOf": "2026-04-28"
}

This matters more than it sounds. A valid no-match succeeds and tells you the source was healthy. Anything else, a blocked request, a changed payload shape, an unexplained empty response, fails the run and writes a diagnostic to the key-value store. You never get billed for a green run that quietly returned nothing.

How do I run it?

Tutorial

  1. Open the Actor and leave the prefilled input alone for your first run. It screens OZEMPIC.
  2. Press Start. The run finishes in well under a minute.
  3. Open the Safety signals dataset view. Sort by prr descending.
  4. Filter isUnlabeledSignal to true. That is your review queue.
  5. Open the Drug summaries view for the one-row-per-drug picture.
  6. When you are happy, add your own products to drugs and set a weekly schedule.

Input

{
"drugs": ["OZEMPIC", "metformin", "atorvastatin"],
"dateFrom": "2024-01-01",
"dateTo": "2026-04-28",
"maxReactionsPerDrug": 25,
"minReportCount": 3,
"seriousOnly": false,
"includeLabelCheck": true,
"includeRecalls": true,
"emitSummary": true
}
FieldWhat it does
drugsBrand, generic, or substance names. Up to 25 per run. Each is screened separately.
dateFrom, dateToOptional reporting window, YYYY-MM-DD. Both the numerator and the background rate are restricted, so the statistics stay valid.
maxReactionsPerDrugHow many of the drug's top reactions to test. 25 covers the meaningful tail for most products.
minReportCountSkip reactions below this many co-reports. The standard screening floor is 3.
seriousOnlyRestrict everything to reports FDA flagged serious.
includeLabelCheckTurn the label reconciliation on or off. Leave it on, it is the differentiator.
includeRecallsAdd recall counts by class and the latest recall reason to each summary.
openFdaApiKeyOptional. openFDA allows 240 requests per minute and 1,000 per day without a key. Add a free key only if you screen large lists.

Output

Two record types in one dataset, separated by the recordType field and by the two prebuilt dataset views. Every row carries schemaVersion, a stable recordId so reruns upsert cleanly, ISO 8601 retrievedAt, sourceQueryUrl, fieldCompletenessScore, and agentMarkdown.

The run also writes AGENT_BRIEFING to the key-value store: one markdown briefing covering every drug in the run, ready to hand to an LLM.

What is the best openFDA scraper, and why choose this Actor?

There are a number of openFDA scrapers on the Store. They are useful for what they do, which is returning raw FAERS records. This Actor is a different product, and the comparison is factual rather than promotional.

Typical openFDA scraperFDA Drug Safety Signals
OutputRaw adverse event recordsRanked signals with statistics, plus raw counts
PRR, ROR, chi-squaredNot computedComputed with 95% confidence intervals
Background rateNot establishedFull 20.3M report denominator per reaction
Screening standardNone statedEvans criteria, stated and reproducible per row
Label reconciliationNot doneEvery signal checked against the FDA label, method and confidence reported
Recall historySeparate ActorJoined into the drug summary
Per-query intelligenceNoneOne summary row per drug
Honest empty resultsOften a silent empty datasetExplicit zero-match record, or a failed run with diagnostics
Agent readinessRaw JSONagentMarkdown per row plus an AGENT_BRIEFING per run

If you want raw FAERS records to load into your own pipeline, a simpler scraper may suit you better and cost less. If you want the analysis those records are meant to support, that is what this Actor is for.

How much will screening FDA safety signals cost you?

Pricing is pay per event, so you pay for results rather than for compute time.

This Actor uses the official openFDA API over plain HTTP. There is no browser, no proxy, and no third party data vendor in the path, which is the cheapest architecture available on the platform. That cost advantage is passed through to the price rather than kept as margin padding.

A few practical notes on controlling spend:

  • Each run has a hard charge cap, so a misconfigured input cannot run away with your budget.
  • maxReactionsPerDrug is the main cost lever. 25 reactions per drug is the sensible default. Raising it to 100 roughly quadruples the rows.
  • Raising minReportCount cuts low-information rows before they are charged for.
  • A failed run does not bill you for records it never delivered, because the Actor fails honestly instead of reporting an empty success.

Current per-event pricing and any volume tiers are shown on the Actor's pricing card on this page, which is always the authoritative figure.

Frequently asked questions

Is PRR the right method, or should I be using a Bayesian approach? PRR with the Evans criteria is the most widely used and most widely accepted screening method, and it is the one regulators and most safety teams recognise. Bayesian shrinkage methods such as EBGM and BCPNN behave better for very sparse cells, which is why this Actor also exposes the raw contingency counts. If you want to run EBGM downstream, reportCount, drugTotalReports, reactionTotalReports, and databaseTotalReports give you everything you need.

Does a signal mean the drug caused the reaction? No, and the Actor says so on every summary row. FAERS is a spontaneous reporting system. It is subject to reporting bias, notoriety bias, confounding by indication, and duplicate reports. Disproportionality tells you a reaction is reported more often than the background rate. It does not establish causation. It tells you where to look.

How current is the data? Every row carries dataAsOf, taken from openFDA's own last_updated field for the endpoint. FDA refreshes FAERS quarterly. Verification runs for this release reported 2026-04-28.

Do I need an FDA or openFDA API key? No. openFDA is a free public API and this Actor works without any key. The optional openFdaApiKey field only raises your rate limit if you screen very large drug lists.

Can I run this on a schedule and get alerted to new signals? Yes. Add it to an Apify schedule, weekly or monthly depending on your portfolio, and use unlabeledSignalCount on the summary row as your alert condition. Because recordId is stable across runs, comparing two runs to find new signals is straightforward.

Why did my drug return zero reports? Usually the product is recorded in FAERS under a different name. Try the generic or active substance name rather than the brand, check the spelling, and widen or remove the date window. The zero-match summary record tells you the source was healthy, so the query is the thing to change.

Can I use this for medical devices or foods? Not in this version. This Actor screens the drug adverse event endpoint. Device and food safety data live in different openFDA endpoints with different structures. If you need those, say so in the Issues tab and it will be weighed against the roadmap.

Can I run this from Python, Node, or an n8n or Make workflow? Yes. It is a standard Apify Actor, so the Apify Python and JavaScript clients, the REST API, and the n8n, Make, Zapier, and LangChain integrations all work without anything special. Start a run, wait for it to finish, then read the dataset.

How do I get the data into my own system? Use the Apify API, the dataset export in JSON, CSV, or Excel, or a webhook on run completion. The dataset is a normal Apify dataset, so anything that works with Apify works here.

Is the output stable enough to build on? Every record carries schemaVersion. Field names will not change or disappear inside a major version. New fields may be added, which is why parsing should ignore unknown keys.

This Actor retrieves data from openFDA (api.fda.gov), the U.S. Food and Drug Administration's official public API. It accesses only public endpoints, uses no authentication bypass, and applies no anti-bot circumvention of any kind. openFDA data is public U.S. government information.

Points worth stating plainly:

  • No affiliation or endorsement. This Actor is an independent product. It is not affiliated with, endorsed by, or sponsored by the U.S. Food and Drug Administration or any pharmaceutical manufacturer. No FDA logo or seal is used anywhere in this listing or its artwork.
  • FDA's own disclaimer applies. FDA does not guarantee the accuracy or completeness of openFDA data, and the data should not be used to make clinical decisions on its own.
  • No personal data. FAERS reports are de-identified at source. This Actor extracts counts, statistics, and reaction terms. It does not attempt to identify individuals.
  • Not medical advice. Output is for research, pharmacovigilance screening, and regulatory intelligence. It is not medical advice and must not be used to diagnose, treat, or make treatment decisions for any individual patient.
  • Your obligations remain yours. If you operate under regulatory reporting duties, this Actor is a screening aid. It does not discharge any reporting obligation you hold.

Other Actors you might want

If you work in regulated data, these siblings pair naturally with this one:

  • Clinical Trials Intel for the ClinicalTrials.gov pipeline picture: sponsors, phases, enrollment, sites, and a competitive landscape summary per query. Pair it with this Actor to see a molecule's trial pipeline and its post-market safety profile side by side.
  • NHTSA Vehicle Safety Intelligence for the same screening idea applied to vehicle recalls, complaints, and investigations.
  • CPSC Product Recall Intelligence for consumer product recall monitoring across the Consumer Product Safety Commission.
  • FDIC Bank Intelligence if your regulatory monitoring extends to financial institutions.

Your feedback

This Actor is actively maintained and feedback shapes what gets built next.

Found a bug, a wrong label match, or a drug that will not resolve? Open a ticket on the Issues tab of this Actor. Bug reports get a real fix, usually quickly, and Issues is the fastest route to one. Please include the drug name, the input you used, and the run ID.

Want a new endpoint, a new statistic, or a different export shape? Issues again. Device and food endpoints, EBGM scoring, and run-over-run signal diffing are all on the list and buyer demand decides the order.

Did it work well? A review genuinely helps other people find it, and it is the single most useful thing you can do for a small independent Actor.