PluginBench
Skill
Review
Audit score 70

openfda-database

google-deepmind/science-skills

Query FDA adverse events, recalls, drug labels, and regulatory data across 28 openFDA API endpoints.

What is openfda-database?

Access the openFDA API to search, count, and download data on drugs, devices, foods, cosmetics, and other FDA-regulated products. Use this skill for safety queries, adverse event lookups, NDC searches, recall information, and regulatory compliance checks.

  • Search any of 28 openFDA endpoints (adverse events, labels, 510(k) clearances, NDC lookups, recalls, shortages, approvals)
  • Count and aggregate field values to identify top reactions, adverse events, or product characteristics
  • Download paginated results with automatic rate limiting and optional API key support
  • Handle entity resolution with .exact suffix for precise brand name and product lookups
  • Query NDC (National Drug Code) with proper escaping for hyphenated identifiers
  • Resolve MedDRA adverse event terminology and cross-reference with ontologies

How to install openfda-database

npx skills add https://github.com/google-deepmind/science-skills --skill openfda-database
Prerequisites
  • Install `uv` (Python package manager) and add to PATH
  • Register for a free FDA_API_KEY at https://open.fda.gov/apis/authentication/ (optional but recommended to avoid 1,000 request/day limit)
  • Add FDA_API_KEY to .env file in home directory using the credentials skill
  • Review openFDA license terms at https://open.fda.gov/apis/ and https://open.fda.gov/license
Claude Code
Cursor
Windsurf
Cline

How to use openfda-database

  1. 1.Run `uv run scripts/openfda_query.py search --category <category> --endpoint <endpoint> --search '<query>' --limit <n> --output <file>` to search and save results to JSON
  2. 2.Use `uv run scripts/openfda_query.py count --category <category> --endpoint <endpoint> --search '<query>' --count_field '<field>' --summary <n> --output <file>` to aggregate field values
  3. 3.Run `uv run scripts/openfda_query.py download --category <category> --endpoint <endpoint> --search '<query>' --max_pages <n> --output <file>` to fetch multiple pages of results
  4. 4.For precise product lookups, append `.exact` to field names (e.g., `openfda.brand_name.exact:"ADVIL"`)
  5. 5.For NDC searches with hyphens, enclose the code in escaped quotes: `--search 'product_ndc:"51285-092"'`
  6. 6.Read the output JSON file with jq or code; use date ranges (e.g., `receivedate:[20250101+TO+20250131]`) to limit large result sets

Use cases

Good for
  • Look up adverse event reports for a specific drug to assess safety patterns
  • Find all FDA recalls or shortages for a product category within a date range
  • Retrieve drug labeling information and active ingredients for an NDC code
  • Count the most common adverse reactions reported for a medication
  • Download comprehensive adverse event data for a therapeutic area to support research
Who it's for
  • Pharmacovigilance and drug safety researchers
  • Regulatory compliance and quality assurance teams
  • Healthcare professionals evaluating medication safety
  • Pharmaceutical and medical device companies
  • Public health researchers and epidemiologists

openfda-database FAQ

What is the daily request limit and how do I increase it?

Without an API key: 240 requests/min and 1,000 requests/day per IP. With a free FDA_API_KEY: 240 requests/min and 120,000 requests/day. Register at https://open.fda.gov/apis/authentication/ and add the key to your .env file.

Why does my NDC search return 0 results?

Hyphens in NDC codes must be escaped in quotes (e.g., `'product_ndc:"51285-092"'`). If still no results, the drug may be discontinued; try querying the `drug/label` endpoint instead.

How do I find the most common adverse reactions for a drug?

Use the `count` subcommand with `--count_field "patient.reaction.reactionmeddrapt.exact"` and `--summary 10` to get the top 10 reactions for your search query.

What should I do if a brand name search returns no results?

Try searching without the `.exact` suffix to see available brand name variants in the database, then re-query with the full exact name including any suffixes (e.g., 'TYLENOL Extra Strength').

Can I download all results for a drug at once?

Use `--all_results` to auto-paginate, but note the safety cap is 25,000 records per download. For high-volume drugs, use date ranges like `receivedate:[20250101+TO+20250131]` to limit results.

Full instructions (SKILL.md)

Source of truth, from google-deepmind/science-skills.


