← Methods repository
CONCEPTFOUNDATIONALPYTHON · R4 citations

HCPCS Level II Codes and J-Codes

A federal coding system maintained by CMS that assigns a five-character alphanumeric code (one letter + four digits) to every non-physician service, supply, and drug billed outside of a physician visit, with the J-code family (J + 4 digits) specifically covering drugs administered by a provider — the essential data element for identifying medical-benefit (buy-and-bill) drug exposure in claims.

Data Standardcoding-systemdata-standardprimitivedrugsproceduresclaimsmedical-benefitprovider-administered
On this page
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

HCPCS Level II J-codes are the billing codes that hospitals and doctor offices use when they give a patient a drug by injection or infusion during a visit — think IV chemotherapy, infused immunotherapy, or a biologic given in a clinic. Each code is one letter (J, Q, or C) followed by four numbers, and each code's description specifies exactly how many milligrams (or other units) one billed unit represents. Because these codes appear on medical claims rather than pharmacy prescriptions, any study that wants to see all the cancer drugs or biologics a patient received must look at both the medical side (J-codes) and the pharmacy side (prescription fills) — using only one source will miss a large share of real-world drug use.

When to use it
Use J-codes for IV/infused drugs; use NDCs for oral and self-administered drugs; use both for complete ascertainment in oncology or biologic-heavy therapeutic areas.
Always pair J-codes (for drug identity) with CPT 96413-series codes (for administration type and complexity) in any oncology claims analysis.
Use J-codes as the drug identifier; use revenue center codes to identify the cost center and distinguish drug charges from administration charges in cost analyses.
Watch out for
No days_supply, so exposure duration must be modeled from administration cadence; billing-unit to dose conversion requires consulting the code descriptor; NOC-window under-ascertainment for newly approved drugs.
J-codes alone do not identify the administration setting, complexity, or duration; CPT codes are needed to distinguish a simple IV push from a prolonged infusion for HCRU analyses.
Revenue center codes provide site-of-service and cost-center context that J-codes alone do not supply; both fields are needed for complete UB-04 analysis.

HCPCS Level II

(Healthcare Common Procedure Coding System Level II) is the federal alphanumeric coding standard maintained by the Centers for Medicare and Medicaid Services (CMS) for services, supplies, and drugs that are not covered by CPT (Level I). Every code is exactly five characters: one letter (A–V) followed by four digits. CMS updates the system quarterly, not annually like CPT, which means codes for newly approved drugs can appear within months of FDA clearance — but also means code lists used in analyses go stale and must be refreshed against the quarterly CMS release files at each study update.

Format, families, and scope

The letter determines the broad service category. Key families for RWE and HEOR work include:

  • J codes (J0001–J9999): Drugs administered other than by the oral route — the family used for nearly all provider-administered (infused, injected, or instilled) drugs. The J9000–J9999 sub-range historically covers antineoplastic agents specifically. Example public codes from CMS payment files: J9271 (pembrolizumab, per 1 mg), J9305 (pemetrexed, per 10 mg), J9000 (doxorubicin, per 10 mg).
  • Q codes (Q0000–Q9999): CMS temporary codes for services and drugs awaiting permanent code assignment; oncology biologics newly approved by the FDA frequently launch here before receiving a permanent J-code. Q codes behave identically to J-codes in claims data — service date, billing units, NDC field — but are more likely to be combined with J3490 (Not Otherwise Classified, parenteral drug) or J3590 (unclassified biological) during the pre-permanent-code window.
  • C codes (C1000–C9999): Hospital outpatient prospective payment system (OPPS) codes; newly approved drugs in the hospital outpatient setting are assigned C-codes until they receive a permanent J or Q.
  • A codes (A0000–A9999): Ambulance, medical and surgical supplies, administrative, miscellaneous.
  • B codes (B4000–B9999): Enteral and parenteral nutrition supplies.
  • E codes (E0100–E9999): Durable medical equipment (DME) — wheelchairs, walkers, oxygen.
  • G codes (G0000–G9999): CMS temporary codes for procedures and quality measures not in CPT, used by CMS demonstration projects, quality programs (MIPS), and some cancer screening services.

