DEV Community

linderroger-eng
linderroger-eng

Posted on

Building a Pharma Compliance Alert System with the FDA Drug & Safety API

Building a Pharma Compliance Alert System with the FDA Drug & Safety API

Regulatory compliance in pharmaceuticals isn't optional — it's existential. A missed FDA enforcement action, an unmonitored recall, or a delayed adverse-event flag can cost a company millions in fines, product liability, and reputational damage. Yet most compliance teams still rely on manually checking FDA.gov, email newsletters, or expensive legacy platforms that cost $50K+/year.

Here's the thing: the FDA publishes all of this data for free via openFDA. And there's now a clean REST API that wraps it into developer-friendly endpoints so you can build your own compliance alert pipeline in an afternoon.

In this guide I'll show you how to build a lightweight pharma compliance monitoring system using the FDA Drug & Safety API — covering enforcement actions, device recalls, and adverse event spikes — with real curl examples and a Python automation script you can run on a cron schedule.


Why Build Your Own Compliance Monitor?

Commercial pharmacovigilance platforms (Veeva Vault, Aris Global, Oracle Argus) are powerful, but they're built for enterprise teams with enterprise budgets. If you're a:

  • Health-tech startup building a drug safety feature into your product
  • Compliance consultant who wants to send automated client alerts
  • Investor tracking FDA risk exposure across a portfolio
  • Hospital IT team monitoring device recalls for your procurement list

...then you don't need a six-figure contract. You need a good API and a Python script.


The API: Endpoints We'll Use

Base URL: https://fda-drug-safety-api.onrender.com

All requests require the header: x-api-key: YOUR_API_KEY

There are six core endpoints:

Endpoint What It Returns
/drug/search Drug lookup by name (brand/generic)
/drug/adverse-events FAERS adverse event reports
/drug/label Full prescribing info / warnings
/device/recalls FDA device recall database
/enforcement Drug enforcement actions and recalls
/health API status check

Step 1: Explore Enforcement Actions

Enforcement actions are the bread and butter of any compliance alert system. These cover recalls, market withdrawals, and import alerts.

curl -s "https://fda-drug-safety-api.onrender.com/enforcement?limit=3" \
  -H "x-api-key: YOUR_API_KEY"
Enter fullscreen mode Exit fullscreen mode

Sample response:

