FDA Orange Book Patents & Exclusivity Scraper
Pricing
from $14.18 / 1,000 drug product results
FDA Orange Book Patents & Exclusivity Scraper
Scrape the FDA Orange Book: approved drug products joined to their patents and marketing exclusivity, with patent numbers, expiry dates, use codes and generic-entry / patent-cliff dates. Filter by ingredient, brand, applicant or expiry. Export JSON, CSV or Excel.
Pricing
from $14.18 / 1,000 drug product results
Rating
0.0
(0)
Developer
Scrapers Lat
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
FDA Orange Book Patents & Exclusivity Scraper
Here is one real result, with every field the actor returns:
{"ingredient": "ATORVASTATIN CALCIUM","tradeName": "ATORVALIQ","applicant": "CMP DEV LLC","applicantFullName": "CMP DEVELOPMENT LLC","strength": "20MG/5ML","dosageForm": "SUSPENSION","route": "ORAL","applType": "NDA - New Drug (brand)","applTypeCode": "N","applNo": "213260","productNo": "001","teCode": null,"approvalDate": "2023-02-01","approvalDateText": "Feb 1, 2023","referenceListedDrug": true,"referenceStandard": true,"marketingStatus": "Prescription","hasPatents": true,"patentCount": 7,"exclusivityCount": 0,"earliestPatentExpiry": "2037-06-07","latestPatentExpiry": "2037-06-07","patents": [{"patentNo": "11654106","expireDate": "2037-06-07","expireDateText": "Jun 7, 2037","drugSubstance": false,"drugProduct": true,"patentUseCode": "U-3612","delisted": false,"submissionDate": "2023-06-01"}],"exclusivity": null,"orangeBookUrl": "https://www.accessdata.fda.gov/scripts/cder/ob/results_product.cfm?Appl_Type=n&Appl_No=213260","aiPatentCliff": null,"dataFileDate": "2026-08-14","source": "FDA Orange Book","observedAt": "2026-08-20T15:57:53.743Z","error": null}
The most complete FDA Orange Book scraper available. It returns every product the Orange Book lists, joined to its patents and marketing exclusivity, with patent numbers, expiry dates, drug-substance and drug-product flags and use codes, plus derived fields (earliestPatentExpiry, latestPatentExpiry, patentCount, hasPatents), and it gives you eight filters to target exactly the drugs and patent-cliff windows you need.
📥 Input · 📤 Output · 💰 Pricing · ▶️ Examples
Table of contents
- What it does
- Quickstart
- Input reference
- Output reference
- Example output record
- Run via API and CLI
- Fetch results
- Billing and limits
- FAQ and troubleshooting
What it does
The actor reads the current FDA Orange Book (Approved Drug Products with Therapeutic Equivalence Evaluations) data file, joins each approved drug product to its listed patents and marketing exclusivity by application and product number, applies the filters you pass, and writes one normalized record per product to the run's dataset.
The uniquely valuable part is the patent and exclusivity layer. For every product you get the full list of Orange Book patents (patent number, expiry date, drug-substance flag, drug-product flag, use code, delist flag, submission date) and every exclusivity entry (code and date), plus derived earliestPatentExpiry and latestPatentExpiry so you can rank drugs by patent cliff without extra parsing. That is the data that drives generic-entry timing, patent-cliff models, paragraph-IV strategy and pharma investment analysis.
Dates are normalized to YYYY-MM-DD (the original printed text is kept alongside), missing source values are returned as null, and each record names the exact Orange Book data-file date it was drawn from.
Quickstart
Open the actor, paste this into the input, and press Run. It returns up to 10 atorvastatin products that list patents.
{"ingredient": "atorvastatin","hasPatents": true,"maxResults": 10}
Every input field is optional. Combine filters to narrow the set, for example a patentExpiresAfter / patentExpiresBefore window to find drugs whose patents fall due in a target period.
Input reference
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
ingredient | string | no | (empty) | Active ingredient contains this text, case-insensitive, for example atorvastatin, semaglutide, apixaban. |
tradeName | string | no | (empty) | Trade / brand name contains this text, for example Lipitor, Eliquis, Ozempic. |
applicant | string | no | (empty) | Applicant / holder name contains this text, for example Pfizer, Teva, Novartis. Matches the short and full name. |
applNo | string | no | (empty) | Exact FDA application number, with or without its N/A prefix, for example 020702 or NDA020702. |
teCode | string | no | (empty) | Exact therapeutic equivalence code, for example AB, AP, BX. AB products are substitutable generics. |
hasPatents | boolean | no | false | When on, return only products that list at least one Orange Book patent. |
patentExpiresAfter | string | no | (empty) | Return only products with at least one patent expiring on or after this date (YYYY-MM-DD). |
patentExpiresBefore | string | no | (empty) | Return only products with at least one patent expiring on or before this date (YYYY-MM-DD). |
maxResults | integer | no | 10 | Maximum drug product records to return. One drug can yield several product rows (one per strength). Free Apify plans are capped at 10. |
withAiPatentCliff | boolean | no | false | Paid add-on. For each product that lists patents, generate an AI patent-cliff read (generic-entry outlook, key blocking patents, risk notes). Disabled for free plans. |
Filters combine with logical AND. With an empty input the actor returns the first products in the current data file, up to maxResults.
Output reference
One dataset item per drug product. Types: string, integer, boolean, array, object, or null when the source value is absent.
| Field | Type | Description |
|---|---|---|
ingredient | string | Active ingredient(s) of the product. |
tradeName | string | Trade / brand name. |
applicant | string | Applicant / holder short name. |
applicantFullName | string | Applicant full legal name. |
strength | string | Product strength. |
dosageForm | string | Dosage form, for example TABLET, SUSPENSION, INJECTION. |
route | string | Route of administration, for example ORAL, INTRAVENOUS. |
applType | string | Application type in words: NDA - New Drug (brand) or ANDA - Generic. |
applTypeCode | string | Raw application type code: N (NDA) or A (ANDA). |
applNo | string | FDA application number. |
productNo | string | Product number within the application. |
teCode | string | Therapeutic equivalence code, or null when not rated. |
approvalDate | string | Approval date (YYYY-MM-DD), or null when approved before 1982. |
approvalDateText | string | Approval date as printed in the source, for example Feb 1, 2023. |
referenceListedDrug | boolean | Whether the product is a Reference Listed Drug (RLD). |
referenceStandard | boolean | Whether the product is a Reference Standard (RS). |
marketingStatus | string | Prescription, Over-the-counter, or Discontinued. |
hasPatents | boolean | Whether the product lists any Orange Book patent. |
patentCount | integer | Number of listed patents. |
exclusivityCount | integer | Number of exclusivity entries. |
earliestPatentExpiry | string | Earliest listed patent expiry (YYYY-MM-DD), or null. |
latestPatentExpiry | string | Latest listed patent expiry (YYYY-MM-DD), or null. |
patents | array | Listed patents, each with patentNo, expireDate, expireDateText, drugSubstance, drugProduct, patentUseCode, delisted, submissionDate. null when none. |
exclusivity | array | Marketing exclusivity entries, each with exclusivityCode, exclusivityDate, exclusivityDateText. null when none. |
orangeBookUrl | string | Link to the product's Orange Book page. |
aiPatentCliff | object | AI patent-cliff analysis when the add-on is enabled, otherwise null. |
dataFileDate | string | Date of the Orange Book data file the record was drawn from. |
source | string | Always FDA Orange Book. |
observedAt | string | ISO 8601 timestamp of when the record was collected. |
error | string | null on success. On a failed run a single item with a populated error field is written instead. |
Example output record
Real record from a live run (input {"ingredient":"atorvastatin","hasPatents":true,"maxResults":10}), showing the full patent list:
{"ingredient": "ATORVASTATIN CALCIUM","tradeName": "ATORVALIQ","applicant": "CMP DEV LLC","applicantFullName": "CMP DEVELOPMENT LLC","strength": "20MG/5ML","dosageForm": "SUSPENSION","route": "ORAL","applType": "NDA - New Drug (brand)","applNo": "213260","productNo": "001","approvalDate": "2023-02-01","referenceListedDrug": true,"marketingStatus": "Prescription","hasPatents": true,"patentCount": 7,"earliestPatentExpiry": "2037-06-07","latestPatentExpiry": "2037-06-07","patents": [{ "patentNo": "11654106", "expireDate": "2037-06-07", "drugSubstance": false, "drugProduct": true, "patentUseCode": "U-3612", "delisted": false, "submissionDate": "2023-06-01" },{ "patentNo": "11925704", "expireDate": "2037-06-07", "drugSubstance": false, "drugProduct": true, "patentUseCode": "U-3853", "delisted": false, "submissionDate": "2024-03-25" }],"exclusivity": null,"orangeBookUrl": "https://www.accessdata.fda.gov/scripts/cder/ob/results_product.cfm?Appl_Type=n&Appl_No=213260","dataFileDate": "2026-08-14","source": "FDA Orange Book","observedAt": "2026-08-20T15:57:53.743Z","error": null}
With withAiPatentCliff enabled, each product that lists patents also gets an aiPatentCliff object, for example:
{"aiPatentCliff": {"genericEntryOutlook": "Generic competition can realistically enter after the earliest patent on November 8, 2026, but may be delayed until February 2, 2037 due to additional patents.","keyPatents": ["10722471", "9388134", "8877938"],"riskNotes": "No exclusivities are listed that would further delay generic entry, but multiple patents may pose challenges for generic manufacturers."}}
Run via API and CLI
Start a run and wait for it to finish, then read the dataset. Replace <TOKEN> with your Apify API token.
Run synchronously and get dataset items in one call:
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~fda-orange-book-patents-scraper/run-sync-get-dataset-items?token=<TOKEN>" \-H "Content-Type: application/json" \-d '{"ingredient":"apixaban","hasPatents":true,"maxResults":25}'
Start a run asynchronously:
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~fda-orange-book-patents-scraper/runs?token=<TOKEN>" \-H "Content-Type: application/json" \-d '{"patentExpiresAfter":"2027-01-01","patentExpiresBefore":"2030-12-31","maxResults":100}'
Apify CLI:
apify call scrapers_lat/fda-orange-book-patents-scraper \--input '{"tradeName":"eliquis","hasPatents":true}'
Fetch results
Every run writes to a dataset. Fetch items as JSON, CSV, or Excel by changing format:
# JSONcurl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=json"# CSVcurl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=csv"# Paginate large datasetscurl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&offset=1000&limit=1000"
<DATASET_ID> is returned as defaultDatasetId in the run object. Use offset and limit to page through large result sets. clean=true drops empty and internal fields.
Billing and limits
- Pay per result. You are charged per drug product record returned (
resultevent), plus a small one-timeActor startfee per run. See the pricing tab for current prices. - AI patent-cliff add-on. When you enable
withAiPatentCliff, theAI patent-cliff analysisevent is charged once per product, only when the analysis is produced. Off by default and disabled for free plans. - No charge on failure. If a run errors, the actor writes a single item with a populated
errorfield and does not charge for it. Empty runs cost nothing. - Spend cap respected. Set
maxTotalChargeUsdon the run; once reached, the actor stops emitting and charging further billable results. - Free Apify plans are capped at 10 records per run. Upgrade for higher
maxResults.
FAQ and troubleshooting
A run returned 0 records. Why?
The filter combination matched nothing in the current data file. Loosen filters (for example remove hasPatents or widen the expiry window), or check the spelling of the ingredient or trade name. Zero-result runs are not charged.
How do I find drugs facing a patent cliff in a given window?
Set patentExpiresAfter and patentExpiresBefore to the window you care about and hasPatents to true. Rank the results by earliestPatentExpiry.
Why do some products have no patents or no exclusivity?
Older drugs and many generics have no listed patents or exclusivity, so those fields are null. The Orange Book only lists patents and exclusivity that a sponsor has submitted for the product.
What is the difference between earliestPatentExpiry and latestPatentExpiry?
They are the minimum and maximum expiry dates across the product's listed patents. The earliest is the first date a patent barrier can fall; the latest is when the last listed patent expires.
Why is teCode null?
The product is not therapeutically rated (for example a single-source innovator with no rated equivalent). Missing source values are returned as null, never invented.
Is this an official FDA tool? No. This actor is independent and has no affiliation with the FDA. It reads only data that the FDA publishes publicly in the Orange Book data file. Use it in accordance with the FDA terms of use.
Related scrapers
- FDA Drug Approvals Scraper: Drugs@FDA NDA, ANDA and BLA approvals with sponsors and submission history.
- FDA NDC Drug Directory Scraper: National Drug Code directory of marketed drug products.
- openFDA Drug Labels Scraper: Structured drug labeling (SPL) content.
- USPTO Patent Assignments Scraper: US patent assignment and ownership records.
- SEC EDGAR Company Filings Scraper: SEC filings by ticker or CIK.
More scrapers at scrapers.lat
Built and maintained by scrapers.lat, where we publish scrapers for US and Latin American public platforms: company registries, government data, finance, e-commerce and more. Browse the catalog or request a custom scraper at scrapers.lat.
Independent tool, not affiliated with the FDA. Accesses only publicly available FDA Orange Book data. Use in accordance with the FDA terms of use.