Core conceptual distinction — the medical-benefit / pharmacy-benefit split

This is the single most consequential distinction in RWE drug-exposure ascertainment, and HCPCS Level II is the key data element on the medical-benefit side.

Provider-administered drugs — those infused or injected in a physician office, hospital outpatient department (HOPD), or infusion center — are purchased by the provider, administered to the patient, and billed to the payer under the medical benefit. In Medicare, this is Part B. In commercial insurance, it is the medical benefit file. These administrations appear as HCPCS J- or Q-code lines on the CMS-1500 (professional) or UB-04 (institutional) claim, with a service date, a billing-unit count, and (since the Omnibus Budget Reconciliation Act of 1990 and strengthened by later CMS policy) an NDC field that should identify the specific product administered.

Self-administered drugs — pills, self-injected biologics, or oral oncologics dispensed at retail or specialty pharmacies — are billed under the pharmacy benefit (Part D for Medicare, or a separate pharmacy benefit for commercial) using an 11-digit National Drug Code (NDC), a fill date, and a days_supply. They do not appear on medical claims and have no HCPCS code in most contexts.

The practical consequence: an RWE study that queries only pharmacy claims will miss 100% of IV chemotherapy, most infused immunotherapy (e.g., pembrolizumab, nivolumab, atezolizumab), all IV biologics for RA (tocilizumab, infliximab), IV bone agents, and any other provider-administered drug. Conversely, a study that queries only medical claims for oncology drug exposure will miss oral targeted therapies (erlotinib, osimertinib, ibrutinib, capecitabine) dispensed as Part D fills. Complete exposure ascertainment for oncology, rheumatology, neurology (natalizumab), and most biologic-heavy therapeutic areas requires querying both files.

Billing units and the dose computation — the most common error in HCPCS pharmacoepi

Each HCPCS code has a written descriptor that specifies the unit of measure for one billing unit. The billing unit is almost never milligrams and almost never one vial. Examples from public CMS Annual Physician Fee Schedule files:

  • J9271 (pembrolizumab): "injection, 1 mg" → 1 unit = 1 mg
  • J9305 (pemetrexed): "injection, per 10 mg" → 1 unit = 10 mg
  • J0800 (corticotropin): "up to 40 USP units" → 1 unit = 40 USP units
  • J1745 (infliximab): "10 mg" → 1 unit = 10 mg

The claim shows `units_billed` (the HCPCS units field). To recover the administered dose:

`administered_dose_mg = units_billed × descriptor_mg_per_unit`

This sounds simple but has several failure modes that are pervasive in the literature:

  1. Analysts conflate billing units with milligrams. For J9305 (pemetrexed, per 10 mg), 50 billed units means 500 mg, not 50 mg. The descriptor must be consulted, not assumed.
  2. The descriptor quantity changes between code revisions. A code retired and replaced (common in the quarterly update cycle) may have a different per-unit amount than its predecessor, breaking cross-year dose comparisons.
  3. Providers sometimes bill whole vials rather than exact dose. Because vial sizes are standardized and dose is weight-based, the billed units can reflect vial wastage accounting, not the true per-patient dose. This introduces heteroskedastic measurement error in dose across practice settings.
  4. Units on the same service date summing to more than one standard dose can represent split billing, combination therapy, or data error — a pre-analysis quality check is essential.

The NOC-code under-ascertainment window for newly launched drugs

When a new drug receives FDA approval, it typically lacks a permanent HCPCS code for weeks to months (sometimes 6–18 months). During this period, providers bill using a "not otherwise classified" (NOC) code:

  • J3490 — Unclassified drugs
  • J3590 — Unclassified biologics
  • C9399 — Unclassified drugs or biologics, hospital outpatient (OPPS/C-APC setting)