{
  "total_found": 17681,
  "results": [
    {
      "recall_number": "D-0115-2026",
      "recall_initiation_date": "20251015",
      "classification": "Class II",
      "product_description": "Semaglutide Injection, 10 mg/4 mL...",
      "reason": "Lack of Assurance of Sterility",
      "recalling_firm": "ProRx LLC",
      "state": "PA",
      "status": "Ongoing",
      "voluntary_mandated": "Voluntary: Firm initiated",
      "distribution_pattern": "TX and UT"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Notice the classification field — Class I is the most serious (risk of serious injury or death), Class II is a possible temporary health consequence, Class III is unlikely to cause harm. Your alert system should treat Class I events as immediate priority.


Step 2: Monitor Device Recalls

Medical device recalls affect hospitals, surgical centers, and any company with devices in their supply chain. Pull the latest:

curl -s "https://fda-drug-safety-api.onrender.com/device/recalls?limit=5" \
  -H "x-api-key: YOUR_API_KEY"
Enter fullscreen mode Exit fullscreen mode

Filter by keyword to track specific device categories relevant to your organization:

curl -s "https://fda-drug-safety-api.onrender.com/device/recalls?keyword=insulin+pump&limit=5" \
  -H "x-api-key: YOUR_API_KEY"
Enter fullscreen mode Exit fullscreen mode

This is especially useful for hospital procurement teams who need to know if a device currently in service has an active recall.


Step 3: Track Adverse Event Spikes

Adverse event monitoring is critical for pharmacovigilance. The /drug/adverse-events endpoint queries the FDA Adverse Event Reporting System (FAERS), which contains over 15 million reports going back decades.

curl -s "https://fda-drug-safety-api.onrender.com/drug/adverse-events?name=aspirin&limit=5" \
  -H "x-api-key: YOUR_API_KEY"
Enter fullscreen mode Exit fullscreen mode

Sample response:

{
  "drug": "aspirin",
  "total_reports": 609473,
  "results": [
    {
      "report_id": "10003304",
      "receive_date": "20140312",
      "serious": false,
      "serious_criteria": {
        "death": false,
        "hospitalization": false,
        "life_threatening": false,
        "disability": false
      },
      "patient_sex": "female",
      "reactions": ["Drug hypersensitivity"],
      "drugs_taken": ["ASPIRIN", "OXYCONTIN", "TRAMADOL HYDROCHLORIDE"]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

For a compliance system, you'd track the serious: true count over rolling time windows. A sudden spike in serious adverse events for a drug in your portfolio is an early regulatory warning signal.


Step 4: The Python Compliance Alert Script

Here's a production-ready Python script that runs on a daily cron schedule, pulls new enforcement actions and device recalls, filters for high-severity events, and outputs a structured alert digest.

import requests
import json
from datetime import datetime

API_BASE = "https://fda-drug-safety-api.onrender.com"
API_KEY = "YOUR_API_KEY"
HEADERS = {"x-api-key": API_KEY}

# --- Configuration ---
WATCH_DRUGS = ["semaglutide", "metformin", "ozempic", "wegovy"]
WATCH_DEVICES = ["insulin pump", "pacemaker", "ventilator"]
ALERT_CLASSIFICATIONS = ["Class I"]  # Highest severity only


def get_enforcement_actions(limit=50):
    url = f"{API_BASE}/enforcement"
    resp = requests.get(url, headers=HEADERS, params={"limit": limit})
    resp.raise_for_status()
    return resp.json().get("results", [])


def get_device_recalls(keyword=None, limit=20):
    url = f"{API_BASE}/device/recalls"
    params = {"limit": limit}
    if keyword:
        params["keyword"] = keyword
    resp = requests.get(url, headers=HEADERS, params=params)
    resp.raise_for_status()
    return resp.json().get("results", [])


def get_adverse_event_count(drug_name):
    url = f"{API_BASE}/drug/adverse-events"
    resp = requests.get(url, headers=HEADERS, params={"name": drug_name, "limit": 1})
    resp.raise_for_status()
    return resp.json().get("total_reports", 0)


def filter_high_severity(enforcement_actions):
    return [
        action for action in enforcement_actions
        if action.get("classification") in ALERT_CLASSIFICATIONS
        and action.get("status") == "Ongoing"
    ]


def build_compliance_report():
    report = {
        "generated_at": datetime.utcnow().isoformat(),
        "high_severity_enforcement": [],
        "device_recall_alerts": [],
        "adverse_event_counts": {}
    }

    # 1. Enforcement actions — filter for Class I
    all_actions = get_enforcement_actions(limit=100)
    report["high_severity_enforcement"] = filter_high_severity(all_actions)

    # 2. Device recalls for watched device categories
    for keyword in WATCH_DEVICES:
        recalls = get_device_recalls(keyword=keyword, limit=5)
        report["device_recall_alerts"].extend(
            [{**r, "_matched_keyword": keyword} for r in recalls]
        )

    # 3. Adverse event totals for watched drugs
    for drug in WATCH_DRUGS:
        report["adverse_event_counts"][drug] = get_adverse_event_count(drug)

    return report


def format_digest(report):
    lines = [
        f"FDA Compliance Digest — {report['generated_at'][:10]}",
        "=" * 50,
        f"HIGH-SEVERITY ENFORCEMENT ({len(report['high_severity_enforcement'])} Class I, Ongoing)",
    ]
    for action in report["high_severity_enforcement"][:5]:
        lines.append(f"  [{action.get('classification')}] {action.get('recalling_firm')}")
        lines.append(f"  Product: {str(action.get('product_description', ''))[:80]}...")
        lines.append(f"  Reason:  {str(action.get('reason', ''))[:80]}...")
        lines.append("")

    lines.append(f"DEVICE RECALLS ({len(report['device_recall_alerts'])} matched)")
    for recall in report["device_recall_alerts"][:5]:
        lines.append(f"  [{recall.get('_matched_keyword')}] {str(recall.get('product_description', ''))[:80]}...")
        lines.append("")

    lines.append("ADVERSE EVENT TOTALS")
    for drug, count in report["adverse_event_counts"].items():
        lines.append(f"  {drug.title()}: {count:,} reports")

    return "\n".join(lines)


if __name__ == "__main__":
    report = build_compliance_report()

    # Save JSON snapshot
    filename = f"compliance_{datetime.utcnow().strftime('%Y%m%d')}.json"
    with open(filename, "w") as f:
        json.dump(report, f, indent=2)

    digest = format_digest(report)
    print(digest)

    # Plug in your delivery layer:
    # requests.post(SLACK_WEBHOOK, json={"text": digest})          # Slack
    # sendgrid.send(to="team@yourco.com", body=digest)             # Email
    # requests.post(PAGERDUTY_URL, json={"payload": digest})       # PagerDuty (Class I)
Enter fullscreen mode Exit fullscreen mode

Step 5: Automate with Cron or a Serverless Scheduler

# Run every morning at 7am UTC
0 7 * * * cd /opt/compliance && python3 fda_compliance_monitor.py >> logs/fda.log 2>&1
Enter fullscreen mode Exit fullscreen mode

Or deploy serverlessly:

  • AWS Lambda + EventBridge (free tier easily covers daily runs)
  • Railway.app cron job (one-click deploy from GitHub)
  • GitHub Actions scheduled workflow (completely free)

The API is stateless and fast — a complete compliance sweep takes under 5 seconds.


What to Build on Top of This

Once the data pipeline is running, real value comes from enrichment and routing:

  • Slack alerts — Route Class I recalls to #compliance-alerts the moment they appear
  • Competitor monitoring — Watch enforcement actions by specific firm names
  • Historical trending — Store adverse event counts in Postgres, alert on weekly spikes > 20%
  • Regulatory dashboard — Feed Metabase or Grafana for a visual compliance calendar
  • Portfolio risk scoring — Aggregate enforcement exposure across all drugs a pharma company manufactures (useful for investors and M&A due diligence)

Get API Access

The FDA Drug & Safety API is available on RapidAPI — search "FDA Drug Safety API" to find the listing, review usage tiers, and get your API key.

Direct API base: https://fda-drug-safety-api.onrender.com

All data is sourced from openFDA (public domain). The API provides a clean, normalized abstraction layer so you spend time building — not wrestling with raw openFDA pagination, field normalization, and response inconsistencies.


Stay in the Loop

Building at the intersection of AI, automation, and health data? I publish weekly breakdowns of tools, APIs, and business opportunities worth knowing about.

Get weekly AI business & automation insights → AI Business Trends on Substack


Built something cool with this API? Drop it in the comments — especially if you've wired it to Slack or a compliance dashboard.

Top comments (0)