← Methods repository
concept

Voluntary (Non-Imposed) Post-Authorisation Safety Study

A sponsor-initiated post-authorisation safety study that is not a condition of the marketing authorisation, conducted under GVP Module VIII to identify, characterise, or quantify a safety hazard or confirm the safety profile of an already-authorised medicine.

Study_Designpost-authorisation-safety-studypharmacovigilancenon-interventionalgvp-module-viiisafety-surveillanceadverse-event-of-special-interestenceppstudy-design
Methods reference only. Use primary source citations and local policy before applying this in a study protocol, regulatory submission, payer dossier, or clinical decision.

In plain language

A Post-Authorization Safety Study (PASS) is research a drug company runs on a medicine that regulators have already approved, specifically to look for safety problems in real-world use. A voluntary PASS is one the company chooses to run on its own, rather than because a regulatory agency made it a condition of approval. Because the drug is already on the market and patients are taking it as their doctor prescribes, these studies almost always use existing records — insurance claims, hospital records, or disease registries — instead of enrolling people in a controlled experiment. The goal is to answer the question: does this approved drug cause harm we did not fully see before approval, and how often?

A post-authorisation safety study (PASS) is, under EMA Good Pharmacovigilance Practices (GVP) Module VIII, "any study relating to an authorised medicinal product conducted with the aim of identifying, characterising or quantifying a safety hazard, confirming the safety profile of the medicine, or measuring the effectiveness of risk-management measures." A PASS is voluntary (non-imposed) when the marketing-authorisation holder initiates it on its own accord rather than because a competent authority has made it a binding condition of the authorisation. Most voluntary PASS are non-interventional: the medicine is prescribed in the usual manner per the marketing authorisation, treatment is not decided by a protocol, and no additional diagnostic or monitoring procedures are applied — so the study is a secondary-data cohort, case-control, self-controlled, or registry analysis rather than a trial.

Core conceptual distinction

. The defining axis is regulatory status and control, not the analytic method — the same new-user cohort can be either a voluntary or an imposed PASS. (1) Voluntary vs imposed: an imposed PASS is a condition of the marketing authorisation under Article 9, 21a, or 22a of Directive 2001/83/EC (Annex II / the risk management plan), so the PRAC assesses the draft protocol before the study starts and assesses the final results, protocol substantial amendments need approval, milestones are binding, and non-completion carries regulatory and legal consequences (variation, suspension, fees). A voluntary PASS sits outside that mandatory oversight: the sponsor controls timing, scope, and publication; PRAC protocol pre-approval is not required (though ENCePP/EU PAS Register registration and the ENCePP Code of Conduct are strongly encouraged and increasingly expected by HTA bodies and journals). (2) Non-interventional vs clinical-trial PASS: a voluntary PASS may legally be a clinical trial, but in practice it is overwhelmingly non-interventional, which is what places it in the realm of RWE database design. The estimand is the same family of pharmacovigilance quantities — absolute incidence of an adverse event of special interest (AESI), a comparative hazard versus an active comparator or background population, or a standardised incidence ratio against an external reference — assessed for safety, with the analytic burden concentrated on outcome ascertainment, susceptibility windows, and confounding by indication rather than on demonstrating efficacy.

Pros, cons, and trade-offs

. - vs imposed PASS: A voluntary PASS gives the sponsor design latitude, faster start (no PRAC protocol gate), and control over scope and dissemination — useful for hypothesis-generating signal characterisation, label-enrichment evidence, or HTA-facing safety packages. Cost: it carries less a priori regulatory weight, PRAC has not endorsed the protocol, and a voluntary study cannot by itself discharge a binding pharmacovigilance obligation. Prefer voluntary when the safety question is sponsor-driven and not a regulatory condition; an imposed PASS is required when the authority has mandated the evidence as a condition of marketing. - vs spontaneous-reporting / disproportionality signal detection: A PASS supplies a defined denominator (person-time at risk), a comparator, and protocol-prespecified outcome definitions, so it quantifies and tests a hazard rather than merely flagging it. Cost: far more expensive and slower than mining a spontaneous-report database. Prefer a PASS to characterise or refute a signal that disproportionality analysis has already raised. - vs a head-to-head comparative-effectiveness study: A PASS is governed by the pharmacovigilance legal framework (GVP) and is safety-focused, so it inherits PSUR/RMP linkage, qualified-person-for-pharmacovigilance accountability, and adverse-event reporting obligations that a generic effectiveness study does not. Cost: that governance overhead is wasted if the question is purely comparative effectiveness. The analytic core of a non-interventional PASS is usually an active-comparator new-user or self-controlled design — the PASS label adds the regulatory wrapper.

