# FDA Orange Book Patent & Exclusivity Tracker — Quarterly Diff (`changewire/fda-orange-book-extraction`) Actor

Daily diff feed for FDA Orange Book. Emits JSONL records for every change to approval status, patent count, expirations, exclusivity grants, generic availability, or product count. Replaces $25-50k/yr Cortellis / Evaluate Pharma / IPD Analytics tiers at $2-1,350/mo. For pharma BI and IP attorneys.

- **URL**: https://apify.com/changewire/fda-orange-book-extraction.md
- **Developed by:** [ChangeWire](https://apify.com/changewire) (community)
- **Categories:** AI, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## FDA Orange Book API — Daily Loss-of-Exclusivity & Patent-Listing Diff

> Daily diff of every FDA Orange Book approved-drug application
> for pharma competitive-intelligence desks, IP attorneys, generic-
> pharma forecasting teams, AI-agent builders embedding pharma
> signals, and specialty-pharma watchlist analysts. Watches the
> Orange Book bulk-ZIP refresh for approval-status flips, patent-
> count changes, patent-expiration moves, exclusivity-grant
> additions, generic-availability shifts, dosage-form changes, and
> product-count drift across NDA / ANDA / BLA applications — emits
> one JSONL change record per detected change.

### What this does

- **Tracks ~26k Orange Book applications across NDA + ANDA + BLA**
  with full diff coverage on seven dimensions (approval status,
  patent count, patent expirations, exclusivity expirations,
  generic availability, dosage form, product count).
- **Cuts loss-of-exclusivity surveillance latency from quarterly
  ETL builds to one day** so pharma-BI desks, IP attorneys, and
  generic-pharma forecasting teams catch patent listings, exclusivity
  grants, and TE-code transitions the same day FDA refreshes the
  Orange Book — rather than waiting for the next Cortellis bi-weekly
  digest or the next Evaluate Pharma quarterly snapshot.
- **Replaces $35-50k/yr Cortellis Drug Discovery / Evaluate Pharma /
  IPD Analytics enterprise tiers** with a metered pay-per-result
  Apify actor at $0.03 per change record (typically $2-12/month for
  a small competitor portfolio or $120-1,350/month for a 500-
  ingredient ingredient-watch).

### Use cases

#### FDA Orange Book API for pharma competitive-intelligence desks

A pharma-BI desk at a top-20 pharma maintains a 50-application
competitor portfolio (their three top competitors' full NDA + key
ANDAs across the franchise). The desk runs this actor weekly with
`watchlist: ["NDA-021423", "NDA-020702", "ANDA-076503", ...]` and
routes JSONL diff records into Slack `#pharma-bi-alerts`. Every
`patent_expirations` move surfaces 2-4 weeks before Cortellis catches
up and 6+ weeks before Evaluate Pharma's quarterly refresh — letting
the BI desk update the LoE calendar in their forecasting model
faster than competitors using bundled-suite vendors. Cost: roughly
5-30 changes/week × $0.03 = $0.45-2.70/week = $2-12/mo.

#### FDA Orange Book diff for IP attorneys and litigation triggers

An IP-litigation team at a Top-50 AmLaw firm tracks the Orange Book
patent listings for ~150 drugs in active inter partes review or
litigation. Each `patent_count` drop is a public-record signal of
either patent-settlement, patent-invalidation, or a "Delist Flag"
move — all of which materially shape litigation strategy. The actor
emits structured `before` / `after` snapshots with patent number
arrays, so the team's docket-research paralegal can immediately
cross-reference the delisted patent number against PACER without
manual Orange Book HTML re-parsing. Cost: ~$15-50/mo for the 150-
drug watch + alert volume.

#### Loss-of-exclusivity tracker for generic-pharma forecasting

A generic-pharma R&D forecasting team filters this actor on the
top-200 high-revenue ingredients (semaglutide, tirzepatide,
ozempic-class, GLP-1 agonists, etc.) and runs daily. Every
`exclusivity_expirations` and `patent_expirations` change feeds
into the team's first-filer ANDA prioritization model. The
structured `change_type` field lets the model distinguish a
patent-cliff signal (exclusivity expires) from a label expansion
(new exclusivity grant) — a distinction Evaluate Pharma's quarterly
PDF reports collapse into a single "patent activity" rollup. Cost:
$120-450/mo at 500-ingredient watch + daily cadence.

#### Pharma patent expiration API for AI-agent builders

An AI-agent builder packages this actor's JSONL output stream as a
tool inside an agent that answers pharma-investment research
questions ("which drugs lose exclusivity in Q3 2027?"). Programmatic
access at $0.03/result lets the agent burn 10-50 records per query
without rebuilding the Orange Book ETL each session. Replaces the
$50k/yr Cortellis API tier most agent-builders can't afford with
metered per-query economics that scale with usage.

#### Specialty-pharma watchlist API for therapeutic-area portfolios

A specialty-pharma analyst at an oncology-focused fund filters on
specific ingredient lists (oncology-relevant compounds) using
`ingredients: ["pembrolizumab", "nivolumab", "ipilimumab", ...]`
and tracks 50-100 high-value applications across the watchlist.
Each daily diff record surfaces approval-status flips and patent-
listing additions that map directly into the fund's investment
thesis on biosimilar-entry risk and patent-cliff timing. Same
$0.03/result economics; ~$30-80/mo typical run cost.

### Input

See `.actor/input_schema.json` for the full schema. Key fields:

| Field | Type | Default | Description |
|---|---|---|---|
| `watchlist` | array of strings | `[]` | Application keys (e.g. `["NDA-021423","ANDA-076503"]`). |
| `trade_names` | array of strings | `[]` | Brand-name substrings (case-insensitive). |
| `ingredients` | array of strings | `[]` | Active-ingredient substrings (case-insensitive). |
| `change_types` | array of strings | all seven | Subset of {approval_status, patent_count, patent_expirations, exclusivity_expirations, generic_availability, dosage_form, product_count}. |
| `snapshot_key` | string | `snapshot-latest` | Apify Key-Value Store key for previous snapshot. |
| `bulk_url` | string | `""` | Explicit Orange Book ZIP URL override. Empty triggers landing-page auto-discovery. |
| `rate_limit_rps` | int | `1` | Polite RPS for landing-page + ZIP fetch. FDA does not publish an RPS limit; 1 is conservative. |

If `watchlist` + `trade_names` + `ingredients` are all empty, the actor
processes the full Orange Book (~26k applications) and emits diff
records for every detected change — useful for a baseline first run.

Realistic example input (50-application competitor portfolio for a
pharma-BI desk):

```json
{
  "watchlist": ["NDA-021423", "NDA-020702", "ANDA-076503", "NDA-022518", "..."],
  "change_types": [
    "patent_expirations",
    "exclusivity_expirations",
    "patent_count",
    "approval_status"
  ],
  "rate_limit_rps": 1
}
````

### Output

JSONL dataset; one record per detected change:

```json
{
  "actor": "actor-3-fda-orange-book-extraction",
  "schema_version": "1.0.0",
  "extracted_at": "2026-05-22T06:00:00Z",
  "source_url": "https://www.accessdata.fda.gov/scripts/cder/ob/results_product.cfm?Appl_Type=NDA&Appl_No=021423",
  "appl_type": "NDA",
  "appl_no": "021423",
  "appl_key": "NDA-021423",
  "trade_name": "LEXAPRO",
  "ingredient": "ESCITALOPRAM OXALATE",
  "change_type": "patent_expirations",
  "before": {"earliest": "06/04/2025", "patent_numbers": ["6916941"]},
  "after":  {"earliest": "06/04/2027", "patent_numbers": ["6916941"]},
  "detected_at": "2026-05-22T06:00:00Z"
}
```

Apify Console preview shows a 6-column table view (appl key / trade
name / ingredient / change type / detected at / source URL) so
analysts and non-engineers can sanity-check runs before piping into
a BI pipeline.

### Pricing & limits

- **$0.03 per result** (per detected diff record).
- **Typical small portfolio cost** (50 applications, weekly cadence):
  \~$2-12/mo PPR.
- **Mid-market cost** (500-ingredient ingredient-watch, daily cadence):
  \~$120-1,350/mo PPR.
- **Free 7-day trial** so you can verify diff fidelity against your
  own watchlist before committing.
- **Recommended schedule:** Daily 06:00–08:00 UTC after the FDA bulk
  ZIP refresh window. Running more often than the FDA refreshes is
  harmless but emits zero records.
- **Estimated monthly cost:**
  - Pharma-BI competitor portfolio (~50 apps, weekly): **$2-12/mo PPR**
  - IP-litigation watch (~150 drugs, daily): **$15-50/mo PPR**
  - Generic-pharma LoE forecasting (~500 ingredients, daily): **$120-450/mo PPR**
  - Specialty-pharma therapeutic-area portfolio (~80 apps, daily): **$30-80/mo PPR**
  - Replaces Cortellis Drug Discovery ($35-50k/yr) / Evaluate Pharma
    ($25-40k/yr) / IPD Analytics ($30-60k/yr) enterprise tiers with
    metered per-event fidelity for the Orange Book diff subset.

### Data source & freshness

- **Source:** FDA Orange Book bulk-ZIP refreshed quarterly + on-demand
  per-application detail (`accessdata.fda.gov/scripts/cder/ob`).
  Auto-discovers the current ZIP URL from `fda.gov/drugs/.../orange-
  book-data-files`; accepts an explicit `bulk_url` override.
- **Update cadence (source-side):** Bulk-ZIP refreshes quarterly with
  rolling daily updates published into the same files between
  refreshes. Patent listings + exclusivity grants land within
  1-3 days of FDA approval. TE-code changes typically batch into
  the quarterly ZIP cycle.
- **Actor cadence (recommended):** Daily 06:00 UTC. Catches rolling
  daily updates without spurious activity on quiet days.
- **Public-records license:** Orange Book is published under the
  21 CFR §314.53 patent-and-exclusivity public-disclosure mandate.
  17 USC §105 removes copyright on the underlying FDA records.
  Actor sets a polite 1 rps default and an identifying User-Agent
  on landing-page + ZIP fetches.

### FAQ

#### How does this compare to Cortellis or Evaluate Pharma?

Cortellis Drug Discovery / Evaluate Pharma / IPD Analytics package
Orange Book watching as one feature in a $25-50k/yr enterprise
pharma-intelligence suite that also includes pipeline tracking,
clinical-trial outcomes, deal-and-licensing data, market-access
intelligence, and human-curated weekly insight reports. This actor
does **only** the federal-Orange-Book diff layer at $0.03 per change
record. Pick this if your team already has the rest of its pharma-
intelligence stack and just needs a programmatic Orange Book feed;
pick Cortellis or Evaluate if you need bundled global pharma data +
pipeline + deal data + human-curated reports.

#### What's a `appl_key` and how does it map to NDAs / ANDAs / BLAs?

`appl_key` is a hyphenated combination of `Appl_Type` + `Appl_No`
(e.g. `NDA-021423`, `ANDA-076503`, `BLA-125558`). FDA assigns each
application a separate Appl\_Type prefix; the actor preserves both
fields explicitly and rolls up at the `appl_key` level — which is
the natural pharma-workflow granularity (one regulatory submission
per application). One Appl\_No can cover multiple strengths
(Product\_No 001, 002, 003 ...); the actor rolls up at the
application level. Per-strength diffing is a candidate Week-5
follow-up if buyers ask.

#### What change types does this detect?

Seven dimensions: `approval_status` (Type field shifts including
DISCN withdrawals + new RX/OTC approvals), `patent_count` (number
of listed patents drops or rises — a delist-flag move shows up as
a count drop), `patent_expirations` (earliest expiration date moves
on existing patents), `exclusivity_expirations` (new exclusivity
codes added or expirations move), `generic_availability` (TE-code
transitions signaling generic entry), `dosage_form` (DF;Route field
changes for label-expansion signal), `product_count` (number of
strength-level products under one appl\_no rises or drops).

#### Are delisted patents handled correctly?

Yes — patents flagged `Delist_Flag=Y` are dropped at aggregation
time, matching how FDA presents the Orange Book listing surface to
buyers. A delisted patent surfaces as a `patent_count` drop diff
record, not as a `patent_expirations` change — so the IP-litigation
buyer cohort can distinguish "patent withdrawn from listing" from
"patent expiration moved" cleanly.

#### How does this handle the quarterly bulk-ZIP refresh + daily incremental updates?

The actor downloads the current bulk ZIP on every run, parses the
three pipe-delimited tables (products.txt + patent.txt +
exclusivity.txt — the historical tilde-delimited variant is
auto-detected), and diffs the resulting per-`appl_key` aggregate
against the previous snapshot in Apify Key-Value Store. FDA's
rolling daily updates land into the same files between quarterly
refreshes, so a daily actor cadence catches every change FDA
publishes without needing separate "delta" handling. The bulk
ZIP is roughly 30-50 MB; download is the hot path for cost but
memory pressure is negligible.

#### Are there PII or attorney-client risks?

No. Orange Book data describes regulated drug applications,
patent listings, and exclusivity grants — there is no individual-
PII surface. Patents reference individuals only via the patent
number's filed inventor list (which is itself USPTO public-
record); the actor does not dereference patents to USPTO.

#### What about the FDA Akamai WAF I keep reading about?

FDA's `www.fda.gov` landing page sits behind an Akamai abuse-
detection layer that throttles aggressive scraping. The actor's
landing-page auto-discovery uses a polite 1 rps with an
identifying User-Agent and works fine from Apify-platform run-time
IPs (verified end-to-end smoke run 2026-05-20 baselining 27,121
applications successfully). The WAF only affects high-frequency
scraping from a single IP without proper UA — neither of which
this actor does. If your run consistently 403s on the landing-page
fetch, set `bulk_url` explicitly to the current quarter's ZIP URL
to skip landing-page auto-discovery entirely.

#### Is there a rate-limit risk?

The actor self-limits to 1 rps and respects FDA's robots.txt. FDA
does not publish an explicit RPS limit; 1 rps is conservative.
Bulk runs against the full ~26k-application Orange Book take
\~2-3 minutes wall time at 1 rps depending on landing-page round
trip + ZIP download throughput.

### Companion actors in this portfolio

`changewire` maintains a portfolio of federal-data diff actors. All
share the same daily-snapshot + JSONL change-record pattern, watchlist
filtering, and per-record change-type semantics. Pick the data domain
you need; mix and match across a single Apify account:

- [`changewire/clinicaltrials-protocol-diff`](https://apify.com/changewire/clinicaltrials-protocol-diff) — NIH-registered trial protocol diffs.
- [`changewire/grantsgov-opportunity-alert`](https://apify.com/changewire/grantsgov-opportunity-alert) — Daily diff of federal grant opportunities (status, deadline, award amount, eligibility).
- [`changewire/noaa-storm-events-diff`](https://apify.com/changewire/noaa-storm-events-diff) — NOAA NCEI storm-event records (tornados, hail, floods) with daily incremental diff.
- [`changewire/uspto-ttab-docket-extractor`](https://apify.com/changewire/uspto-ttab-docket-extractor) — USPTO TTAB trademark docket records + filings + parties + deadlines, on-demand extraction.
- [`changewire/epa-echo-compliance`](https://apify.com/changewire/epa-echo-compliance) — EPA ECHO facility compliance status + violations + enforcement cases per program (CAA / CWA / RCRA / SDWA).
- [`changewire/samgov-contracts-diff`](https://apify.com/changewire/samgov-contracts-diff) — SAM.gov federal contract opportunities, daily diff. *(currently hard-blocked on identity-tied SAM.gov API key; awaiting user-machine key generation)*

### Running locally (for contributors)

```bash
cd actors/actor-3-fda-orange-book-extraction
apify run --purge  ## uses .actor/input_schema.json defaults
```

Watchlist run:

```bash
apify run --input '{"watchlist": ["NDA-021423", "NDA-020702"]}'
```

Ingredient run:

```bash
apify run --input '{"ingredients": ["semaglutide", "tirzepatide"]}'
```

### Legal

FDA Orange Book is US-government public-domain data. Patent listings

- exclusivity grants + product approvals are published under the
  21 CFR §314.53 public-disclosure mandate; 17 USC §105 removes
  copyright on the underlying FDA records. Actor honors FDA's
  robots.txt for landing-page paths, sets a non-spoofed identifying
  User-Agent, and defaults to 1 rps to stay polite under FDA's
  Akamai abuse-detection threshold. No PII in output: Orange Book
  data describes drug applications + patent listings + exclusivity
  grants, not individuals.

# Actor input Schema

## `watchlist` (type: `array`):

Explicit application keys, e.g. NDA-021423 or ANDA-076503. If empty, falls through to trade\_names + ingredients filters; if all three are empty, the actor processes the full Orange Book.

## `trade_names` (type: `array`):

Brand-name substring filter, case-insensitive (e.g. LEXAPRO, OZEMPIC).

## `ingredients` (type: `array`):

Active-ingredient substring filter, case-insensitive (e.g. ESCITALOPRAM, SEMAGLUTIDE).

## `change_types` (type: `array`):

Subset of: approval\_status, patent\_count, patent\_expirations, exclusivity\_expirations, generic\_availability, dosage\_form, product\_count.

## `snapshot_key` (type: `string`):

Key-value store key holding the previous snapshot. Default: 'snapshot-latest'.

## `bulk_url` (type: `string`):

Explicit fda.gov/media/<id>/download URL for the Orange Book bulk ZIP. If empty, the actor scrapes the landing page to auto-discover.

## `rate_limit_rps` (type: `integer`):

FDA does not publish an RPS limit. We default to 1 rps as polite-default.

## Actor input object example

```json
{
  "watchlist": [],
  "trade_names": [],
  "ingredients": [],
  "change_types": [
    "approval_status",
    "patent_count",
    "patent_expirations",
    "exclusivity_expirations",
    "generic_availability",
    "dosage_form",
    "product_count"
  ],
  "snapshot_key": "snapshot-latest",
  "bulk_url": "",
  "rate_limit_rps": 1
}
```

# 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("changewire/fda-orange-book-extraction").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("changewire/fda-orange-book-extraction").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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 changewire/fda-orange-book-extraction --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=changewire/fda-orange-book-extraction",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "FDA Orange Book Patent & Exclusivity Tracker — Quarterly Diff",
        "description": "Daily diff feed for FDA Orange Book. Emits JSONL records for every change to approval status, patent count, expirations, exclusivity grants, generic availability, or product count. Replaces $25-50k/yr Cortellis / Evaluate Pharma / IPD Analytics tiers at $2-1,350/mo. For pharma BI and IP attorneys.",
        "version": "0.1",
        "x-build-id": "eGiKW2CKavF5GAh2r"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/changewire~fda-orange-book-extraction/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-changewire-fda-orange-book-extraction",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/changewire~fda-orange-book-extraction/runs": {
            "post": {
                "operationId": "runs-sync-changewire-fda-orange-book-extraction",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/changewire~fda-orange-book-extraction/run-sync": {
            "post": {
                "operationId": "run-sync-changewire-fda-orange-book-extraction",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "watchlist": {
                        "title": "Watchlist (Application keys)",
                        "type": "array",
                        "description": "Explicit application keys, e.g. NDA-021423 or ANDA-076503. If empty, falls through to trade_names + ingredients filters; if all three are empty, the actor processes the full Orange Book.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "trade_names": {
                        "title": "Trade names",
                        "type": "array",
                        "description": "Brand-name substring filter, case-insensitive (e.g. LEXAPRO, OZEMPIC).",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "ingredients": {
                        "title": "Active ingredients",
                        "type": "array",
                        "description": "Active-ingredient substring filter, case-insensitive (e.g. ESCITALOPRAM, SEMAGLUTIDE).",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "change_types": {
                        "title": "Change types to emit",
                        "type": "array",
                        "description": "Subset of: approval_status, patent_count, patent_expirations, exclusivity_expirations, generic_availability, dosage_form, product_count.",
                        "default": [
                            "approval_status",
                            "patent_count",
                            "patent_expirations",
                            "exclusivity_expirations",
                            "generic_availability",
                            "dosage_form",
                            "product_count"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "snapshot_key": {
                        "title": "Snapshot key",
                        "type": "string",
                        "description": "Key-value store key holding the previous snapshot. Default: 'snapshot-latest'.",
                        "default": "snapshot-latest"
                    },
                    "bulk_url": {
                        "title": "Bulk-ZIP URL override",
                        "type": "string",
                        "description": "Explicit fda.gov/media/<id>/download URL for the Orange Book bulk ZIP. If empty, the actor scrapes the landing page to auto-discover.",
                        "default": ""
                    },
                    "rate_limit_rps": {
                        "title": "Polite rate limit (requests per second)",
                        "minimum": 1,
                        "maximum": 5,
                        "type": "integer",
                        "description": "FDA does not publish an RPS limit. We default to 1 rps as polite-default.",
                        "default": 1
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
