Medicare Advantage, Part D, Medicaid

MA pbp section b8 clin diag ther

medicare_silver.pbp_section_b8_clin_diag_ther·partial·silver·quarterly (CMS publishes new PBP snapshots within a benefit year — quarters present per year are irregular: e.g. 2020 has Q1/Q2/Q4, 2024 has Q1/Q3/Q4, and 2021/2025/2026 are Q1-only; the benefit year each row describes is annual)·Medicare Advantage Plan Benefit Packages (PBP)
Rows
N/A
Columns
159
History
2001 (report_year 2001, effective_period_start 2001-01-01) to 2026 (report_year 2026, effective_period_start 2026-01-01)
Card
yesgrain, traps, filters
Typed tools
1

What it is

  1. 1A cleaned, bitemporal silver copy of Section B-8 of the CMS Medicare Advantage Plan Benefit Package (PBP) Public Use Files — the as-filed member cost-sharing (copay, coinsurance, deductible, max-OOP) and prior-authorization/referral rules each MA plan sets for outpatient CLINICAL and DIAGNOSTIC services.
  2. 2B-8a covers clinical/diagnostic services (lab tests, diagnostic radiology and non-radiology tests, clinical/therapeutic monitoring);
  3. 3B-8b covers outpatient diagnostic and therapeutic RADIOLOGY (including DRS = advanced diagnostic radiology such as MRI/CT/PET).
  4. 4It is the demand-side benefit-design counterpart to provider/payer rate data: it tells you what a Medicare Advantage enrollee actually pays out of pocket for these services under each plan.

Grain

KeyGrain
contract_idplan_idsegment_idreport_yearquarter
  1. 1One row per Medicare Advantage plan benefit package per CMS quarterly PBP release: i.e. one row per contract_id x plan_id x segment_id x report_year x quarter.
  2. 2Verified: COUNT(DISTINCT contract_id|plan_id|segment_id|report_year|quarter) = 201,488 = total row_count.
  3. 3The same plan-year is RE-FILED in multiple quarterly snapshots (Q1-Q4) for 2018+, so a single benefit year can appear in up to 4 rows; pre-2018 years have only one (Q1) snapshot.
  4. 4Collapsing to the latest quarter per plan-year yields 114,175 distinct plan-years.

How to read it

  1. 1Compare what Medicare Advantage enrollees pay out of pocket for outpatient diagnostic and radiology services across plans/insurers/years.
  2. 2Example: to get the current (latest-snapshot) member cost share for advanced diagnostic radiology (MRI/CT) per plan for 2026, take the row with the max quarter per plan-year and read pbp_b8b_copay_amt_drs / pbp_b8b_coins_pct_drs: WITH latest AS (SELECT contract_id,plan_id,segment_id,report_year,MAX(quarter) mq FROM medicare_silver.pbp_section_b8_clin_diag_ther WHERE report_year=2026 GROUP BY 1,2,3,4) SELECT t.contract_id,t.plan_id,t.pbp_b8b_copay_amt_drs,t.pbp_b8b_coins_pct_drs FROM medicare_silver.pbp_section_b8_clin_diag_ther t JOIN latest l ON t.contract_id=l.contract_id AND t.plan_id=l.plan_id AND t.segment_id=l.segment_id AND t.report_year=l.report_year AND t.quarter=l.mq.
  3. 3Answers: how MA diagnostic-imaging cost-sharing is distributed and how it differs by plan/carrier (DRS copay median ~$4, B-8b therapeutic-radiology coinsurance median 20%).

