openFDA Drug Labels (SPL) Scraper avatar

openFDA Drug Labels (SPL) Scraper

Pricing

Pay per event

Go to Apify Store
openFDA Drug Labels (SPL) Scraper

openFDA Drug Labels (SPL) Scraper

Export the openFDA Structured Product Labeling drug-label corpus as clean, flat rows — filterable by brand name, generic name, manufacturer, product NDC, or route, with control over which label sections (active ingredient, warnings, dosage, and more) land in your dataset as JSON, CSV, or Excel.

Pricing

Pay per event

Rating

0.0

(0)

Developer

DevilScrapes

DevilScrapes

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

19 hours ago

Last modified

Categories

Share


🎯 What this scrapes

openFDA's /drug/label.json endpoint is the only place the FDA publishes the full structured product label (SPL) text — active ingredient, purpose, indications, warnings, dosage, and eleven more official sections — for every drug on the US market, keyed by brand name, generic name, manufacturer, NDC code, or route. The raw API ships every section as full paragraphs whether you need them or not, hides an intermittent cold-query 500, and caps pagination at 25 000 skipped records. This Actor normalises all of that into one dependable row shape with a section-level field-selection toggle, so a compliance or competitive-intel watchlist becomes a spreadsheet instead of a scripting project.

🔥 What we handle for you

  • 🛡️ Browser fingerprint rotationcurl-cffi impersonates real Chrome / Firefox / Safari TLS handshakes on every request.
  • 🔁 Retries with exponential backoff on 408 / 429 / 5xx, including openFDA's documented cold-query timeouts — up to 5 attempts per page.
  • 🧱 Stops cleanly at openFDA's pagination ceiling instead of looping on a 400, and fails loud (not silently empty) if the endpoint goes down for 3 consecutive pages.
  • 🧊 Per-record fault isolation — one malformed record never takes down the run; we skip it, log it, and keep paging.
  • 🧊 Section-level field selection — pick only the label sections you need; unset sections come back null instead of billing you for paragraphs you'll never read.
  • 💰 Pay-Per-Event pricing — you only pay for results that hit your dataset. No data, no charge.

💡 Use cases

  • Pull the official label text (warnings, dosage, active ingredients) for every SKU your marketplace or pharmacy sells, and flag listings whose copy drifts from the FDA's own record.
  • Track how a manufacturer's label language changes across label versions for a drug you compete with.
  • Build a regulatory/competitive-intel watchlist filtered by brand, generic name, manufacturer, NDC, or route.
  • Feed a research dataset of OTC vs. prescription label sections (active ingredient, purpose, warnings) across thousands of records.

⚙️ How to use it

  1. Click Try for free at the top of the page.
  2. Fill in the input form — most fields have sensible defaults.
  3. Click Start. Output streams into the run's dataset.
  4. Export from Storage → Dataset as JSON, CSV, or Excel — or fetch via the API.

📥 Input