name: openfda-database description: > Query, search, and download data from the openFDA API for drugs, devices, foods, tobacco, cosmetics, animal and veterinary products, substances, and transparency data. Use for FDA adverse events, recalls, labeling, approvals, shortages, 510(k) clearances, NDC lookups, and any FDA safety or regulatory data query across all 28 API endpoints.

openFDA Search and Query

Prerequisites

  1. uv: Read the uv skill and follow its Setup instructions to ensure uv is installed and on PATH.
  2. User Notification: If .licenses/openfda_database_LICENSE.txt does not already exist in the workspace root directory then (1) prominently notify the user to check the terms at https://open.fda.gov/apis/ and https://open.fda.gov/license, then (2) create the file recording the notification text and timestamp.
  3. .env file: Make sure the .env file exists in your home directory. Create one if it does not exist.
  4. FDA_API_KEY (optional but recommended): Raises the daily request limit from 1,000 to 120,000. The skill works without it, but an agent can easily exhaust the keyless limit in a single session. You can register for a free key at https://open.fda.gov/apis/authentication/. You MUST use the safe credentials protocol in the credentials skill to check for and request this key if this skill looks relevant to the user's request.

Core Rules

  • Use the Wrapper: ALWAYS execute the provided helper scripts to query the database rather than accessing the database directly. The scripts automatically enforce the required rate limit gracefully.

  • Rate Limiting: Respect openFDA rate limits. Without API key: 240 requests/min, 1,000 requests/day per IP. With API key: 240 requests/min, 120,000 requests/day per key. Always set an API key before running multi-query workflows.

Warning: An automated agent can easily exhaust the 1,000-request daily limit in a single research session. Always set an API key before running multi-query workflows.

You MUST use the safe credentials protocol in the credentials skill to help the user add FDA_API_KEY to their .env file if this skill looks relevant to the user's request. The script will emit a warning to stderr if no API key is detected.

  • Always Use --output: All subcommands require --output <file> to write results to a file. This prevents large output becoming overwhelming. Use jq or code to read the output file.

  • Notification: If this skill is used, ensure this is mentioned in the output.

Utility Script

Single script for all operations:

uv run scripts/openfda_query.py {search,count,download} --output <file> [options]

1. Search

Search any of the 28 endpoints and save JSON results to a file.

uv run scripts/openfda_query.py search \
  --category drug --endpoint event \
  --search "patient.drug.medicinalproduct:aspirin" \
  --limit 5 --output /tmp/fda_results.json

Stdout prints a compact summary:

{"status": "success", "output": "/tmp/fda_results.json", "results_in_file": 5, "total_matching": 601477}

Options:

  • --output: Output file for full JSON results (required).
  • --category: API category — drug, device, food, tobacco, other, animalandveterinary, cosmetic, transparency.
  • --endpoint: Endpoint within the category (e.g., event, label, 510k). See references/api_endpoints.md for full list.
  • --search: Query string (e.g., patient.drug.medicinalproduct:aspirin+AND+serious:1).
  • --sort: Sort field and order (e.g., receivedate:desc).
  • --limit: Max results (default 10, max 1000).
  • --skip: Pagination offset (default 0).
  • --api_key: API key (also reads FDA_API_KEY env var).

2. Count

Count unique values of a field within matching results.

uv run scripts/openfda_query.py count \
  --category drug --endpoint event \
  --search "patient.drug.medicinalproduct:aspirin" \
  --count_field "patient.reaction.reactionmeddrapt.exact" \
  --summary 10 --output /tmp/aspirin_reactions.json

Stdout prints a summary with the top 5 terms. Full data is in the output file.

Additional options:

  • --count_field: Field to count (append .exact for whole-phrase counting).
  • --summary N: Return only the top N most frequent terms. Use this to avoid flooding the context with hundreds of infrequent terms.

3. Download

Download multiple pages of results to a file.

uv run scripts/openfda_query.py download \
  --category drug --endpoint event \
  --search "patient.drug.medicinalproduct:aspirin" \
  --limit 100 --max_pages 5 \
  --output /tmp/aspirin_events.json

Additional options:

  • --max_pages: Maximum pages to fetch (default 10).

  • --all_results: Automatically paginate to fetch all matching results. Safety cap of 25,000 records maximum per download to prevent runaway downloads and prevent excessive API usage.

    Tip: Common drugs can have excessive reports. Use a date range (e.g., receivedate:[20250101+TO+20250131]) to limit the volume of download.