When to use

. A sponsor wants to identify, quantify, or confirm a safety concern for an authorised product on its own initiative — e.g. characterising the real-world incidence of a labelled AESI, evaluating effectiveness of a risk minimisation measure (a pregnancy-prevention programme, a prescriber education tool), generating EU PAS Register-listed safety evidence to support a future label or HTA submission, or pre-empting a likely regulatory request. Choose the non-interventional route when the product is used per its authorisation and the question can be answered in secondary data (claims, EHR, disease/product registries) or a light-touch prospective cohort.

When NOT to use — and when it is actively misleading or dangerous

. - The study is a condition of the marketing authorisation. If PRAC or a national authority has imposed it, a voluntary design does not satisfy the obligation; submitting voluntary work in its place is a compliance failure. Use the imposed pathway with PRAC protocol assessment. - The intervention departs from routine care. Allocating treatment by protocol, adding non-routine tests, or randomising converts the study into a clinical trial; calling it a "non-interventional PASS" mislabels it and evades the correct ethics/regulatory regime — a serious integrity problem. - The data cannot support the safety estimand. A rare AESI needs a denominator and follow-up that a short, fragmented data source cannot deliver; reporting an "incidence" on unstable person-time is misleading. If only signal detection is feasible, do not dress it up as a quantitative PASS. - Confounding by indication is unaddressed. Comparing a drug to non-users for a safety outcome reproduces channelling bias; without an active comparator and time-zero alignment, a "reassuring" or "alarming" PASS result can be an artefact, not the drug.

Data-source operational depth