Traps

  1. 1NO is_current / latest flag exists. The same plan-year is re-filed across quarterly snapshots, so a naive COUNT(*) or GROUP BY contract/plan/segment/report_year SUMMED over rows double-counts: 75,577 plan-years appear in 1 quarter, 7,353 in 2, 13,775 in 3, and 17,470 in ALL 4 quarters. To get one current row per plan-year, select MAX(quarter) per (contract_id,plan_id,segment_id,report_year) — that collapses 201,488 raw rows to 114,175.
  2. 2quarter is part of the real key, not a throwaway. The minimal verified grain is contract_id x plan_id x segment_id x report_year x quarter (= 201,488). The profiler reported a 10-column SUPERSET that also listed bid_id, pbp_a_plan_type, and the two pbp_b8*_maxplan_yesno_pos columns — those are functionally dependent extras, not part of the key. version is likewise NOT part of the key.
  3. 3Quarters available per year are irregular and incomplete: 2001-2017 are Q1-only (annual), 2018/2019/2023 have all four, but 2020=Q1/Q2/Q4, 2024=Q1/Q3/Q4, and 2021/2025/2026=Q1-only. Do not assume Q4 is the canonical snapshot — always take MAX(quarter) actually present for that year.
  4. 4Many '*_auth', '*_ehc', and '*_cost_share' string columns are PACKED multi-character flag strings (e.g. auth='01000', coins_ehc='110'), where each character position is a separate yes/no flag for a service sub-type. They are NOT scalar values and must be decoded by position against the CMS PBP B-8 data dictionary. The simple '_yn' companions use CMS coding '1'=Yes, '2'=No (NOT 1/0), with NULL meaning not-applicable for that plan-type/year.
  5. 5bid_id is NULL for exactly the 8,316 oldest rows (report_year 2001-2006) because that field predates 2007; for 2007+ it is just contract_id||'_'||plan_id||'_'||segment_id, so it is derivable and not an independent identifier. Relatedly, version=0 marks that same pre-2007 vintage.
  6. 6Bitemporal columns are lineage, not benefit content, and do not affect the grain: observed_period/effective_period_start just restate Jan 1 of report_year; asserted_at/cms_vintage_sequence/parse_revision/source_url/sha256_content_hash describe Vlada's load (two batches, 2026-05-16 and 2026-05-20) and each plan-year-quarter is asserted exactly once. Duplicate legacy columns also exist (e.g. pbp_b_8a_ded_amt with an extra underscore vs pbp_b8a_ded_amt) and are almost entirely NULL — prefer the itemized dmc/lab/drs/tmc amount and coins_pct fields for real cost-share values.

Columns (159)

