> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pav.bio/llms.txt
> Use this file to discover all available pages before exploring further.

# Check patents and loss of exclusivity

> Collect the US patent families, Orange Book patents and exclusivities around a drug, with owners and expiry dates.

This guide gathers the live US patent families that mention tirzepatide, from
every owner, lists them by statutory term end, and adds the drug's Orange Book
patents and exclusivities. It is a starting point for
loss-of-exclusivity (LOE) work, not a legal opinion.

<Warning>
  `statutory_term_end` is the earliest nonprovisional filing date plus 20 years.
  It does not include patent term adjustment, patent term extension or terminal
  disclaimers. Orange Book expiry dates and regulatory exclusivities come from
  [FDA records](/datasets/fda), shown below. Confirm expiry dates before relying
  on them.
</Warning>

## Prerequisites

* A Pav API key in `PAV_API_KEY`. See [Quickstart](/quickstart).
* Python 3.9+ and `pip install requests`.

## Approach

1. **Find the owner** of the drug from its programs.
2. **Search families by every name** of the drug. Patent `q` matches title,
   owner name or patent number as a substring, with no synonyms, so search the
   generic name and code names separately.
3. **Open each live family** for its term, members and owners.
4. **Search by compound class** within the owner's portfolio. Compound patents
   are often titled by chemical class rather than drug name.

## Script

```python loe_check.py theme={null}
import os

import requests

API = "https://api.pav.bio"
HEADERS = {"Authorization": f"Bearer {os.environ['PAV_API_KEY']}"}


def get(path, **params):
    resp = requests.get(f"{API}{path}", headers=HEADERS, params=params, timeout=60)
    resp.raise_for_status()
    return resp.json()


# 1. Find the drug's owner from its programs.
programs = get("/v1/programs", drug="Tirzepatide", limit=50)["data"]
owners = {p["company_id"]: p["company"] for p in programs}
print("owner:", owners)

# 2. Collect families by drug name and code name, from every owner.
families = {}
for term in ["tirzepatide", "LY3298176"]:
    for f in get("/v1/patents", q=term, limit=100)["data"]:
        families[f["family_id"]] = f

# 3. Open each live family for its statutory term and members.
rows = []
for family_id, f in families.items():
    if not f.get("has_live_member"):
        continue
    detail = get(f"/v1/patents/{family_id}")
    rows.append(
        (
            detail.get("statutory_term_end", "n/a"),
            family_id,
            detail["representative_title"][:55],
            ", ".join(detail.get("owner_names", [])),
            detail["granted_count"],
        )
    )

rows.sort()
print(f"{len(rows)} live families mention tirzepatide or LY3298176")
for term_end, family_id, title, owner, granted in rows:
    print(f"{term_end} | {family_id} | {title} | {owner} | granted={granted}")
```

```text Example output (September 2026) theme={null}
owner: {218: 'Eli Lilly'}
7 live families mention tirzepatide or LY3298176
2041-01-22 | 62967867 | THERAPEUTIC USES OF TIRZEPATIDE | ELI LILLY AND COMPANY | granted=1
2042-02-02 | 63150187 | TIRZEPATIDE THERAPEUTIC METHODS | ELI LILLY AND COMPANY | granted=0
2042-11-22 | PCTIB2022061286 | PROCESS FOR THE PREPARATION OF TIRZEPATIDE OR PHARMACEU | SUN PHARMACEUTICAL INDUSTRIES LIMITED | granted=0
2043-06-23 | 63357285 | TIRZEPATIDE COMPOSITIONS AND USE | ELI LILLY AND COMPANY | granted=0
2043-12-29 | 63477734 | PROCESSES AND INTERMEDIATES FOR PREPARING TIRZEPATIDE | ELI LILLY AND COMPANY | granted=1
2044-10-09 | 63589289 | INTRANASAL DELIVERY OF TIRZEPATIDE TO TREAT OBESITY | THE TRUSTEES OF COLUMBIA UNIVERSITY IN THE CITY OF NEW YORK | granted=0
2045-02-25 | 19062335 | MULTI-DOSE PEN OF TIRZEPATIDE | ORBICULAR PHARMACEUTICAL TECHNOLOGIES PRIVATE LIMITED | granted=1
```

Third-party families (formulation, process, device) show up because `q`
searches every owner, not just the drug's sponsor.

## Find compound patents by class

The families above are named after the drug. Earlier compound families use the
chemical class in their titles. Search the owner's portfolio for the class,
oldest priority last:

```python compound_class.py theme={null}
import os

import requests

API = "https://api.pav.bio"
HEADERS = {"Authorization": f"Bearer {os.environ['PAV_API_KEY']}"}

resp = requests.get(
    f"{API}/v1/patents",
    headers=HEADERS,
    params={"company_id": 218, "q": "GIP", "sort": "earliest_priority_date", "limit": 10},
    timeout=60,
)
resp.raise_for_status()
for f in resp.json()["data"]:
    print(f.get("earliest_priority_date"), "|", f["family_id"], "|", f["representative_title"][:70])
```

