Reference file for the openFDA API skill. Do not trigger directly. Contains endpoint field details, composite workflows, pagination, response schemas, and troubleshooting. Loaded on demand by the main openfda-api skill.
patient.drug.medicinalproduct - Drug name as reportedpatient.drug.openfda.brand_name / .generic_name - Standardized namespatient.reaction.reactionmeddrapt - Reaction (MedDRA PT)serious - 1=serious, 2=not seriousseriousnessdeath - 1=resulted in deathreceivedate - Date FDA received report (YYYYMMDD)occurcountry - Country codepatient.drug.drugcharacterization - 1=suspect, 2=concomitant, 3=interactingpatient.drug.drugindication - Reason drug was takenopenfda.brand_name / .generic_name / .manufacturer_nameopenfda.application_number - NDA/ANDAopenfda.product_type - "HUMAN PRESCRIPTION DRUG" or "HUMAN OTC DRUG"openfda.route / .substance_name / .rxcui / .spl_set_idboxed_warning, indications_and_usage, contraindications, warnings_and_precautions, adverse_reactions, drug_interactions, dosage_and_administrationeffective_time - Label date (YYYYMMDD)application_number - NDA/ANDA/BLAsponsor_name - Sponsor companyopenfda.brand_name / .generic_nameproducts[].brand_name / .dosage_form / .route / .active_ingredients / .te_codesubmissions[].submission_type (ORIG, SUPPL) / .submission_status (AP) / .submission_status_datesponsor_name.exact doesn't work for count; use openfda.manufacturer_name.exactproduct_ndc / brand_name / generic_name / labeler_nameactive_ingredients (array with name/strength) / dosage_form / routemarketing_category (NDA, ANDA, BLA, OTC) / application_numberpackaging - NDC packaging variantsrecall_number / reason_for_recall / classification (Class I/II/III)status / product_description / recalling_firmvoluntary_mandated / report_date / recall_initiation_datedistribution_pattern / openfda.brand_namedevice[].generic_name / .brand_name / .manufacturer_d_name / .device_report_product_codemdr_text[].text - Narrative; .text_type_code - "Description of Event", "Manufacturer Narrative"event_type - Malfunction, Injury, Death, Otherdate_received (YYYY-MM-DD) / date_of_event / report_number / source_typek_number / device_name / applicant / decision_datedecision_description - SESE (substantially equivalent), etc.product_code / clearance_type (Traditional, Special, Abbreviated)advisory_committee / advisory_committee_descriptionpma_number / supplement_number / applicant / generic_name / trade_namedecision_date / decision_code (APPR) / product_code / advisory_committeeproduct_code (3-letter) / device_name / device_class (1/2/3)medical_specialty / medical_specialty_description / regulation_numberdefinition / implant_flag / life_sustain_support_flag / gmp_exempt_flagbrand_name / catalog_number / company_name / device_descriptionidentifiers[].id / product_codes[].code / product_codes[].namesterilization.is_sterile / mri_safety / gmdn_termsSame fields as drug/enforcement.
products[].industry_name / .name_brand / .role ("Suspect"/"Concomitant")reactions (array) / outcomes ("Death", "Hospitalization", etc.)consumer.age / .gender / date_started / report_numberSame fields as drug/enforcement.
date_submitted / tobacco_products / reported_health_problems / reported_product_problemsproprietary_name (case-sensitive) / application_number_or_citationproduct_type / package_ndc / package_ndc11 / marketing_start_date / dosage_formnames[].name - Search via names.name:TERM (case-sensitive, uppercase)unii / codes[].code / .code_system (CAS, etc.)substance_class / structure / uuid / moietiesdef safety_signal_scan(drug_name):
"""Top reactions, serious/non-serious counts, deaths, trend."""
results = {}
results["top_reactions"] = openfda_query("drug/event",
search=f"patient.drug.openfda.generic_name:{drug_name}",
count="patient.reaction.reactionmeddrapt.exact", limit=20)
for severity, label in [(1, "serious"), (2, "non_serious")]:
r = safe_query("drug/event",
search=f"patient.drug.openfda.generic_name:{drug_name}+AND+serious:{severity}", limit=1)
results[f"{label}_count"] = r.get("meta", {}).get("results", {}).get("total", 0)
r = safe_query("drug/event",
search=f"patient.drug.openfda.generic_name:{drug_name}+AND+seriousnessdeath:1", limit=1)
results["death_count"] = r.get("meta", {}).get("results", {}).get("total", 0)
results["trend"] = openfda_query("drug/event",
search=f"patient.drug.openfda.generic_name:{drug_name}", count="receivedate")
return results
import time
def compare_drug_profiles(drug_a, drug_b, n_reactions=15):
"""Compare top adverse reactions between two drugs."""
profiles = {}
for drug in [drug_a, drug_b]:
r = openfda_query("drug/event",
search=f"patient.drug.openfda.generic_name:{drug}",
count="patient.reaction.reactionmeddrapt.exact", limit=n_reactions)
profiles[drug] = {item["term"]: item["count"] for item in r.get("results", [])}
time.sleep(0.5)
return profiles
def predicate_search(product_code, limit=20):
"""Find 510(k) cleared devices for predicate identification."""
clearances = openfda_query("device/510k",
search=f"product_code:{product_code}+AND+decision_description:SESE",
limit=limit, sort="decision_date:desc")
classification = safe_query("device/classification",
search=f"product_code:{product_code}", limit=1)
return {"classification": classification.get("results", []),
"clearances": clearances.get("results", [])}
def recall_scan(product_name, categories=None):
"""Search recalls across drug, device, and food enforcement."""
if categories is None:
categories = ["drug", "device", "food"]
results = {}
for cat in categories:
try:
r = openfda_query(f"{cat}/enforcement",
search=f"product_description:{product_name}", limit=10)
results[cat] = r.get("results", [])
except Exception as e:
results[cat] = {"error": str(e)}
time.sleep(0.3)
return results
# FAERS: serious events in date range
def serious_events(drug_name, start="20240101", end="20241231", limit=10):
return openfda_query("drug/event",
search=f"patient.drug.openfda.generic_name:{drug_name}+AND+serious:1+AND+receivedate:[{start}+TO+{end}]",
limit=limit)
# Drug labeling by brand
def get_label(brand_name):
return openfda_query("drug/label", search=f'openfda.brand_name:"{brand_name}"', limit=1)
# Label by NDA/ANDA
def label_by_application(app_number):
return openfda_query("drug/label", search=f'openfda.application_number:"{app_number}"', limit=1)
# Drug approval by brand
def drug_approval(brand_name):
return openfda_query("drug/drugsfda", search=f'openfda.brand_name:"{brand_name}"', limit=5)
# NDC lookup
def lookup_ndc(ndc):
return openfda_query("drug/ndc", search=f'product_ndc:"{ndc}"', limit=1)
# Class I drug recalls
def class1_drug_recalls(start="20250101", limit=10):
return openfda_query("drug/enforcement",
search=f'classification:"Class I"+AND+report_date:[{start}+TO+20261231]', limit=limit)
# Device events by generic name
def device_events(device_name, limit=10):
return openfda_query("device/event", search=f'device.generic_name:"{device_name}"', limit=limit)
# 510(k) by applicant
def find_510k(applicant, limit=10):
return openfda_query("device/510k", search=f"applicant:{applicant}", limit=limit)
# PMA lookup
def find_pma(applicant=None, trade_name=None, limit=10):
search = f"applicant:{applicant}" if applicant else f"trade_name:{trade_name}" if trade_name else None
return openfda_query("device/pma", search=search, limit=limit)
# Device classification
def device_classification(product_code):
return openfda_query("device/classification", search=f"product_code:{product_code}", limit=5)
# UDI lookup
def udi_lookup(brand_name, limit=5):
return openfda_query("device/udi", search=f'brand_name:"{brand_name}"', limit=limit)
# Food events
def food_events(product_name, limit=10):
return openfda_query("food/event", search=f'products.name_brand:"{product_name}"', limit=limit)
Skip-based, max skip+limit = 25,000.
def paginate_results(endpoint, search, max_results=5000, page_size=100):
all_results, skip = [], 0
while skip < max_results and skip < 25000:
r = openfda_query(endpoint, search=search, limit=page_size, skip=skip)
batch = r.get("results", [])
if not batch: break
all_results.extend(batch)
total = r.get("meta", {}).get("results", {}).get("total", 0)
skip += page_size
if skip >= total: break
time.sleep(0.3)
return all_results
For >25,000 records use bulk downloads: https://open.fda.gov/data/downloads/
{"meta": {"last_updated": "2026-01-27", "results": {"skip": 0, "limit": 10, "total": 419459}},
"results": [...]}
{"results": [{"term": "NAUSEA", "count": 752669}, {"term": "FATIGUE", "count": 742320}]}
{"results": [{"time": "20240101", "count": 12345}]}
| Error | Cause | Fix |
|---|---|---|
| 404 | No matching records | Normal; use safe_query wrapper |
| 409 | Rate limit exceeded | Wait; add api_key |
| 400 "Invalid search syntax" | Malformed search | Check colons, brackets, quotes |
| Count returns single words | Missing .exact | Add .exact to text fields |
| Count returns SERVER_ERROR | Missing .exact on text field | Hard error; add .exact |
| Count returns 404 on numeric | Used .exact on numeric field | Remove .exact |
| Skip exceeds limit | skip+limit > 25,000 | Use bulk downloads |
| Wrong data in results | Wrong field path | Verify at open.fda.gov |