ColumnTypeMeaning
contract_idstringCMS MA contract number (e.g. H0022, H0028). First key component; one insurer/org holds many contracts. Always populated.
plan_idstringPlan number within the contract (e.g. '001','004'), zero-padded 3-char string. Second key component.
segment_idstringPlan segment within the plan (service-area segment), zero-padded ('0','1','2'); 27 distinct values. Third key component — a plan can have multiple priced segments. Defaults to '0' when not segmented.
versiondoubleCMS PBP submission/resubmission version number (0-27, right-skewed; most rows 1-6). Functionally dependent on the grain (adding it does not change the distinct count). version=0 corresponds exactly to the 2001-2006 vintage where it was not populated. NOT a snapshot/current flag.
report_yeardoubleBenefit/contract year the row describes (double, 2001-2026). Fourth key component. Equals the year of effective_period_start/observed_period.
quarterdoubleCMS release quarter within the report_year (1-4). Fifth and most important key component: it is the SNAPSHOT dimension — the same plan-year is re-filed each quarter, so quarter distinguishes otherwise-identical plan rows. Not all quarters exist every year.
bid_idstringCMS bid identifier; equals contract_id||'_'||plan_id||'_'||segment_id for all 2007+ rows. NULL for the 8,316 oldest rows (2001-2006), which predate this field. Derivable, not an independent key.
orgtypestringCMS organization-type code (string, '01'-'14'). '01' dominates (177,737 rows, Local CCP/HMO); others e.g. '08','04','11','06','05'. Plan-level attribute, constant within a plan-year.
pbp_a_ben_covstringPart A benefit coverage indicator carried from PBP Section A. '1'=plan provides Part A benefits (196,773), '2'=does not / Part B-only (4,373), NULL (342). Context flag, not B-8 specific.
pbp_a_plan_typestringCMS plan-type code from Section A (string). '01'=HMO dominant (101,510), '04'=Local PPO (55,909), '02', '20'=PDP-like, etc. Describes the plan, not a B-8 benefit.
pbp_b8a_authstring
pbp_b8a_auth_posstring
pbp_b8a_auth_ynstring
pbp_b8a_coins_cov_cmcstring
pbp_b8a_coins_cov_dmcstring
pbp_b8a_coins_cov_labstring
pbp_b8a_coins_cov_posstring
pbp_b8a_coins_cov_tmcstring
pbp_b8a_coins_ehcstring
pbp_b8a_coins_pct_cmcdouble
pbp_b8a_coins_pct_cmc_maxdouble
pbp_b8a_coins_pct_dmcdouble
pbp_b8a_coins_pct_dmc_maxdouble
pbp_b8a_coins_pct_labdouble
pbp_b8a_coins_pct_lab_maxdouble
pbp_b8a_coins_pct_posdouble
pbp_b8a_coins_pct_tmcdouble
pbp_b8a_coins_pct_tmc_maxdouble
pbp_b8a_coins_pctmax_posdouble
pbp_b8a_coins_yesnostring
pbp_b8a_coins_yesno_posstring
pbp_b8a_coins_ynstring
pbp_b8a_copay_amt_posdouble
pbp_b8a_copay_amtmax_posdouble
pbp_b8a_copay_ehcstring
pbp_b8a_copay_max_cmc_amtdouble
pbp_b8a_copay_max_dmc_amtdouble
pbp_b8a_copay_max_tmc_amtdouble
pbp_b8a_copay_max_ynstring
pbp_b8a_copay_min_cmc_amtdouble
pbp_b8a_copay_min_dmc_amtdouble
pbp_b8a_copay_min_tmc_amtdouble
pbp_b8a_copay_yesnostring
pbp_b8a_copay_yesno_posstring
pbp_b8a_copay_ynstring
pbp_b8a_cost_sharestring
pbp_b8a_cost_share_coins_maxdouble
pbp_b8a_cost_share_coins_mindouble
pbp_b8a_cost_share_coins_ynstring
pbp_b8a_cost_share_copay_maxdouble
pbp_b8a_cost_share_copay_mindouble
pbp_b8a_cost_share_copay_ynstring
pbp_b8a_cost_share_yesnostring
pbp_b8a_cost_share_ynstring
pbp_b8a_ded_amtdouble
pbp_b8a_ded_amt_posdouble
pbp_b8a_ded_yesno_posstring
pbp_b8a_ded_ynstring
pbp_b8a_lab_copay_amtdouble
pbp_b8a_lab_copay_amt_maxdouble
pbp_b8a_maxenr_amtdouble
pbp_b8a_maxenr_amt_posdouble
pbp_b8a_maxenr_perstring
pbp_b8a_maxenr_per_dstring
pbp_b8a_maxenr_yesnostring
pbp_b8a_maxenr_ynstring
pbp_b8a_maxenr_yn_posstring
pbp_b8a_maxplan_yesno_posstring
pbp_b8a_maxpln_amt_posdouble
pbp_b8a_maxpln_cov_posstring
pbp_b8a_maxpln_per_posstring
pbp_b8a_refer_ynstring
pbp_b8a_sep_cost_ynstring
pbp_b8b_authstring
pbp_b8b_auth_posstring
pbp_b8b_auth_ynstring
pbp_b8b_coins_cov_mcstring
pbp_b8b_coins_cov_posstring
pbp_b8b_coins_cov_tmcstring
pbp_b8b_coins_ehcstring
pbp_b8b_coins_pct_cmcdouble
pbp_b8b_coins_pct_cmc_maxdouble
pbp_b8b_coins_pct_drsdouble
pbp_b8b_coins_pct_drs_covstring
pbp_b8b_coins_pct_drs_maxdouble
pbp_b8b_coins_pct_posdouble
pbp_b8b_coins_pct_tmcdouble
pbp_b8b_coins_pct_tmc_maxdouble
pbp_b8b_coins_pctmax_posdouble
pbp_b8b_coins_yesnostring
pbp_b8b_coins_yesno_posstring
pbp_b8b_coins_ynstring
pbp_b8b_copay_amt_drsdouble
pbp_b8b_copay_amt_drs_maxdouble
pbp_b8b_copay_amt_posdouble
pbp_b8b_copay_amt_tmcdouble
pbp_b8b_copay_amt_tmc_maxdouble
pbp_b8b_copay_amtmax_posdouble
pbp_b8b_copay_ehcstring
pbp_b8b_copay_max_ynstring
pbp_b8b_copay_mc_amtdouble
pbp_b8b_copay_mc_amt_maxdouble
pbp_b8b_copay_yesnostring
pbp_b8b_copay_yesno_posstring
pbp_b8b_copay_ynstring
pbp_b8b_cost_sharestring
pbp_b8b_cost_share_coins_maxdouble
pbp_b8b_cost_share_coins_mindouble
pbp_b8b_cost_share_coins_ynstring
pbp_b8b_cost_share_copay_maxdouble
pbp_b8b_cost_share_copay_mindouble
pbp_b8b_cost_share_copay_ynstring
pbp_b8b_ded_amtdouble
pbp_b8b_ded_amt_posdouble
pbp_b8b_ded_yesnostring
pbp_b8b_ded_yesno_posstring
pbp_b8b_ded_ynstring
pbp_b8b_maxenr_amtdouble
pbp_b8b_maxenr_amt_posdouble
pbp_b8b_maxenr_perstring
pbp_b8b_maxenr_per_dstring
pbp_b8b_maxenr_yesnostring
pbp_b8b_maxenr_ynstring
pbp_b8b_maxenr_yn_posstring
pbp_b8b_maxplan_yesno_posstring
pbp_b8b_maxpln_amt_posdouble
pbp_b8b_maxpln_cov_posstring
pbp_b8b_maxpln_per_posstring
pbp_b8b_refer_ynstring
pbp_b8b_sep_cost_ynstring
pbp_b_8a_ded_amtdouble
pbp_b_8a_ded_yesnostring
observed_perioddateVlada bitemporal field: the period the data is observed-as-of. Always Jan 1 of report_year (e.g. 2018-01-01). Equals effective_period_start here; redundant with report_year.
asserted_atdateVlada ingest/assertion date (when this record was loaded into the substrate): two batches observed, 2026-05-16 (100,054 rows) and 2026-05-20 (101,434 rows). Does NOT split the grain — each plan-year-quarter is asserted in exactly one batch. Use it as load lineage, not a benefit attribute.
effective_period_startdate
effective_period_enddate
cms_vintage_sequenceintWhich CMS source-file vintage the row came from (int 1-4). Provenance/lineage, correlates with asserted_at batch (batch 1 = vintage 1; batch 2 = vintages 2-4).
parse_revisionintParser version that produced the row (int, observed 1-2). Lineage only — despite matching an 'is_*'/version-like name search it is NOT a current-record flag.
parser_artifact_hashstringSHA-256 of the parser artifact that produced the row. Pure provenance.
source_urlstringCMS download URL of the originating PBP PUF zip (e.g. .../pbp-pufs/pbp-benefits-2018-q2.zip). Encodes the year+quarter of the source file; ~24+16 distinct files across the two batches. Provenance.
sha256_content_hashstringSHA-256 of the source file content. Provenance / dedup integrity, constant within a source file.
pbp_b8a_auth / pbp_b8a_auth_pos / pbp_b8b_auth / pbp_b8b_auth_posPACKED prior-authorization flag strings (e.g. '01000','00111') — each character position is a yes/no flag for whether prior auth is required for a specific service sub-type within the section. NOT a single scalar; must be decoded position-by-position against the CMS PBP B-8 layout. '_pos' variants are the point-of-service / OON counterpart.
pbp_b8a_auth_yn / pbp_b8b_auth_ynSimple yes/no roll-up: '1'=Yes (auth required for some service), '2'=No, NULL=not asked for that plan-type/year. (b8a_auth_yn: 121,715 Yes / 18,014 No / 61,759 NULL.)
pbp_b8a_refer_yn / pbp_b8b_refer_ynWhether a referral is required for the section's services. '1'=Yes, '2'=No (CMS 1/2 coding).
pbp_b8a_coins_yn / pbp_b8a_copay_yn / pbp_b8a_ded_yn (and pbp_b8b_* equivalents)Does the plan charge coinsurance / copay / deductible for this section. CMS coding '1'=Yes, '2'=No, NULL=not applicable. coins_yn and copay_yn are near-mirror-images (a plan usually picks copay OR coinsurance).
pbp_b8a_*_ehc / pbp_b8b_*_ehc (e.g. pbp_b8a_coins_ehc, pbp_b8b_copay_ehc)PACKED 'enrollee health-care' indicator strings: b8a = 2 chars (e.g. '11','01','10'), b8b = 3 chars (e.g. '111','110','011'). Each position is a 1/0 flag for whether the cost-share applies to a specific service sub-type (lab / diagnostic / radiology component). Decode by position, do not read as a number.
pbp_b8a_lab_copay_amt / _maxMember copay dollar amount (and its max) for LAB tests under B-8a. Real $: min 0, observed up to tens of dollars. ~96K populated. _max is the upper bound when the plan files a range.
pbp_b8a_copay_min_dmc_amt / pbp_b8a_copay_max_dmc_amtMin/max member copay $ for DIAGNOSTIC tests/procedures (dmc) under B-8a. ~99K populated; range $0-$999, median max ~$37. The headline B-8a diagnostic copay.
pbp_b8a_copay_min_cmc_amt / _max_cmc_amt, pbp_b8a_copay_min_tmc_amt / _max_tmc_amtMin/max copay $ for clinical (cmc, rare ~1K) and therapeutic-monitoring (tmc, ~7K) sub-services under B-8a. Sparsely populated — most plans don't itemize these.
pbp_b8a_coins_pct_dmc / _lab / _cmc / _tmc (and *_max, *_pct_pos)Coinsurance PERCENTAGES the member pays for the dmc/lab/cmc/tmc sub-services under B-8a (double, 0-50, commonly 20). '_pos' = point-of-service/OON percentage. NULL when the plan charges copay instead.
pbp_b8b_copay_amt_drs / _drs_max, pbp_b8b_coins_pct_drs / _drs_maxMember cost share for DRS = advanced Diagnostic Radiology Services (MRI/CT/PET) under B-8b. copay_amt_drs ~99K populated, $0-$450 (median ~$4 because many plans use coinsurance); coins_pct_drs is the percentage variant. THE advanced-imaging member-cost field.
pbp_b8b_copay_mc_amt / _max, pbp_b8b_coins_pct_cmc / _maxCost share for general outpatient diagnostic radiology / medical radiology (mc/cmc) under B-8b. copay_mc_amt is the most-populated B-8b amount (~108K).
pbp_b8b_copay_amt_tmc / _max, pbp_b8b_coins_pct_tmc / _maxCost share for THERAPEUTIC radiology (tmc) under B-8b. coins_pct_tmc median 20% (range 0-50%); ~55K rows populated. Therapeutic (treatment) vs diagnostic radiology distinction lives here.
pbp_b8a_ded_amt / pbp_b8b_ded_amt / pbp_b_8a_ded_amt (and *_yn, *_yesno, *_pos)Service-specific deductible dollar amount for the section and its yes/no presence flag. Mostly NULL (most plans have no service-specific B-8 deductible). NOTE pbp_b_8a_ded_amt / pbp_b_8a_ded_yesno (extra underscore) are legacy duplicate columns from an older CMS layout — nearly always NULL.
pbp_b8a_maxenr_amt / _per / _per_d / _yn (and pbp_b8b_* equivalents)Service-specific MAXIMUM enrollee out-of-pocket: amount, period code (_per), and free-text period DESCRIPTION (_per_d, e.g. 'The maximum enrollee out-of-pocket cost share is per day.' with inconsistent wording across plans), plus yes/no flag. Sparsely populated.
pbp_b8a_maxpln_amt_pos / _cov_pos / _per_pos / pbp_b8a_maxplan_yesno_pos (and b8b)Plan-level maximum-cost and coverage for the point-of-service / out-of-network side of the section. The two maxplan_yesno_pos columns appear in the profiler's reported key but are NOT needed for uniqueness — they are functionally dependent attributes, mostly NULL.
pbp_b8a_cost_share* / pbp_b8b_cost_share* (cost_share, _coins_min/_max/_yn, _copay_min/_max/_yn, _yesno, _yn)Generic combined cost-share min/max and yes/no fields (a later CMS layout's roll-up of the copay/coins detail). Largely NULL in this table — the itemized dmc/lab/drs/tmc fields above carry the real values.
pbp_b8a_sep_cost_yn / pbp_b8b_sep_cost_ynWhether a SEPARATE cost share applies (vs bundled into another benefit). CMS yes/no, mostly NULL.
effective_period_start / effective_period_endThe benefit year window the row's terms apply to: start = Jan 1 of report_year, end = Dec 31 of report_year. effective_period_start is the table's primary time column (2001-01-01 to 2026-01-01, annual).

Query it

describe_data_source(source_fqn="medicare_silver.pbp_section_b8_clin_diag_ther")     # the card, live
query_substrate(sql="SELECT * FROM medicare_silver.pbp_section_b8_clin_diag_ther WHERE contract_id = '<value>' AND plan_id = '<value>' AND segment_id = '<value>' AND report_year = '<value>' AND quarter = '<value>' LIMIT 100")
ItemValue
Typed tools that read itget_pbp_benefit
Identity keycontract_id
Joinhow_to_join(source_fqn="medicare_silver.pbp_section_b8_clin_diag_ther")
Raw doorAthena (read-only via query_substrate): medicare_silver.pbp_section_b8_clin_diag_ther
NoteGrain-governed; live in Glue / query_substrate. Source family pbp_benefits.

This page as markdown: /docs-md/data/medicare_silver_pbp_section_b8_clin_diag_ther.md · every page in one file: /llms-full.txt