Under NOC billing, the specific drug identity is conveyed only in the NDC field on the claim line — a field that is often missing, incorrectly formatted, or populated inconsistently across payers and practice settings. As a result, NOC-period administrations are routinely missed or misclassified in RWE studies that identify drugs solely by their permanent HCPCS code. For a drug with a 12-month NOC window (not unusual for new immuno-oncology agents), the entire first year of real-world use is under-counted, which can bias adoption curves, first-line utilization rates, and even comparative safety/effectiveness analyses that use first-to-market date as an anchoring variable. The analyst must

  1. include J3490, J3590, and C9399 in all drug-identification queries,
  2. parse the NDC field on NOC-coded lines, and
  3. document and quantify the NOC window as a study limitation.

CMS ASP NDC-to-HCPCS crosswalk

CMS publishes a quarterly Average Sales Price (ASP) Drug Pricing File that maps NDCs to the HCPCS code under which the drug is reimbursed. This crosswalk is the authoritative forward-link from NDC → HCPCS and is the mechanism by which OMOP Drug domain ingestion of provider-administered drugs can be harmonized. Analysts building NDC-to-HCPCS crosswalks for their own cohort work should start from the CMS ASP file, then supplement with the CanMED-HCPCS (the NCI tool that lists all HCPCS codes for oncology medications by therapeutic category, validated against CMS HCPCS Indices 2012–2018 and commercially available drug databases). The crosswalk runs in both directions: the NDC field on a J3490/C9399 line identifies the product; the J-code on a medical claim identifies the product when the NDC is missing.

No days_supply — the exposure-duration modeling challenge

Because provider-administered drugs have no `days_supply` field (the drug was consumed at the point of service), analysts cannot use the standard pharmacy-claims approach of forward-filling days of coverage from each fill. Instead, exposure duration must be modeled from the administration cadence — typically the regimen-specific dosing interval (e.g., every 3 weeks for pembrolizumab, every 4 weeks for denosumab) applied between claim dates. This requires clinical knowledge of the dosing schedule, introduces assumption-dependence that must be pre-specified in the SAP, and fails for off-schedule administrations (dose delays, early discontinuation between claims). Approaches include

  1. fixed-window persistence (did the next administration occur within a pre-specified grace period?),
  2. regimen-specific cycle modeling, and
  3. linkage to prescription orders in an EHR to confirm intended versus actual cadence.

Revenue center code pairing

On UB-04 institutional claims, the drug J-code appears on a line alongside revenue center code 0636 (pharmacy — IV solutions) or occasionally 0250 (pharmacy general). This pairing allows researchers to distinguish the drug charge from the administration charge (revenue center 0335 for chemotherapy infusion, 0636 for IV push/infusion). On professional/CMS-1500 claims (carrier file), the J-code appears directly without a revenue center code. Analysts must handle both claim types.

OMOP Drug domain integration

The OMOP CDM Drug domain ingests HCPCS codes through the Drug vocabulary, mapping each J-code to a standard concept in the RxNorm or SNOMED hierarchy via the OMOP vocabulary's NDC-to-HCPCS crosswalk and a manually curated HCPCS-to-drug mapping. This allows HCPCS-identified drug exposures to be harmonized with NDC-identified pharmacy-fill exposures into a single `drug_exposure` table. However, mapping fidelity varies: NOC codes map to "drug unspecified" and require NDC-level disambiguation, and newly approved drugs may lack a OMOP concept until the next quarterly vocabulary release.

Pros, cons, and trade-offs — specific and comparative

  • vs NDC-based pharmacy claims for drug identification: HCPCS/J-codes capture what NDC pharmacy claims cannot — every provider-administered drug. For infused oncologics and biologics, J-codes are the only reliable source. Cost: no days_supply, no dispensing details, potential billing-unit interpretation error, and the NOC window. Prefer J-codes for all provider-administered drugs; prefer NDCs for oral and self-administered drugs; require both for complete ascertainment.
  • vs EHR medication administration records (MARs): MARs contain the actual dose infused, the infusion date, and the nurse-charted start/stop time — far more precise for dose than billing units. Cost: MARs are system-specific (usually a single health system), may not capture medications given elsewhere, and cannot provide population-level denominators. Prefer J-code claims for population-representative pharmacoepi; prefer MARs linked to J-codes when precise dose and duration of infusion are needed.
  • vs CMS-1500 specialty billing (CPT procedure codes for drug administration): CPT administration codes (96413 for chemotherapy infusion, 96415 for each additional hour, etc.) appear alongside J-codes on the same claim but identify the administration service, not the drug. The CPT code cannot identify which drug was given — only that a drug was administered. The J-code is required for drug identity; CPT is required for administration setting and complexity.
  • vs revenue center 0636 alone: Revenue center 0636 on a UB-04 indicates a pharmacy/IV item was dispensed but does not identify the drug. J-codes on the same revenue line provide the drug identity. Do not use revenue center alone as a drug identifier; require the J-code.

