openfda-database — Claude Code skill: what it does, how to install
Queries, counts and downloads records from the openFDA API. Use it for FDA safety events, recalls, labels, NDC lookups and regulatory data searches.
npx skills add google-deepmind/science-skills --skill openfda-database -a claude-code
npx skills add google-deepmind/science-skills --skill openfda_database -a claude-codeWhat openfda-database does
This skill queries 28 openFDA API endpoints and writes responses to JSON files. It covers FDA datasets for drugs, devices, food, tobacco, cosmetics, veterinary products, substances and transparency, including recalls, approvals, shortages and 510(k) clearances.
All operations go through uv run scripts/openfda_query.py. Its search, count and download subcommands retrieve records, aggregate a field, or fetch multiple pages; every call requires --output <file> so large responses are stored outside the agent context.
You need uv, a .env file in the home directory, and an openFDA terms notice in .licenses/openfda_database_LICENSE.txt. FDA_API_KEY is optional, but the keyless allowance is 1,000 daily requests rather than 120,000 per key. For multi-query work, an API key is effectively required because an agent can exhaust the smaller limit in one session. Set the key before a multi-query run.
What it helps with
- search adverse event reports for a drug
- count recurring reactions in matching records
- download several result pages into JSON
- look up a product by NDC
- find FDA labels or recall records
Example prompts for the agent
- Search adverse events for aspirin and save the JSON to
/tmp/fda_results.json. - Count reactions for aspirin in the
drugeventendpoint and write the result to/tmp/aspirin_reactions.json. - Look up NDC
51285-092and save the response to/tmp/ndc.json.
How to install openfda-database
1Skills CLI (Vercel)
npx skills add google-deepmind/science-skills --skill openfda-database -a claude-codenpx skills add google-deepmind/science-skills --skill openfda_database -a claude-code2Manually: put the files in place
~/.claude/skills/openfda_database/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/openfda_database/
1Skills CLI (Vercel)
npx skills add google-deepmind/science-skills --skill openfda_database -a codex2Manually: put the files in place
.agents/skills/openfda_database/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add google-deepmind/science-skills --skill openfda_database -a cursor2Manually: put the files in place
.cursor/skills/openfda_database/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install google-deepmind/science-skills openfda_database2Manually: put the files in place
.github/skills/openfda_database/SKILL.md1Skills CLI (Vercel)
npx skills add google-deepmind/science-skills --skill openfda_database -a gemini-cli2Platform CLI
gemini skills install https://github.com/google-deepmind/science-skills --path skills/openfda_databaseManually: put the files in place
.devin/skills/openfda_database/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add google-deepmind/science-skills --skill openfda_database -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about openfda-database
How do I install openfda-database in Codex?
Run npx skills add google-deepmind/science-skills --skill openfda_database -a codex, then open .agents/skills/openfda_database/SKILL.md.
What does openfda-database do?
The skill sends requests to the openFDA API through a helper script. It can search records, count field values, and download paginated results as JSON.
Do I need an API key for openfda-database?
The skill runs without a key, with a limit of 1,000 daily requests per IP. With FDA_API_KEY, the daily limit is 120,000 requests per key; set it in .env before multi-query workflows.
Source text
SKILL.md · Apache-2.0
---
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:**
```bash
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.
```bash
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:
```json
{"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](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.
```bash
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.
```bash
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.
```bash
# 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:
```bash
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.
```bash
# 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
- **Query syntax and all endpoints**: See
[references/api_endpoints.md](references/api_endpoints.md) for field names,
search syntax, date ranges, and boolean operators.
## 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](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.
© google-deepmind · Apache-2.0 · google-deepmind/science-skills