# FDA Orange Book Drug Patents & Exclusivity API (`myworkingmemory/fda-orange-book-drug-patents-exclusivity-api`) Actor

Search FDA Orange Book drug products, patents and exclusivity. Normalized records with product context, source hashes and QA. Filter by drug, applicant, application and expiration; export JSON or CSV.

- **URL**: https://apify.com/myworkingmemory/fda-orange-book-drug-patents-exclusivity-api.md
- **Developed by:** [Myworkingmemory](https://apify.com/myworkingmemory) (community)
- **Categories:** Developer tools, Business
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 delivered rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## FDA Orange Book Drug Patents & Exclusivity API

Get analysis-ready FDA Orange Book drug-product, patent and exclusivity records. Search by drug name, ingredient, applicant, application number, patent number or exclusivity code; filter source-reported expiration dates; export the matching records as JSON or CSV.

Use the API to build an applicant’s listed drug-patent or exclusivity research table, screen the current FDA download for source-reported expirations in a date range, or refresh a saved drug or ingredient query. Matching product details are already linked to each patent or exclusivity record.

Patent and exclusivity results can include the corresponding drug-product details in the same row. Each result keeps source identifiers, raw dates, normalized dates, duplicate occurrence counts and source hashes. The run manifest includes acquisition evidence and measured source quality checks.

Independently produced by Myworkingmemory from public FDA files; not endorsed by FDA.

### Pricing

Each run costs **$0.01 to start plus $0.001 per delivered row ($1 per 1,000 rows)**. Platform execution is included in these event prices. For example, one run returning 100 rows costs $0.11; 1,000 rows cost $1.01. The startup fee applies after the Actor starts, including no-match queries and runs that later fail. Each pagination request starts another run. The current prices are also shown in the Apify pricing panel before you run it.

The default customer spending cap is $0.25. You can set a lower or higher cap, subject to the $0.011 minimum. A cap can reduce the number of delivered rows; inspect MANIFEST for the actual count and continuation offset. API usage is purchased through Apify separately from any one-time CSV snapshot package.

### Quick examples

Patents with drug-product context:

```json
{"table":"patents","drugName":"ACTHAR","limit":10}
```

Example output excerpt from the query retrieved October 30, 2026. A full patent-context row has 44 fields:

```json
{
  "application_number": "008372",
  "product_number": "003",
  "patent_number": "11752199",
  "patent_expiration_date_iso": "2041-07-18",
  "product_trade_name": "ACTHAR GEL (AUTOINJECTOR)",
  "product_ingredient": "CORTICOTROPIN",
  "source_release_id": "fda-ob-sha256-c2088c7a36db1930a152b63db23e7a995c471bf4b18c960b1d28190580984e4d",
  "retrieved_at_utc": "2026-10-30T22:27:33.132769+00:00"
}
```

These are source-reported values from that dated example. [Download free CSV samples and see the query guide](https://www.myworkingmemory.ai/orange-book-api.html#free-samples) before running your own query.

Exclusivity records for an ingredient:

```json
{"table":"exclusivity","ingredient":"SITAGLIPTIN","limit":10}
```

Products for an application:

```json
{"table":"products","applicationNumber":"008372","limit":100}
```

The default is up to 100 patent records with product context. A run queries one table. To obtain patent and exclusivity data, run each table separately; this avoids multiplying patent rows by exclusivity rows.

### Inputs

| Field | Meaning |
| --- | --- |
| `table` | `products`, `patents` or `exclusivity`; default `patents`. |
| `includeProductContext` | Default `true`. Appends `product_` fields to patent/exclusivity records. Product records already contain their own context. |
| `drugName` | Case-insensitive substring of the FDA trade name. |
| `ingredient` | Case-insensitive substring of active-ingredient text. |
| `applicant` | Case-insensitive substring of either the full or abbreviated applicant name. |
| `applicationNumber` | Exact 1–6 digit JSON string, left-padded to six digits. |
| `patentNumber` | Exact source patent identifier, including any suffix; patents only. |
| `exclusivityCode` | Exact FDA exclusivity code; exclusivity only. |
| `expiresFrom`, `expiresTo` | Inclusive `YYYY-MM-DD` source expiration-date range; patents/exclusivity only. |
| `limit` | Requested page size, 1–10,000; default 100. Apify spending limits can reduce delivery. |
| `offset` | Skip this many matching records; default 0. |
| `expectedSourceReleaseId` | Optional source hash ID from an earlier run. If the current source differs, the run fails before writing records. |

Filters combine with AND. Empty text filters have no effect. Unknown fields, invalid dates, unsupported table/filter combinations and invalid bounds fail before source retrieval.

### Output

- **Default dataset:** the selected records. Export JSON or CSV through Apify's normal dataset API or Console.
- **MANIFEST:** source ZIP/member hashes, retrieval timestamp, actual input, source quality counts, matched/returned record counts, pagination and delivery status.
- **QA:** source row counts, exact duplicate accounting, date precision counts and product-link checks.
- **DATA_DICTIONARY:** the fields for the selected table and context option.

Examples of retained fields include `application_number`, `product_number`, `application_product_key`, `source_record_fingerprint`, `source_release_id`, `retrieved_at_utc` and `source_occurrence_count`. Patent records add patent identifiers/dates/flags; exclusivity records add exclusivity codes/dates. Product context is prefixed with `product_`. Identifiers remain strings, including leading zeros and patent suffixes. Occurrence counts are JSON integers.

The `source_release_id` is a provider-created hash identifier, not an FDA-issued release number. Retrieval time, HTTP timestamps and ZIP timestamps do not establish an FDA coverage month. `MANIFEST.pagination.returned_rows` records what was actually saved, including any spending-limit truncation. A no-match query returns an empty dataset with zero matches in the manifest.

### Pagination without mixing snapshots

Results are ordered by application/product key and source-record fingerprint. Take `source_release_id` from the first run's MANIFEST and supply it as `expectedSourceReleaseId` on later offset requests. Also keep the filters unchanged. If FDA updates the source between runs, the pin check fails visibly rather than mixing two releases. Restart from offset zero for the new release. This API does not retrieve earlier snapshots by hash.

The `next_offset` in MANIFEST advances by the number of records actually delivered. A user spending limit is per run; review that limit before starting another page. Start a new run for each page. This version does not resume a previous run: a nonempty default dataset is rejected before FDA retrieval to prevent duplicate or mixed-snapshot results.

### Calling through the Apify API

Actor identifier: `sKjpMW1IXVbhX7cMg`. Set your Apify token in your own environment; do not place it in request bodies or shared URLs.

```sh
curl --request POST \
  --header "Authorization: Bearer $APIFY_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{"table":"patents","drugName":"ACTHAR","limit":10}' \
  "https://api.apify.com/v2/acts/sKjpMW1IXVbhX7cMg/run-sync-get-dataset-items?format=json&clean=true"
```

For an asynchronous workflow, POST the same JSON to `/v2/acts/sKjpMW1IXVbhX7cMg/runs`, wait for that run to succeed, then read `/v2/datasets/DEFAULT_DATASET_ID/items?format=json` or `?format=csv`. Read `/v2/key-value-stores/DEFAULT_KEY_VALUE_STORE_ID/records/MANIFEST` for source and paging details. Apify supplies the storage IDs in the run response.

### Use from an AI assistant

This Actor can be selected through Apify’s MCP server in a compatible AI client. Use the scoped server URL `https://mcp.apify.com?tools=myworkingmemory/fda-orange-book-drug-patents-exclusivity-api` and authenticate with your own Apify account using the client’s supported connection flow. A prompt such as “Find FDA Orange Book patent records for ACTHAR, maximum ten rows” should map to the same input shown above. Review the proposed input and spending limit before approving a run. [Official Apify MCP setup](https://docs.apify.com/mcp).

### Reuse a focused query

Save your input as an Apify Task or reusable API request and rerun it when you refresh your research. Every run retrieves the currently available FDA download and is charged separately. Keep the source-release pin and spending-limit instructions when paginating. Saving a query does not create a recurring delivery service.

### Source and freshness

Every normal run retrieves the currently available official FDA downloadable ZIP, validates its schema and normalizes it. FDA describes its downloadable Orange Book files as monthly updates; this Actor does not claim a new release exists each month or run a background acquisition schedule. Source or schema failures fail the run. Old bundled data is not silently substituted for a failed live request.

This version provides one source snapshot per run. Expiration searches cover only records present in that download, not an exhaustive historical record set. Historical change feeds and recurring delivery services are outside its scope. Source-reported patent/exclusivity dates are preserved as data, rather than converted into an independent conclusion about enforceability or market-entry timing.

Sources: [FDA Orange Book overview](https://www.fda.gov/drugs/drug-approvals-and-databases/approved-drug-products-therapeutic-equivalence-evaluations-orange-book), [FDA data-file definitions](https://www.fda.gov/drugs/drug-approvals-and-databases/orange-book-data-files).

### Developer verification

Python 3.12 and the official pinned Apify SDK are used. Core parsing/query code uses the Python standard library. No browser, paid proxy, AI model or separate supplier API key is needed.

```sh
python -m pip install -r requirements.txt
python -m unittest discover -s tests -v
python -m src.main --offline-source tests/fixtures/source --input examples/patents-input.json --output validation/local/patents
```

The offline command makes no network requests. Its manifest explicitly says `preserved_fixture` and retains the fixture's original retrieval date; it is not evidence of current FDA data or an Apify cloud run. See `MAINTENANCE.md` for source/schema changes, SDK updates and release checks.

# Actor input Schema

## `table` (type: `string`):

One record type per run. Patent and exclusivity rows can include matching drug-product context.

## `includeProductContext` (type: `boolean`):

For patents/exclusivity, append product\_ fields from the matching product. Products table already includes its own product fields.

## `limit` (type: `integer`):

Requested page size. Apify spending limits can reduce delivered rows. Maximum10,000 records per run.

## `offset` (type: `integer`):

Skip this many matching rows. Compare source_release_id across pages; a changed source hash means a different snapshot.

## `drugName` (type: `string`):

Case-insensitive substring of the FDA trade name. Leave blank for no filter.

## `ingredient` (type: `string`):

Case-insensitive substring of active ingredient text.

## `applicant` (type: `string`):

Case-insensitive substring of either abbreviated or full FDA applicant name.

## `applicationNumber` (type: `string`):

Exact1–6digit string, left-padded to six digits. Keep identifiers as strings; for example008372.

## `patentNumber` (type: `string`):

Exact case-insensitive source patent identifier, including any suffix. Available only with patents.

## `exclusivityCode` (type: `string`):

Exact case-insensitive FDA source exclusivity code. Available only with exclusivity.

## `expiresFrom` (type: `string`):

Optional inclusive date YYYY-MM-DD, for patents or exclusivity. Not a legal-status determination.

## `expiresTo` (type: `string`):

Optional inclusive date YYYY-MM-DD, for patents or exclusivity.

## `expectedSourceReleaseId` (type: `string`):

Optional source_release_id from a previous MANIFEST. Use with offset paging. If the freshly downloaded source hash differs, fail before writing results instead of mixing snapshots.

## Actor input object example

```json
{
  "table": "patents",
  "includeProductContext": true,
  "limit": 100,
  "offset": 0
}
```

# Actor output Schema

## `records` (type: `string`):

No description

## `manifest` (type: `string`):

No description

## `qa` (type: `string`):

No description

## `dictionary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("myworkingmemory/fda-orange-book-drug-patents-exclusivity-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("myworkingmemory/fda-orange-book-drug-patents-exclusivity-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call myworkingmemory/fda-orange-book-drug-patents-exclusivity-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,myworkingmemory/fda-orange-book-drug-patents-exclusivity-api"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/sKjpMW1IXVbhX7cMg/builds/vunevM3JmPOK1dMPR/openapi.json