When NOT to use — and when HCPCS-based ascertainment is actively misleading or dangerous

  • As the sole drug identifier for therapeutic areas with both oral and IV agents. A study of "pembrolizumab use" that queries only J9271 is complete only for 2017-onward (when J9271 was assigned). Studies of combination regimens that include an oral agent (erlotinib, capecitabine, ibrutinib) will systematically miss the oral arm unless Part D pharmacy claims are added. This is the most dangerous failure mode in oncology pharmacoepi.
  • When the payer does not submit medical claims at the line level. Medicare Advantage (MA) enrollees' medical claims are encounter-based rather than fully adjudicated fee-for-service. J-code granularity is frequently absent or unreliable in MA encounter data. Restricting to FFS-observable enrollment (Part A/B/D or commercial medical + pharmacy benefit) before building any J-code cohort is mandatory; MA-only person-time should be excluded.
  • When billing-unit counts are used as milligram doses without consulting the descriptor. The resulting dose will be wrong by the factor of the descriptor amount (e.g., 10× error for pemetrexed if units are treated as milligrams). This error propagates silently into dose-response analyses.
  • When the NOC window is ignored for newly approved drugs. A study that starts its observation window in the year a drug received permanent J-code assignment will miss all administrations billed under J3490/J3590 in the prior NOC period. For fast-adopting drugs, this can mean missing the majority of real-world first-year use.
  • When J-codes are used without pairing with the CPT administration code or place of service to distinguish an infusion given at a physician office (CPT 96413 + J-code, place of service 11) from one given at a hospital outpatient department (same J-code, revenue center 0636, place of service 22). Site of service matters for cost, access, and safety analyses.

Data-source operational depth

  • Medicare FFS (Part B carrier and outpatient files): The primary home of J-codes. Carrier file contains professional claims (CMS-1500 equivalent); outpatient file contains institutional claims (UB-04 equivalent) from hospital outpatient departments. Both contain the `hcfa_mtus_cnt` (units) and the procedure code (J-code). The NDC field is available on the carrier file (as the `lne_ndc_cd` on the line item) and on the outpatient revenue center line. MA enrollees lack these adjudicated claim details — exclude MA-only person-time or supplement with MA encounter-data J-codes after validating completeness. For complete oncology drug capture, also query the DME file for any oral drugs billed under HCPCS (unusual but not impossible for clinical trial patients).
  • Commercial claims (MarketScan, Optum, IQVIA): J-codes appear in the medical (outpatient and inpatient professional) claims tables. Column names vary by vendor; units may appear as `quantity`, `units`, or `submit_charge_units`. Verify units interpretation with vendor documentation — some vendors normalize to "quantity dispensed" rather than "HCPCS billing units," which can differ. NDC availability on medical claim lines varies by vendor and payer; it is more consistent in MarketScan than in some Optum products.
  • EHR (Epic, Cerner, Allscripts): EHR medication administration records capture the exact dose infused, the NDC, and the infusion date — more accurate for dose than billing units. However, EHR does not capture administrations at other facilities. For multi-site analyses, link EHR administration records to medical claims to verify J-code billing completeness, especially for 340B-discounted drugs where billing may differ from acquisition pricing.
  • OMOP CDM: HCPCS J-codes are mapped into the Drug domain via the OMOP vocabulary's HCPCS standard concepts. Query `drug_exposure` for both `drug_source_concept_id` (the raw J-code concept) and the standard `drug_concept_id` (the harmonized RxNorm/SNOMED mapping). NOC codes (J3490, J3590) will map to a generic unclassified drug concept; supplement by querying `drug_source_value` for the NDC string associated with those lines.

