Daily FAERS adverse event signal review for your drug portfolio
Every weekday at 7am ET, scan FDA adverse event reports for every drug in your portfolio and post one ranked safety digest to Slack.
Build me an agent workflow that runs a daily pharmacovigilance signal review on my drug portfolio. The audience is a pharma safety team, so the output must read like a clinical signal triage, not a generic news digest.
Trigger: cron, every weekday (Monday through Friday) at 7am ET.
Step 1 — Load the portfolio. Use Airtable's List Records on my portfolio base. Each row is one drug with these fields: brand_name, generic_name, therapeutic_class, and safety_lead_slack_handle. Treat this list as the universe of drugs to monitor.
Step 2 — For each drug, query openFDA's Search Drug Adverse Events (FAERS). Make two calls per drug:
(a) A recent window: reports where receivedate is in the last 7 days AND serious=1, filtered to the drug by openfda.brand_name (and fall back to openfda.generic_name if brand returns no matches). Capture the seriousness flags (seriousnessdeath, seriousnesslifethreatening, seriousnesshospitalization) and the reaction terms (patient.reaction.reactionmeddrapt.exact).
(b) A 90-day baseline: use the count parameter on patient.reaction.reactionmeddrapt.exact over the prior 90 days for the same drug. This is the reference distribution the agent will compare the last 7 days against to spot reactions that are new or trending up versus history.
openFDA returns HTTP 404 (not an empty results array) when there are no matches. Treat 404 as "zero signals for this drug today," not a fatal error, and continue.
Step 3 — Agent reasoning. For each drug, rank candidate signals in this order: Class A = any report with seriousnessdeath=1 or seriousnesslifethreatening=1; Class B = seriousnesshospitalization=1; Class C = serious reactions that are new (absent from the 90-day baseline) or trending up (meaningfully higher frequency than baseline). Within each class, prefer reactions that are not already documented on the drug's FDA label. Then deduplicate against Airtable: read the Signal Log table for this drug and discard any candidate signal that has already been logged (match on drug + reaction term + class). For every remaining signal write one short clinical-sounding bullet that includes the report count for the 7-day window, the top reaction terms, the class (A/B/C), a one-line rationale ("new vs baseline", "3x baseline frequency", "fatal outcome reported", etc.), and a direct FAERS query URL so the safety lead can drill in.
Step 4 — Append new signals to Airtable using Create Records on the Signal Log table. One row per new signal with: drug (brand_name + generic_name), therapeutic_class, class (A/B/C), reaction_term, report_count_7d, baseline_freq_90d, rationale, faers_query_url, first_seen_date (today), and source_run_id.
Step 5 — Post one digest to a Slack channel using Slack Bot's Send a Message. Format it as one section per drug that has at least one new signal, using Slack mrkdwn (so *bold* not **bold**). Omit drugs with zero new serious signals entirely — the message must stay scannable. For each included drug, show the drug name, therapeutic class, and the ranked signal bullets from Step 3 grouped by class (A first, then B, then C). Only @-mention the safety lead (from the portfolio row's safety_lead_slack_handle) when that drug has at least one Class A signal. If no drug in the portfolio has any new serious signals, post a single short "No new serious signals across the portfolio today" line instead of skipping the message.
Keep the tone clinical and terse: counts, reaction terms, class, rationale, link. No marketing language, no emoji decoration beyond a small severity indicator per class if helpful.
Additional information
What does this prompt do?
- Pulls your drug portfolio from Airtable (brand name, generic name, therapeutic class, and the safety lead for each drug).
- Checks the FDA's adverse event database for the last 7 days of serious reports for every drug, and compares against a 90 day baseline to spot new or trending reactions.
- Ranks signals the way a safety team would: deaths and life threatening events first, then hospitalizations, then unusual reactions not already on the label.
- Logs every new signal as a row in an Airtable Signal Log so pharmacovigilance has an auditable trail, and skips signals already logged from prior runs.
- Posts one scannable Slack digest with a section per drug, and only @-mentions the responsible safety lead when a death or life threatening signal appears.
What do I need to use this?
- An Airtable base with one row per drug in your portfolio, including brand name, generic name, therapeutic class, and the safety lead's Slack handle.
- An Airtable Signal Log table where new signals will be appended (the workflow can use any table you point it at).
- A Slack workspace and a channel for the safety team to receive the daily digest.
- No FDA account is required. The FDA's adverse event database is public, so the workflow can read it without any credentials.
How can I customize it?
- Change the schedule. Run it at a different time, or shift to twice daily if your safety team triages morning and evening.
- Tune the window. The default looks back 7 days against a 90 day baseline, but you can widen the trend window or narrow the alert window.
- Adjust the severity bar. Decide which classes of events deserve an @-mention versus a quiet log entry, and whether to include non-serious reports.
- Swap the destination. Route the digest to a different Slack channel, or split into per therapeutic class channels if your portfolio is large.
Frequently asked questions
Where does the safety data come from?
What counts as a signal?
Will I get pinged every morning even when nothing is happening?
How does it avoid alerting on the same signal twice?
Can I add or remove drugs from the portfolio without touching the workflow?
Stop hand-checking FAERS every morning.
Connect Airtable and Slack once, and Geni runs your daily pharmacovigilance signal review before the team logs on.