Entity Resolution: Using .exact for Precision

When searching for specific product names, drug names, or categorical terms, always use the .exact suffix on the field to get exact-match results. Without it, the API tokenizes multi-word values and returns noisy partial matches.

# Precise: matches only "ADVIL"
uv run scripts/openfda_query.py search --category drug --endpoint label \
  --search 'openfda.brand_name.exact:"ADVIL"' \
  --limit 5 --output /tmp/advil_label.json

Note: Many brand names in the FDA database include variant suffixes (e.g., "TYLENOL Extra Strength" rather than just "TYLENOL"). If an .exact search returns 0 results, try without .exact to see the available brand name variants, then re-query with the full exact name.

The .exact suffix is also required when using --count_field to aggregate whole phrases instead of individual words.

NDC Lookups: Hyphens & Discontinued Drugs

  1. Always Quote Hyphenated NDCs: In openFDA search syntax, an unquoted hyphen (-) acts as the boolean NOT operator (e.g., 51285-092 searches for 51285 AND NOT 092). Always enclose hyphenated NDC strings in escaped double quotes:

    uv run scripts/openfda_query.py search --category drug --endpoint ndc \
      --search 'product_ndc:"51285-092"' \
      --limit 5 --output /tmp/ndc.json
    
  2. Discontinued Drugs Fallback (drug/label): The drug/ndc endpoint only contains currently active/marketed products. If a valid NDC returns 0 results in drug/ndc, query the drug/label endpoint with exact phrase quotes (--search '"51285-092"'). Note that for discontinued drugs, the openfda metadata block may be empty ({}), so read brand name, active ingredients, and labeler from the label text fields (package_label_principal_display_panel, description, or spl_product_data_elements).

MedDRA Term Resolution

openFDA adverse event data uses MedDRA (Medical Dictionary for Regulatory Activities) terms for reactions. The API reports Preferred Terms (PTs) but does not provide the MedDRA hierarchy (System Organ Class, High Level Terms, etc.).

Note: MedDRA is a proprietary ontology and is not indexed in the EMBL-EBI OLS. To approximate MedDRA hierarchy lookups, use the Human Phenotype Ontology (HP) or NCI Thesaurus (NCIT) as proxy ontologies — they cross-reference MedDRA IDs and provide parent/ancestor relationships.

# Step 1: Get top reactions from openFDA
uv run scripts/openfda_query.py count \
  --category drug --endpoint event \
  --search "patient.drug.medicinalproduct:metformin" \
  --count_field "patient.reaction.reactionmeddrapt.exact" \
  --summary 5 --output /tmp/metformin_reactions.json

# Step 2: Look up the top reaction term using a biomedical ontology service
# skill (e.g. embl-ebi-ols skill).
# MedDRA is not available in OLS; use the Human Phenotype Ontology (HP) or
# NCI Thesaurus (NCIT) as a proxy to find the hierarchical classification of
# the reaction term.

Available Endpoints (28 total)

Category to endpoint mapping:

  • drug: event, label, ndc, enforcement, drugsfda, shortages
  • device: 510k, classification, enforcement, event, pma, recall, registrationlisting, udi, covid19serology
  • food: enforcement, event
  • tobacco: problem, researchpreventionads, researchdigitalads, researchsmokefree
  • other: historicaldocument, nsde, substance, unii
  • animalandveterinary: event
  • cosmetic: event
  • transparency: crl

Reference

Recipes

Common query patterns for drugs, devices, foods, tobacco, cosmetics, animal and veterinary products, substances, transparency data, adverse events, recalls, labeling, approvals, shortages, 510(k) clearances, NDC lookups, any FDA safety or regulatory data query, and more. See references/recipes.md for the full recipes.

Workflow

  1. Search for records using search with --output. Read the output file.
  2. Use count with --summary 10 --output to summarize field distributions.
  3. Use download (with --all_results for exhaustive pulls) to fetch larger datasets.
  4. Read and analyze the output file using standard tools.
  5. For MedDRA term hierarchy questions, use a biomedical ontology service skill (e.g. EMBL-EBI OLS skill with the HP or NCIT ontology) to look up the term.