FieldTypeRequiredDefaultNotes
brandNamestringno'Ibuprofen'Filter: brand name (matches openfda.brand_name). Only field with a prefill value in this Actor — combine with other…
genericNamestringno'—'Filter: generic name (matches openfda.generic_name).
manufacturerNamestringno'—'Filter: manufacturer name (matches openfda.manufacturer_name).
productNdcstringno'—'Filter: product NDC code (matches openfda.product_ndc).
routestringno'—'Filter: administration route (matches openfda.route), e.g. ORAL.
searchQuerystringno'—'Raw openFDA search expression, ANDed with the structured filters above (same convention as…
fieldsarrayno['active_ingredient', 'purpose', 'indications_and_usage', 'warnings']Which label content sections to populate in each output row. openfda identity fields (brand/generic name, manufacturer,…
maxResultsintegerno100Stop after this many records. Each record is one billed result row.
proxyConfigurationobjectno{'useApifyProxy': False}openFDA is a public keyless government API and does not need a proxy. Leave this off unless your account requires…

Example input

{
"brandName": "Ibuprofen",
"maxResults": 3,
"proxyConfiguration": {
"useApifyProxy": false
}
}

📤 Output

Every row is one dataset item.

FieldTypeNotes
idstringopenFDA record identifier.
set_idstringopenFDA label set identifier (groups versions of the same label).
versionstringLabel version number within its set_id.
effective_timestringLabel effective date, YYYYMMDD.
brand_namestringBrand name (openfda.brand_name[0]).
generic_namestringGeneric name (openfda.generic_name[0]).
manufacturer_namestringManufacturer name (openfda.manufacturer_name[0]).
product_ndcarrayProduct NDC code(s).
product_typestringProduct type, e.g. HUMAN OTC DRUG.
routearrayAdministration route(s).
substance_namearrayActive substance name(s).
application_numberstringFDA application number, e.g. part341.
active_ingredientstringActive ingredient(s) and strength. Null unless requested via fields and present on the source label.
purposestringStated purpose of the product (OTC labels). Null unless requested via fields and present on the source label.
indications_and_usagestringWhat the product is indicated/used for. Null unless requested via fields and present on the source label.
warningsstringWarnings section text. Null unless requested via fields and present on the source label.
do_not_usestringDo-not-use contraindications. Null unless requested via fields and present on the source label.
ask_doctorstringAsk-a-doctor-before-use guidance. Null unless requested via fields and present on the source label.
ask_doctor_or_pharmaciststringAsk-a-doctor-or-pharmacist guidance. Null unless requested via fields and present on the source label.
when_usingstringGuidance for while using the product. Null unless requested via fields and present on the source label.
stop_usestringConditions under which to stop use. Null unless requested via fields and present on the source label.
pregnancy_or_breast_feedingstringPregnancy/breastfeeding guidance. Null unless requested via fields and present on the source label.
keep_out_of_reach_of_childrenstringChild-safety storage warning. Null unless requested via fields and present on the source label.
dosage_and_administrationstringDosage and administration instructions. Null unless requested via fields and present on the source label.
storage_and_handlingstringStorage and handling instructions. Null unless requested via fields and present on the source label.
inactive_ingredientstringInactive ingredient(s) list. Null unless requested via fields and present on the source label.
questionsstringQuestions/contact section text. Null unless requested via fields and present on the source label.
package_label_principal_display_panelstringPrincipal display panel text. Null unless requested via fields and present on the source label.

Example output

{
"id": "d3f8a2b1-9c44-4e11-8a77-2f6b1c9e0a12",
"set_id": "b4e2f9c0-1234-4a56-9abc-def012345678",
"version": "3",
"effective_time": "20240115",
"brand_name": "IBUPROFEN",
"generic_name": "IBUPROFEN",
"manufacturer_name": "Acme Pharmaceuticals Inc.",
"product_ndc": [
"12345-678-90"
],
"product_type": "HUMAN OTC DRUG",
"route": [
"ORAL"
],
"substance_name": [
"IBUPROFEN"
],
"application_number": "part341",
"active_ingredient": "Ibuprofen 200 mg (NSAID)",
"purpose": "Pain reliever/fever reducer",
"indications_and_usage": "temporarily relieves minor aches and pains...",
"warnings": "Allergy alert: Ibuprofen may cause a severe allergic reaction...",
"do_not_use": null,
"ask_doctor": null,
"ask_doctor_or_pharmacist": null,
"when_using": null,
"stop_use": null,
"pregnancy_or_breast_feeding": null,
"keep_out_of_reach_of_children": null,
"dosage_and_administration": null,
"storage_and_handling": null,
"inactive_ingredient": null,
"questions": null,
"package_label_principal_display_panel": null
}

💰 Pricing

Pay-Per-Event — you pay only when these events fire:

EventUSDWhat it is
actor-start$0.2One-off warm-up charge per run
result$0.003Per dataset item

Example: 1 000 results at the rates above ≈ $3.20. No subscription, no minimum, no card to start — Apify gives every new account $5 of free credit.

🚧 Limitations

  • openFDA caps pagination at 25 000 records per query on this endpoint — narrow the search to go deeper.
  • Filter values aren't escaped for embedded double-quote characters — avoid quotes inside brand, generic, manufacturer, NDC, or route filters.
  • This Actor emits the current label record as returned by openFDA for a given query; it does not walk historical version history for a given set_id.

❓ FAQ

Do I need an API key?

No. openFDA serves label data keylessly; the Actor stays inside the anonymous rate limit (240 requests/min, 1000/day per IP).

Why are so many fields null on my rows?

Two reasons, both intentional: a content section is null when you didn't select it in fields, and it's also null when the source label simply never populated that section (most prescription-only labels skip OTC-style sections like do_not_use or ask_doctor entirely).

What's the difference between this and the other openFDA Actors?

This Actor is the only one covering /drug/label.json — the full structured product label text. openfda-adverse-events-scraper covers FAERS adverse-event reports, fda-510k-clearances-scraper covers device clearances, and fda-recalls-scraper covers recalls/enforcement actions. No output-row overlap between any of them.

💬 Your feedback

Spotted a bug, hit a weird edge case, or need a new field? Open an issue on the Actor's Issues tab on Apify Console — we ship fixes weekly and we read every report.