Decision diagram

flowchart LR
  MED["Medical Claim\n(CMS-1500 / UB-04)"]
  PHARM["Pharmacy Claim\n(Part D / pharmacy benefit)"]
  JCODE["J-code or Q-code\n(provider-administered drug)\ne.g. J9271 pembrolizumab"]
  NDC["NDC + days_supply\n(self-administered drug)\ne.g. 00310094630 erlotinib"]
  NOC["NOC code line\n(J3490 / J3590 / C9399)\n→ parse NDC field"]
  DOSE["Administered dose\n= units_billed × descriptor_mg_per_unit"]
  XWALK["CMS ASP NDC–HCPCS crosswalk\n(quarterly)"]
  MED --> JCODE
  MED --> NOC
  PHARM --> NDC
  JCODE --> DOSE
  NOC --> |"NDC field present?"| DOSE
  NDC --> XWALK
  XWALK --> JCODE
HCPCS Level II J-codes sit exclusively on medical claims; NDCs sit on pharmacy claims. Complete drug ascertainment requires both. NOC-coded lines (J3490/J3590/C9399) bridge the period before a permanent J-code is assigned and rely on the NDC field for drug identity. The CMS ASP NDC-HCPCS crosswalk links the two systems.

Worked example

Scenario

An analyst is studying real-world pembrolizumab dosing in a commercial insurance database. Pembrolizumab (Keytruda) is an infused immunotherapy — it is given IV in a clinic, billed under the medical benefit as HCPCS J9271, where one billing unit equals 1 mg. The standard approved dose is 200 mg every 3 weeks. The analyst wants to verify that the billed units on a small sample of claim lines translate to the expected doses, and then flag any lines that look anomalous. The table below shows five claim lines from three patients, as they would appear in a medical claims outpatient or carrier file.

Dataset

Five medical claim lines for pembrolizumab (HCPCS J9271, descriptor "injection, 1 mg"). The administered_dose_mg column is the target — computed as units_billed × 1 mg.

claim_idperson_idservice_datehcpcs_codeunits_billedadministered_dose_mg
C00130012023-03-01J9271200200
C00230012023-03-22J9271200200
C00330022023-04-05J9271100100
C00430022023-04-26J9271200200
C00530032023-05-10J9271200200
FIG. 1 — DESIGN TIMELINE
Pembrolizumab Q3W administration cycles for two patients — J9271 billing units to dose
Pembrolizumab Q3W administration cycles for two patients — J9271 billing units to dose

Steps

1Look up the descriptor for J9271 in the CMS HCPCS file: 'pembrolizumab, injection, 1 mg.' This means 1 billing unit = 1 mg. Administered dose (mg) = units_billed × 1 mg.
2Patient 3001, claim C001: 200 units × 1 mg = 200 mg. This matches the standard 200 mg flat dose. Patient 3001, claim C002: same calculation, 200 mg, administered 21 days later — consistent with the 3-week cycle.
3Patient 3002, claim C003: 100 units × 1 mg = 100 mg. The standard dose is 200 mg, so 100 mg is half the expected amount. Flag for review — possible weight-based dosing (2 mg/kg for a 50 kg patient), a split vial billed on a second line (check for a companion line on the same date), or a data entry error.
4Patient 3002, claim C004: 200 mg, 21 days after C003 — consistent with a next cycle at standard dose. The 100 mg on C003 is likely weight-based dosing for a lighter patient, not an error.
5Patient 3003, claim C005: 200 mg — standard dose. Service date is 10 May 2023; there is no prior claim in the dataset for this patient. Check whether this patient was in the NOC window (J3490 billed before J9271 was assigned) or enrolled after the permanent code was available.
6Now contrast with J9305 (pemetrexed, descriptor 'injection, per 10 mg'). If a claim showed 50 units of J9305, the administered dose would be 50 × 10 mg = 500 mg — NOT 50 mg. Treating billing units as milligrams without checking the descriptor would introduce a 10× underestimate of the dose for pemetrexed.

Result