. - Claims (FFS or commercial): Exposure is the pharmacy claim (NDC + `fill_date` + `days_supply`); AESIs are captured from inpatient/outpatient diagnosis and procedure codes. Require continuous medical + pharmacy enrollment across baseline so absence of prior exposure and outcomes is observed, not missing. Failure modes: Medicare Advantage-only person-time lacks fee-for-service claims, so AESI ascertainment is silently incomplete — restrict to enrollees with Parts A/B/D (or commercial medical+pharmacy) and exclude MA-only spans. Acute, hospitalisation-coded AESIs (e.g. anaphylaxis, DKA, acute liver injury) are well captured; insidious or outpatient-managed events are not. Claims carry no death cause and weak severity, so adjudication-ready code algorithms with PPV from prior validation are essential. - EHR: Labs, vitals, problem lists, and notes sharpen AESI definitions (e.g. ALT/AST thresholds for Hy's-law liver injury) and baseline risk factors that claims miss — a real advantage for safety. But visit-driven capture means a patient who leaves the network is differentially lost, and an out-of-network hospitalisation for the very AESI of interest can be invisible; define observation windows explicitly and treat loss to follow-up as potentially informative. - Registry (disease/product/pregnancy): Strongest for adjudicated, clinically rich safety outcomes and for products with mandated pregnancy or device registries; typically weak for complete drug exposure and for a contemporaneous comparator. Link to claims for the full fill history and to a death index to firm up censoring and fatal-outcome capture. - Linked claims–EHR–vital records: The ideal substrate for a safety PASS — EHR severity + claims completeness + reliable mortality — but linkage selects the linkable subset and introduces order/fill/service-date discrepancies that must be reconciled before time-zero and the susceptibility window are fixed.

Worked claims example

Voluntary, non-interventional PASS to quantify the incidence of acute liver injury (ALI) among new users of a recently authorised oral antifungal, with an active comparator, in a commercial + Medicare FFS database. (1) Eligibility: age ≥18 and ≥365 days of continuous A/B/D (or commercial medical+pharmacy) enrollment before the first dispensing — the baseline window in which prior ALI and risk factors (alcohol-related codes, hepatitis, hepatotoxic co-medications) are measured. (2) New-user washout: no fill of the study drug or the comparator antifungal in the prior 365 days, so person-time starts at a true initiation. (3) Time zero = first qualifying `fill_date`; assign arm from the dispensed NDC. (4) Prespecified AESI algorithm: first inpatient ALI diagnosis (ICD code on a hospital claim) with no ALI code in baseline; this first-event coding plus the washout removes prevalent disease. (5) Susceptibility / risk window: from time zero through the last covered day (`fill_date` + `days_supply`) plus a prespecified 30-day carry-over, reflecting drug-induced liver injury latency. (6) Person-time and censoring: accrue at risk until the first ALI event, disenrollment, death, end of data, or end of the risk window; exclude MA-only spans so person-time reflects FFS-observable claims. (7) Output: crude incidence rate per 1,000 person-years per arm, an age/sex-standardised incidence ratio against the comparator, and a Cox or Fine-Gray comparative hazard with death as a competing risk. (8) Pre-registration in the EU PAS Register and a negative-control outcome to probe residual confounding complete the protocol — making the voluntary study defensible to PRAC, HTA reviewers, and journals even without imposed oversight.

Worked example

Scenario

A company has received approval for a new oral antifungal drug. The label mentions a possible risk of liver injury, but the pre-approval trials were too small and too short to measure how often this happens in ordinary patients. The company decides — without being told to by a regulator — to run a voluntary PASS using insurance claims data to find out how common liver injury is among the first real-world users, compared to patients taking an older antifungal. Below is a simplified comparison showing how this voluntary PASS differs from a PASS that a regulator has imposed as a condition of approval.

Dataset

Imposed vs voluntary PASS: a side-by-side comparison of key features

FeatureImposed PASSVoluntary PASS (this concept)
Who requires it?Regulatory agency (e.g., EMA/PRAC) — it is a legal condition of approvalThe company itself — no regulator has demanded it
What question does it answer?A specific safety question the regulator identified as unanswered before approvalA safety question the sponsor considers important or useful for label or HTA purposes
Real-world safety after approval?Yes — conducted in patients using the approved drug in routine careYes — same setting, same kind of real-world data
Who reviews the protocol first?PRAC (the EMA safety committee) must assess and approve the protocol before the study startsNo mandatory regulatory pre-review; ENCePP registration is strongly encouraged
What happens if it is not completed?Legal and regulatory consequences — possible suspension or finesNo legal penalty, but the company loses the scientific and reputational value it sought
How does it differ from a pre-approval trial?Both differ from trials: the drug is prescribed normally, no random assignment, no extra tests added by the protocolSame — non-interventional, observational, based on routine care records

Steps

  • The company identifies the safety question on its own: how often does the new antifungal cause liver injury in real-world patients, compared to an older antifungal?

  • Because no regulator has imposed this study, it is classified as voluntary — the company controls the timeline, data source, and scope.

  • The company registers the protocol in the EU PAS Register (ENCePP) before collecting data, making the study plan public and the results credible to regulators and HTA reviewers even without mandatory PRAC oversight.

  • The study design is non-interventional: patients are prescribed the drug by their own doctors in routine care, not by a protocol. Insurance claims or EHR records are used — not a trial.

  • An active comparator (the older antifungal) is included so the incidence of liver injury in new users of the study drug can be compared to a similar patient group, rather than to non-drug-users who may be healthier to begin with.

  • The result — crude incidence rates per arm and a comparative hazard estimate — can support a future label update, an HTA submission, or early detection of a safety signal, even though the study was not required by law.

Result

A voluntary PASS is used when the sponsor wants to identify or quantify a real-world safety concern for an approved drug on its own initiative. It follows the same non-interventional, claims- or EHR-based design as an imposed PASS, but sits outside mandatory regulatory oversight — making it faster to start and more flexible in scope, while carrying less inherent regulatory authority than a study the agency required.

Runnable example

python implementation

Non-interventional voluntary-PASS engine: build a new-user safety cohort, ascertain a first-event AESI from a validated code algorithm, accrue FFS-observable person-time over a days_supply-based risk window, and return crude incidence rates per arm....

import pandas as pd
import numpy as np

WASHOUT_DAYS = 365   # drug-free + continuous-enrollment baseline that defines a "new user"
CARRYOVER_DAYS = 30  # AESI latency added to the last covered day to close the risk window

def build_pass_cohort(rx: pd.DataFrame, enroll: pd.DataFrame, dx: pd.DataFrame) -> pd.DataFrame:
    rx = rx.sort_values(["person_id", "fill_date"])
    study = rx[rx["drug_class"].isin(["STUDY", "COMPARATOR"])]

    # Time zero = first fill of study drug or active comparator; arm = drug dispensed that day.
    idx = (study.groupby("person_id").first().reset_index()
                .rename(columns={"fill_date": "index_date", "drug_class": "arm"}))

    # New-user washout: drop anyone with a study/comparator fill in the WASHOUT_DAYS before index.
    prior = study.merge(idx[["person_id", "index_date"]], on="person_id")
    prior = prior[(prior["fill_date"] < prior["index_date"]) &
                  (prior["fill_date"] >= prior["index_date"] - pd.Timedelta(days=WASHOUT_DAYS))]
    idx = idx[~idx["person_id"].isin(prior["person_id"])].copy()

    # Continuous, FFS-observable enrollment across baseline through index (no MA-only spans -> no silent AESI gaps).
    e = enroll.merge(idx[["person_id", "index_date"]], on="person_id")
    e["covers"] = ((e["enroll_start"] <= e["index_date"] - pd.Timedelta(days=WASHOUT_DAYS)) &
                   (e["enroll_end"]   >= e["index_date"]) & (~e["ma_only"]))
    idx = idx[idx["person_id"].isin(e.loc[e["covers"], "person_id"])].copy()

    # Exclude prevalent AESI: require no AESI dx in the baseline window (first-event definition).
    base_dx = dx[dx["aesi"]].merge(idx[["person_id", "index_date"]], on="person_id")
    prevalent = base_dx[(base_dx["dx_date"] < base_dx["index_date"]) &
                        (base_dx["dx_date"] >= base_dx["index_date"] - pd.Timedelta(days=WASHOUT_DAYS))]
    idx = idx[~idx["person_id"].isin(prevalent["person_id"])].copy()

    # Risk window end = last covered day (fill_date + days_supply) over on-treatment fills, plus carry-over.
    on_tx = study.merge(idx[["person_id", "index_date", "arm"]], on="person_id")
    on_tx = on_tx[on_tx["fill_date"] >= on_tx["index_date"]]
    on_tx["covered_end"] = on_tx["fill_date"] + pd.to_timedelta(on_tx["days_supply"], unit="D")
    rx_end = on_tx.groupby("person_id")["covered_end"].max() + pd.Timedelta(days=CARRYOVER_DAYS)
    idx = idx.merge(rx_end.rename("risk_end"), on="person_id")

    # Censor at min(risk window end, disenrollment, end of data); first incident AESI on/after index = event.
    disenroll = enroll.groupby("person_id")["enroll_end"].max().rename("disenroll")
    idx = idx.merge(disenroll, on="person_id")
    idx["fu_end"] = idx[["risk_end", "disenroll"]].min(axis=1)

    inc = dx[dx["aesi"]].merge(idx[["person_id", "index_date", "fu_end"]], on="person_id")
    inc = inc[(inc["dx_date"] >= inc["index_date"]) & (inc["dx_date"] <= inc["fu_end"])]
    first_evt = inc.groupby("person_id")["dx_date"].min().rename("event_date")
    idx = idx.merge(first_evt, on="person_id", how="left")
    idx["event"] = idx["event_date"].notna().astype(int)
    idx["exit_date"] = idx["event_date"].fillna(idx["fu_end"])
    idx["person_days"] = (idx["exit_date"] - idx["index_date"]).dt.days.clip(lower=0)

    rates = (idx.groupby("arm")
                .agg(events=("event", "sum"), person_years=("person_days", lambda d: d.sum() / 365.25))
                .assign(ir_per_1000py=lambda t: 1000 * t["events"] / t["person_years"]))
    return rates.reset_index()
r implementation

Non-interventional voluntary-PASS cohort + crude incidence with data.table. Inputs mirror the Python version: rx : person_id, fill_date (Date), drug_class in {'STUDY','COMPARATOR'}, days_supply enroll : person_id, enroll_start (Date), enroll_end (Date),...

library(data.table)
WASHOUT_DAYS   <- 365L
CARRYOVER_DAYS <- 30L

build_pass_cohort <- function(rx, enroll, dx) {
  setDT(rx); setDT(enroll); setDT(dx)
  setorder(rx, person_id, fill_date)
  study <- rx[drug_class %chin% c("STUDY", "COMPARATOR")]

  # Time zero = first study/comparator fill; arm = drug dispensed that day.
  idx <- study[, .(index_date = fill_date[1L], arm = drug_class[1L]), by = person_id]

  # New-user washout.
  s <- merge(study, idx[, .(person_id, index_date)], by = "person_id")
  prior <- unique(s[fill_date < index_date & fill_date >= index_date - WASHOUT_DAYS, person_id])
  idx <- idx[!person_id %chin% prior]

  # FFS-observable continuous enrollment across baseline through index (no MA-only spans).
  e <- merge(enroll, idx[, .(person_id, index_date)], by = "person_id")
  ok <- e[enroll_start <= index_date - WASHOUT_DAYS & enroll_end >= index_date & !ma_only,
          unique(person_id)]
  idx <- idx[person_id %chin% ok]

  # First-event: drop prevalent AESI in the baseline window.
  bd <- merge(dx[aesi == TRUE], idx[, .(person_id, index_date)], by = "person_id")
  prevalent <- unique(bd[dx_date < index_date & dx_date >= index_date - WASHOUT_DAYS, person_id])
  idx <- idx[!person_id %chin% prevalent]

  # Risk window end = max(fill_date + days_supply) over on-treatment fills + carry-over.
  ot <- merge(study, idx[, .(person_id, index_date)], by = "person_id")[fill_date >= index_date]
  ot[, covered_end := fill_date + days_supply]
  rxend <- ot[, .(risk_end = max(covered_end) + CARRYOVER_DAYS), by = person_id]
  idx <- merge(idx, rxend, by = "person_id")

  # Censor at min(risk_end, disenrollment); first incident AESI in window = event.
  dis <- enroll[, .(disenroll = max(enroll_end)), by = person_id]
  idx <- merge(idx, dis, by = "person_id")
  idx[, fu_end := pmin(risk_end, disenroll)]

  ev <- merge(dx[aesi == TRUE], idx[, .(person_id, index_date, fu_end)], by = "person_id")
  ev <- ev[dx_date >= index_date & dx_date <= fu_end, .(event_date = min(dx_date)), by = person_id]
  idx <- merge(idx, ev, by = "person_id", all.x = TRUE)
  idx[, event := as.integer(!is.na(event_date))]
  idx[, exit_date := fifelse(is.na(event_date), fu_end, event_date)]
  idx[, person_days := pmax(as.integer(exit_date - index_date), 0L)]

  idx[, .(events = sum(event), person_years = sum(person_days) / 365.25), by = arm
      ][, ir_per_1000py := 1000 * events / person_years][]
}