Lead generation
openFDA Drug Labels (SPL) Scraper
Export the openFDA Structured Product Labeling (SPL) drug-label corpus as clean, flat rows — filterable by brand name, generic name, manufacturer, product NDC, or route, with section-level control over which label content (active ingredient, warnings, dosage, and more) lands in your dataset as JSON, CSV, or Excel.
Free Apify credit covers a first run. No credit card to try.
What this Actor 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 rotation —
curl-cffiimpersonates 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.
Input
Paste this into the Apify Console, or send it as the run input over the API. Proxy settings are on by default; you rarely need to touch them.
| Field | Type | Required | What it does |
|---|---|---|---|
brandName | string | no | Filter: brand name (matches openfda.brand_name). Only field with a prefill value in this Actor — combine with other filters cautiously since all set filters are ANDed together. |
genericName | string | no | Filter: generic name (matches openfda.generic_name). |
manufacturerName | string | no | Filter: manufacturer name (matches openfda.manufacturer_name). |
productNdc | string | no | Filter: product NDC code (matches openfda.product_ndc). |
route | string | no | Filter: administration route (matches openfda.route), e.g. ORAL. |
searchQuery | string | no | Raw openFDA search expression, ANDed with the structured filters above (same convention as fda-510k-clearances-scraper). Leave empty to skip. |
fields | array | no | Which label content sections to populate in each output row. openfda identity fields (brand/generic name, manufacturer, NDC, route, substance, application number) and id/set_id/version/effective_time are always… |
maxResults | integer | no | Stop after this many records. Each record is one billed result row. |
{
"brandName": "Ibuprofen",
"maxResults": 3,
"proxyConfiguration": {
"useApifyProxy": false
}
} Output
One row per result, schema-validated before it is written. Export JSON, CSV, Excel or XML from the run, or read it over the API.
idset_idversioneffective_timebrand_namegeneric_namemanufacturer_nameproduct_ndcproduct_typeroutesubstance_nameapplication_numberactive_ingredientpurposeindications_and_usagewarnings
{
"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
| Event | Price | When |
|---|---|---|
| Actor start | $0.20 | Once per run, covers warm-up and proxy session setup. |
| Result emitted | $0.0030 | Per result written to the dataset. |
You pay only for results that land. Cap any run with maxTotalChargeUsd. See pricing & billing for worked examples.
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?
Why are so many fields null on my rows?
What's the difference between this and the other openFDA Actors?
Ready to run it?
Open the listing on Apify, paste the input above, and watch rows land. If it ever breaks, it is our problem before it is yours.
Related Actors