administered_dose_mg = units_billed × descriptor_amount_per_unit. For J9271: 200 units × 1 = 200 mg. For J9305: 50 units × 10 = 500 mg. Billing units are not milligrams; always look up the descriptor before computing dose.

Trade-offs

Pros of this
Captures all provider-administered drugs (infused biologics, IV chemotherapy) that never appear in pharmacy claims; also available when days_supply is not applicable because the drug is consumed at the point of service.
Pros of this
J-codes identify the specific drug administered; CPT codes identify the administration service (infusion type, duration, drug class) but not the drug name or dose.
Pros of this
J-codes on UB-04 claims appear alongside revenue center 0636, but J-codes identify the drug; revenue center 0636 alone only identifies that a pharmacy item was dispensed, not which drug.

Runnable example

Validates HCPCS Level II code format, separates J-code lines from procedure claims, computes administered dose from billing units using a caller-supplied descriptor lookup table, and flags NOC codes (J3490, J3590, C9399) for supplemental NDC-based identification.

import re
from dataclasses import dataclass, field
from typing import Optional

# ------------------------------------------------------------------ format validation
HCPCS_PATTERN = re.compile(r"^[A-V]\d{4}$")
J_CODE_PATTERN = re.compile(r"^J\d{4}$")
NOC_CODES = {"J3490", "J3590", "C9399"}

def is_valid_hcpcs(code: str) -> bool:
    """Return True if code matches the 1-letter + 4-digit HCPCS Level II format."""
    return bool(HCPCS_PATTERN.match(code.strip().upper()))

def is_j_code(code: str) -> bool:
    """Return True if code is a J-family drug code (J0001-J9999)."""
    return bool(J_CODE_PATTERN.match(code.strip().upper()))

def is_noc(code: str) -> bool:
    """Return True if code is a Not-Otherwise-Classified placeholder requiring NDC lookup."""
    return code.strip().upper() in NOC_CODES

def j_code_family(code: str) -> str:
    """Classify J-code into antineoplastic (J9000-J9999) vs other drug (J0001-J8999)."""
    code = code.strip().upper()
    if not is_j_code(code):
        return "not_j_code"
    num = int(code[1:])
    if 9000 <= num <= 9999:
        return "antineoplastic_J9"
    return "other_drug_J0_J8"

# ------------------------------------------------------------------ dose computation
# Descriptor lookup: map HCPCS code -> mg per billing unit.
# ANALYST MUST BUILD THIS FROM CMS HCPCS RELEASE FILES.
# Sample entries for illustration only — verify against the current quarterly release.
DESCRIPTOR_MG_PER_UNIT: dict[str, float] = {
    "J9271": 1.0,    # pembrolizumab, per 1 mg
    "J9305": 10.0,   # pemetrexed, per 10 mg
    "J9000": 10.0,   # doxorubicin hydrochloride, per 10 mg
    "J1745": 10.0,   # infliximab, per 10 mg
    "J0800": 40.0,   # corticotropin, up to 40 USP units (units, not mg)
}

def compute_dose(hcpcs_code: str, units_billed: float,
                 descriptor_table: dict[str, float] = DESCRIPTOR_MG_PER_UNIT
                 ) -> Optional[float]:
    """
    Compute administered dose from billing units * descriptor_mg_per_unit.

    Parameters
    ----------
    hcpcs_code     : HCPCS code string (e.g. 'J9305')
    units_billed   : value from the HCPCS units field on the claim line
    descriptor_table: analyst-built lookup {hcpcs_code: mg_per_billing_unit}

    Returns
    -------
    administered dose in the descriptor's unit (usually mg), or None if code not found.
    """
    code = hcpcs_code.strip().upper()
    mg_per_unit = descriptor_table.get(code)
    if mg_per_unit is None:
        return None  # code not in lookup; requires manual descriptor review
    return units_billed * mg_per_unit

# ------------------------------------------------------------------ claim-line processing
@dataclass
class ClaimLine:
    claim_id: str
    person_id: str
    service_date: str
    hcpcs_code: str
    units_billed: float
    ndc: Optional[str] = None  # populated for NOC-coded lines when available