```text Example output (September 2026) theme={null}
2024-08-02 | 63678779 | GIP RECEPTOR AGONIST COMPOUNDS
2024-06-18 | 63661175 | GIP RECEPTOR AGONIST COMPOUNDS
2023-01-31 | 63482404 | GIP/GLP1/GCG TRI-RECEPTOR AGONISTS AND USES THEREOF
2022-11-21 | 63426904 | PROCESS FOR PREPARING A GIP/GLP1 DUAL AGONIST
2022-10-19 | 63417339 | PRESERVED GIP/GLP AGONIST COMPOSITIONS
2022-09-12 | 63405565 | A GIP/GLP1 FOR USE IN THERAPY
2020-01-23 | 62964932 | GIP/GLP1 CO-AGONIST COMPOUNDS
2019-08-01 | 62881685 | GIPR-AGONIST COMPOUNDS
2019-01-29 | 62797963 | PROCESS FOR PREPARING A GIP/GLP1 DUAL AGONIST
2018-07-23 | 62702061 | METHODS OF USING A GIP/GLP1 CO-AGONIST FOR THERAPY
```

Narrow further with `cpc` (for example `C07K` for peptides), `granted=true`, or
`priority_to` for the earliest filings.

## Add Orange Book patents and exclusivities

The Orange Book lists the patents a sponsor has submitted for an approved drug,
with their expiry dates, and the regulatory
exclusivities FDA has granted. Pull both from [FDA records](/datasets/fda) by
the drug's application numbers. Application numbers are stable across FDA
editions; `record_key` values are not.

```python orange_book.py theme={null}
import os

import requests

API = "https://api.pav.bio"
HEADERS = {"Authorization": f"Bearer {os.environ['PAV_API_KEY']}"}


def get_all(**params):
    rows, offset = [], 0
    while True:
        resp = requests.get(f"{API}/v1/fda", headers=HEADERS, params={**params, "limit": 100, "offset": offset}, timeout=60)
        resp.raise_for_status()
        page = resp.json()["data"]
        rows += page
        if len(page) < 100:
            return rows
        offset += 100


# 1. Find the drug's approved applications in the Orange Book.
products = get_all(q="tirzepatide", record_type="orange_book_product")
apps = sorted({p["application_key"] for p in products})
print("applications:", apps, "|", sorted({p["title"] for p in products}))

# 2. Collect listed patents and exclusivities per application. Patents repeat
#    once per product and use code, so keep one row per patent number.
patents, exclusivities = {}, {}
for app in apps:
    for r in get_all(application_key=app, record_type=["orange_book_patent", "orange_book_exclusivity"]):
        if r["record_type"] == "orange_book_patent":
            key = r["patent_number"]
            if key not in patents or r["event_date"] > patents[key]["event_date"]:
                patents[key] = r
        else:
            key = (r["application_key"], r["status"])
            if key not in exclusivities or r["event_date"] > exclusivities[key]["event_date"]:
                exclusivities[key] = r

# 3. Print expiries, latest last.
print(f"\n{len(patents)} listed patents")
for p in sorted(patents.values(), key=lambda r: r["event_date"]):
    d = p.get("details", {})
    claims = [c for c in ("drug_substance_claim", "drug_product_claim") if d.get(c)]
    print(f"{p['event_date']} | {p['patent_number']} | {', '.join(claims) or 'no substance or product claim flagged'}")
print(f"\n{len(exclusivities)} exclusivities")
for e in sorted(exclusivities.values(), key=lambda r: r["event_date"]):
    print(f"{e['event_date']} | {e['application_key']} | {e['status']}")
```

```text Example output (September 2026) theme={null}
applications: ['N:215866', 'N:217806'] | ['MOUNJARO', 'MOUNJARO (AUTOINJECTOR)', 'MOUNJARO KWIKPEN', 'ZEPBOUND', 'ZEPBOUND (AUTOINJECTOR)', 'ZEPBOUND KWIKPEN']

10 listed patents
2036-05-13 | 9474780 | drug_substance_claim, drug_product_claim
2039-06-14 | 12629404 | drug_product_claim
2039-06-14 | 12453755 | no substance or product claim flagged
2039-06-14 | 12453756 | drug_product_claim
2039-06-14 | 11357820 | drug_substance_claim, drug_product_claim
2039-06-14 | 11918623 | no substance or product claim flagged
2039-07-22 | 12616740 | no substance or product claim flagged
2039-07-22 | 12343382 | no substance or product claim flagged
2039-07-22 | 12453758 | no substance or product claim flagged
2041-12-30 | 12295987 | no substance or product claim flagged

6 exclusivities
2026-11-08 | N:217806 | NP
2027-05-13 | N:215866 | NCE
2027-05-13 | N:217806 | NCE
2027-10-18 | N:217806 | M-82
2027-12-20 | N:217806 | I-958
2028-12-19 | N:215866 | NPP
```

Read the listed patent expiries together with the family dates above.
`details.pediatric_extension` marks an expiry that includes pediatric
exclusivity. Exclusivity codes are FDA's, such as `NCE` (new chemical entity)
and `NPP` (new patient population).

## What to check in each family

* `members[]`: each application's `role` (continuation, divisional, ...),
  `patent_number`, `grant_date`, `status_description` and `is_dead`.
* `ownership[]`: recorded assignments, to confirm the current owner.
* `events[]` and `events_total`: prosecution and maintenance history.
* `has_live_member`: `false` means every member is abandoned or expired.