@dataclass
class ProcessedLine:
    claim_id: str
    person_id: str
    service_date: str
    hcpcs_code: str
    units_billed: float
    ndc: Optional[str]
    is_valid: bool
    is_j_code: bool
    is_noc: bool
    j_family: str
    administered_dose: Optional[float]
    dose_flag: str = ""  # "ok" | "noc_no_ndc" | "descriptor_missing" | "invalid_code"

def process_line(line: ClaimLine,
                 descriptor_table: dict[str, float] = DESCRIPTOR_MG_PER_UNIT
                 ) -> ProcessedLine:
    code = line.hcpcs_code.strip().upper()
    valid = is_valid_hcpcs(code)
    j = is_j_code(code)
    noc = is_noc(code)
    family = j_code_family(code) if j else "not_j_code"

    dose = None
    flag = ""
    if not valid:
        flag = "invalid_code"
    elif noc:
        flag = "noc_no_ndc" if not line.ndc else "noc_ndc_present"
        # dose cannot be computed from J3490/J3590 alone; requires NDC-based descriptor lookup
    else:
        dose = compute_dose(code, line.units_billed, descriptor_table)
        flag = "ok" if dose is not None else "descriptor_missing"

    return ProcessedLine(
        claim_id=line.claim_id,
        person_id=line.person_id,
        service_date=line.service_date,
        hcpcs_code=code,
        units_billed=line.units_billed,
        ndc=line.ndc,
        is_valid=valid,
        is_j_code=j,
        is_noc=noc,
        j_family=family,
        administered_dose=dose,
        dose_flag=flag,
    )

# ------------------------------------------------------------------ example
if __name__ == "__main__":
    lines = [
        ClaimLine("C001", "3001", "2023-03-01", "J9271", 200),
        ClaimLine("C002", "3001", "2023-03-22", "J9271", 200),
        ClaimLine("C003", "3002", "2023-04-05", "J9305", 50),   # pemetrexed, 50 units = 500 mg
        ClaimLine("NOC1", "3003", "2023-04-10", "J3490", 1, ndc="00310094630"),
    ]
    for cl in lines:
        pl = process_line(cl)
        print(f"{pl.claim_id}: {pl.hcpcs_code} | family={pl.j_family} "
              f"| units={pl.units_billed} | dose={pl.administered_dose} | flag={pl.dose_flag}")
    # Output:
    # C001: J9271 | family=antineoplastic_J9 | units=200 | dose=200.0 | flag=ok
    # C002: J9271 | family=antineoplastic_J9 | units=200 | dose=200.0 | flag=ok
    # C003: J9305 | family=antineoplastic_J9 | units=50  | dose=500.0 | flag=ok
    # NOC1: J3490 | family=not_j_code        | units=1   | dose=None  | flag=noc_ndc_present

Citations

FOUNDATIONAL / METHODS
  1. [1]Rivera DR, Lam CJK, Enewold L, Petkov VI, Tran Q, Brennan S, Dickie L, McNeel TS, Noone AM, Ohm B, White DP, Warren JL, Mariotto AB, Penberthy L. Development and Utility of the Observational Research in Oncology Toolbox: Cancer Medications Enquiry Database-Healthcare Common Procedure Coding System (HCPCS). JNCI Monographs. 2020;2020(55):39-45.
  2. [2]Zhang J, Haynes K, Mendelsohn AB, Marshall J, Barr CE, McDermott C, Brown J, Kline A, Kenney J, King KJ, Holmes C, Yeung K, Barron J, Yun H, Lockhart CM. Capture of biologic and biosimilar dispensings in a consortium of U.S.-based claims databases: Utilization of national drug codes and Healthcare Common Procedure Coding System modifiers in medical claims. Pharmacoepidemiology and Drug Safety. 2020;29(7):778-785.
REPORTING & GUIDANCE
  1. [3]Centers for Medicare and Medicaid Services. Healthcare Common Procedure Coding System (HCPCS). CMS.gov. Accessed 2024.
  2. [4]Centers for Medicare & Medicaid Services. HCPCS Quarterly Update. CMS.gov. Accessed 2024.