Medicare Advantage, Part D, Medicaid

MA pbp section b5 partial hosp

medicare_silver.pbp_section_b5_partial_hosp·partial·silver·annual·Medicare Advantage Plan Benefit Packages (PBP)
Rows
N/A
Columns
74
History
2001-01-01 to 2026-01-01
Card
yesgrain, traps, filters
Typed tools
1

What it is

  1. 1CMS Medicare Advantage Plan Benefit Package (PBP) Section B5 - the Partial Hospitalization (psychiatric day-program) cost-sharing design each MA plan files with CMS each year: prior-auth/referral requirements and the member cost-share (copay dollars, coinsurance percent, deductible, per-enrollee maximums).
  2. 2It is a benefit-DESIGN catalog (what the plan says it will charge), one of 31 sibling pbp_section_* benefit tables, not claims or paid amounts.

Grain

KeyGrain
contract_idplan_idsegment_idobserved_periodquarter
  1. 1One row per Medicare Advantage plan-segment per plan-year per CMS quarterly PUF release.
  2. 2Minimal verified key = contract_id + plan_id + segment_id + observed_period + quarter (= 201,488 rows, exactly the table count, unique). bid_id and effective_period_start are redundant (bid_id is always contract_plan_segment; effective_period_start always equals observed_period), and the profiler's extra key columns pbp_a_plan_type / pbp_b5_maxplan_yesno_pos are not needed.
  3. 3Dropping quarter collapses to 114,175 distinct plan-years because 2018-2024 plan-years are republished in 2-4 quarterly PUFs.

How to read it

  1. 1Benchmark partial-hospitalization member cost-share across MA plans for the latest year, de-duplicating the quarterly snapshots and handling the era-shifted copay column.
  2. 2Example: SELECT contract_id, plan_id, segment_id, pbp_b5_copay_yn, COALESCE(pbp_b5_copay_mcia_amt, pbp_b5_copay_mcia_amt_min, pbp_b5_copay_mciaamt) AS copay_usd, pbp_b5_coins_yn, COALESCE(pbp_b5_coins_pct, pbp_b5_coins_pct_min) AS coins_pct, pbp_b5_auth_yn FROM medicare_silver.pbp_section_b5_partial_hosp WHERE report_year = 2026 AND quarter = (SELECT MAX(quarter) FROM medicare_silver.pbp_section_b5_partial_hosp WHERE report_year = 2026).
  3. 3This answers 'for each 2026 MA plan, does partial hospitalization need prior auth and what copay/coinsurance does a member owe?' Join to pbp_section_a (or other pbp_section_* tables) on contract_id+plan_id+segment_id+report_year+quarter to assemble the full benefit package.

Traps

  1. 1QUARTERLY-SNAPSHOT DUPLICATION (biggest trap): a plan-year is NOT one row. For 2018-2024, CMS republished the same plan-year in 2-4 quarterly PUFs, so each plan appears 2-4 near-identical times distinguished only by `quarter`. 2001-2017, 2021, 2025, 2026 are Q1-only (CMS dropped quarterly cadence CY2025+). There is NO is_current/latest flag. To get one row per plan-year you MUST pick a single quarter, e.g. the max(quarter) per (contract_id,plan_id,segment_id,report_year). Counting rows = counting plan-year-quarters, ~1.76x the plan-year count.
  2. 2ERA-DEPENDENT COST COLUMNS - the active copay column moves across years: pbp_b5_copay_mciaamt (2001 only) -> pbp_b5_copay_mcia_amt (2002-2015) -> pbp_b5_copay_mcia_amt_min/_max (2016+). Coinsurance similarly splits: pbp_b5_coins_pct (plain, some eras) vs pbp_b5_coins_pct_min/_max (2016+), and they are mutually exclusive. Always COALESCE across the family (e.g. COALESCE(copay_mcia_amt, copay_mcia_amt_min, copay_mciaamt)) or you silently get all-NULL for half the history.
  3. 3B5A/B5B SUB-BENEFIT COLUMNS ARE 2026-ONLY: all 18 pbp_b5a_* / pbp_b5b_* columns are populated solely in report_year 2026 (CMS split partial hospitalization into 5A/5B sub-services that year) and are 100% NULL for 2001-2025. Do not treat them as historical fields.
  4. 4YN GATES DRIVE AMOUNT PRESENCE - the cost columns are null unless the matching _yn flag says Yes: copay_yn='1' <-> copay amount present (verified 100%/0%); coins_yn='1' or '3' <-> coinsurance pct present, '2'=No=no pct. coins_yn has a third state '3' (range variant). A NULL amount usually means 'no charge / not applicable', not missing data - read it together with its _yn.
  5. 5MANY DECLARED COLUMNS ARE INERT - every `_pos` place-of-service variant (auth_pos, coins_pct_pos, maxpln_*_pos, maxplan_yesno_pos, etc.) plus maxenr_per_d are ~100% NULL (maxplan_yesno_pos has only 29 non-null rows). maxplan_yesno_pos appears in the profiler's candidate key but is effectively empty - do NOT include it in the grain. plan_id (656) and segment_id (27) are only unique WITHIN a contract, never globally.
  6. 6DESIGN DATA, NOT SPEND: these are plan-filed cost-share parameters (what a member would owe), not paid claims, allowed amounts, or utilization. Use for benefit-design benchmarking across MA plans/years; do not read as Vlada-priced or as actual dollars paid. Provenance lives in source_url / sha256_content_hash / asserted_at (bitemporal load time).

Columns (74)

ColumnTypeMeaning
contract_idstringCMS Medicare Advantage contract number (e.g. 'H0028'). 1,972 distinct. Part of the grain key. Joins to contract/enrollment tables.
plan_idstringPlan number within the contract, zero-padded 3-char string (e.g. '001','008'). 656 distinct values but only unique WITHIN a contract. Part of grain key.
segment_idstringPlan segment within the plan (service-area split), string (e.g. '0','1','2'). 27 distinct. Part of grain key. Most plans are segment '0'.
versiondoubleCMS PBP bid version/iteration number for that plan-year (double, e.g. 2.0,3.0,4.0,5.0). The plan's internal submission revision; does NOT make rows duplicate (each plan-year-quarter has one version).
report_yeardoubleContract/benefit calendar year as a double (2001-2026). Equals YEAR(observed_period). This is the plan year the benefits apply to.
quarterdoubleCMS PUF release quarter (1-4) the row was sourced from. CRITICAL: part of the grain. A single plan-year is re-published in multiple quarterly PUFs for 2018-2024, so the SAME plan appears 2-4 times (once per quarter). 2001-2017, 2021, 2025, 2026 are Q1-only (CMS dropped quarterly cadence CY2025+).
bid_idstringComposite key string, ALWAYS exactly contract_id||'_'||plan_id||'_'||segment_id (0 mismatches in 201,488 rows). Fully redundant with the three id columns; convenient join handle, NOT an independent dimension.
orgtypestringOrganization type code (string '01'-'14'). '01' dominates (177,737 = local CCP/HMO-PPO). '08','04','11','06','05' etc are other org types (PFFS, regional PPO, cost, etc).
pbp_a_ben_covstringSection-A benefit-coverage indicator carried into this section ('1' = ~196k rows, '2' = 4,373, null = 342). NOT a clean covered/not-covered flag — both '1' and '2' rows carry populated B5 cost-share detail. Inherited context field.
pbp_a_plan_typestringSection-A plan-type code (string). '01'=HMO (101k), '04'=local PPO (56k), '02'=HMOPOS (20k), '20','09','31','18','48' etc. Describes the MA plan product type.
pbp_b5_authstringFree/numeric auth detail field. Almost entirely null in modern eras (61,700 nulls); superseded by pbp_b5_auth_yn. Legacy.
pbp_b5_auth_posstringPlace-of-service ('_pos') variant of the auth field. Effectively always null (only 29 non-null, all in 2001). Inert column.
pbp_b5_auth_ynstringDoes partial-hospitalization require prior authorization? Coded '1'=Yes (122,635), '2'=No (17,153), null=61,700 (older eras / not-collected). The primary auth flag.
pbp_b5_coins_covstringCoinsurance coverage-scope descriptor. Almost entirely null. Legacy/rarely populated.
pbp_b5_coins_cov_posstringPlace-of-service variant of coins_cov. Effectively all null. Inert.
pbp_b5_coins_pctdoubleCoinsurance percent (plain, single value). Populated 12,926 rows and ONLY in eras that use this column (mutually exclusive with coins_pct_min/max — plain_only=12,926). Era-dependent: this is the active coinsurance column in some years, the min/max pair in others.
pbp_b5_coins_pct_maxdoubleUpper bound of coinsurance percent when the plan reports a range. Real values 0-45%. Populated in the min/max-era rows. Equals min when the rate is a single value.
pbp_b5_coins_pct_mindoubleLower bound (or single value) of coinsurance percent. Median 20%, max 45%. 46,175 populated. The active coinsurance column for 2016+ era rows.
pbp_b5_coins_pct_posdoublePlace-of-service variant of coinsurance percent. Effectively all null (18 rows, 2001 only). Inert.
pbp_b5_coins_yesnostringLegacy yes/no coinsurance descriptor (string). Almost entirely null; superseded by pbp_b5_coins_yn.
pbp_b5_coins_yesno_posstringPlace-of-service variant of coins_yesno. All null. Inert.
pbp_b5_coins_ynstringDoes the plan charge coinsurance for partial hospitalization? '2'=No (132,248, no pct present), '1'=Yes (57,878, pct present), '3'=Yes-range variant (1,182, all have pct), null=10,180. GATE for whether the coins_pct* columns are populated.
pbp_b5_copay_amtd_posdoublePlace-of-service copay-amount-per-day variant (double). Effectively all null. Inert.
pbp_b5_copay_mcia_amtdoubleCopay dollar amount (Medicare Covered If Applicable). THE active copay column for plan years 2002-2015 (0 rows outside that era). Real dollars, median ~$36, max $800. Era-specific — null in 2001 and 2016+.
pbp_b5_copay_mcia_amt_maxdoubleUpper bound of copay dollar amount when a range is reported. Active 2016+ era. Real dollars, max $750. Equals min for single values.
pbp_b5_copay_mcia_amt_mindoubleLower bound (or single value) copay dollar amount. THE active copay column for 2016+ plan years. Median $55, max $750. Null before 2016.
pbp_b5_copay_mciaamtdoubleOldest-form copay dollar column (note: no underscore before 'amt'). Populated ONLY in report_year 2001 (453 rows). Replaced by mcia_amt then mcia_amt_min/max. Era-specific copay value.
pbp_b5_copay_yesnostringLegacy yes/no copay descriptor (string). Almost entirely null; superseded by pbp_b5_copay_yn.
pbp_b5_copay_yesno_posstringPlace-of-service variant of copay_yesno. All null. Inert.
pbp_b5_copay_ynstringDoes the plan charge a copay for partial hospitalization? '1'=Yes (112,671, 100% have a copay amount), '2'=No (78,635, 0% have amount), '3'=rare (2), null=10,180. GATE for the copay amount columns. Verified: yn drives amount presence exactly.
pbp_b5_ded_amtdoubleDeductible dollar amount specific to this benefit. Rarely used: only 100 rows populated, 0-$952. Partial-hosp almost never has its own deductible.
pbp_b5_ded_amt_posdoublePlace-of-service variant of the deductible amount. All null. Inert.
pbp_b5_ded_yesnostringLegacy yes/no deductible descriptor. Almost entirely null. Legacy.
pbp_b5_ded_yesno_posstringPlace-of-service variant of ded_yesno. All null. Inert.
pbp_b5_ded_ynstringDoes this benefit have its own deductible? Overwhelmingly '2'=No (191,184); '1'=Yes only 100; null 10,204. Gate for ded_amt.
pbp_b5_maxenr_amtdoublePer-enrollee maximum out-of-pocket dollar amount for this benefit. Rarely populated (maxenr_yn is almost always No). Dollar cap per member.
pbp_b5_maxenr_amt_posdoublePlace-of-service variant of maxenr_amt. All null. Inert.
pbp_b5_maxenr_perstringPer-enrollee-maximum periodicity number (string). Almost all null (201,157); '3' (284) and '6' (47) when present. Composes with per_d unit. Rarely used.
pbp_b5_maxenr_per_dstringPer-enrollee-maximum period denominator/unit (D=day, M=month, etc per CMS dict). 100% NULL in this table — declared but never populated for B5.
pbp_b5_maxenr_yesnostringLegacy yes/no per-enrollee-max descriptor. Almost all null. Legacy.
pbp_b5_maxenr_ynstringDoes the plan apply a per-enrollee maximum to this benefit? Overwhelmingly '2'=No (190,956); '1'=Yes only 328; null 10,204. Gate for the maxenr_* fields.
pbp_b5_maxenr_yn_posstringPlace-of-service variant of maxenr_yn. All null. Inert.
pbp_b5_maxplan_yesno_posstringPlan-level-maximum yes/no, place-of-service variant. 99.99% NULL (only 29 non-null, value '2'). Appears in the profiler's candidate key but is inert; the true minimal grain does NOT need it.
pbp_b5_maxpln_amt_posdoublePlan-level maximum dollar amount, place-of-service variant. All null. Inert.
pbp_b5_maxpln_cov_posstringPlan-level maximum coverage scope, place-of-service variant. All null. Inert.
pbp_b5_maxpln_per_posstringPlan-level maximum periodicity, place-of-service variant. 100% null. Inert.
pbp_b5_refer_ynstringIs a referral required for partial hospitalization? '2'=No (144,584), '1'=Yes (44,369), null=12,535.
pbp_b5a_coins_pctdoubleCoinsurance percent for sub-benefit B5A. NEW CY2026 only (populated solely in report_year 2026, ~994 rows). Part of the 2026 split of partial-hosp into 5A/5B sub-services. Null for all prior years.
pbp_b5a_copay_amtdoubleCopay dollar amount for sub-benefit B5A. NEW CY2026 only (4,444 rows in 2026, null elsewhere).
pbp_b5b_auth_ynstringPrior-auth flag for sub-benefit B5B. NEW CY2026 only (7,002 rows). Null for all years before 2026.
pbp_b5b_coins_pctdoubleCoinsurance percent for sub-benefit B5B. CY2026 only (903 rows).
pbp_b5b_coins_pct_maxdoubleUpper bound of B5B coinsurance percent. CY2026 only.
pbp_b5b_coins_pct_mindoubleLower bound/single B5B coinsurance percent. CY2026 only.
pbp_b5b_coins_ynstringDoes B5B sub-benefit charge coinsurance? CY2026 only. Gate for b5b_coins_pct*.
pbp_b5b_copay_amtdoubleCopay dollar amount for B5B. CY2026 only (4,495 rows).
pbp_b5b_copay_amt_maxdoubleUpper bound of B5B copay dollar amount (range). CY2026 only.
pbp_b5b_copay_amt_mindoubleLower bound/single B5B copay dollar amount. CY2026 only.
pbp_b5b_copay_ynstringDoes B5B charge a copay? CY2026 only. Gate for b5b_copay_amt*.
pbp_b5b_ded_amtdoubleDeductible dollar amount for B5B. CY2026 only.
pbp_b5b_ded_ynstringDoes B5B have its own deductible? CY2026 only.
pbp_b5b_maxenr_amtdoublePer-enrollee maximum dollar amount for B5B. CY2026 only.
pbp_b5b_maxenr_perstringPer-enrollee-max periodicity number for B5B. CY2026 only (only 7 rows populated).
pbp_b5b_maxenr_per_dstringPer-enrollee-max period unit for B5B. 100% null even in 2026. Inert.
pbp_b5b_maxenr_ynstringDoes B5B apply a per-enrollee maximum? CY2026 only.
pbp_b5b_refer_ynstringIs a referral required for B5B? CY2026 only.
observed_perioddateVlada-added DATE = first day of the plan year (e.g. 2018-01-01). Equals effective_period_start (0 mismatches) and YEAR equals report_year. The benefit-year anchor; part of grain. Annual cadence.
asserted_atdateVlada provenance DATE: when this row was loaded/asserted into the silver layer (e.g. 2026-05-20). Bitemporal 'system time' column; same for a load batch. Not a benefit attribute.
effective_period_startdateDATE the benefit takes effect = Jan 1 of report_year. Identical to observed_period (verified 0 diffs). Redundant with observed_period.
effective_period_enddateDATE the benefit period ends = Dec 31 of report_year (e.g. 2018-12-31). Annual coverage window close.
cms_vintage_sequenceintVlada integer ordering CMS source vintages (e.g. 2). Sequence of the CMS PUF vintage this row came from; provenance/ordering aid.
parse_revisionintVlada integer parser revision (e.g. 2). Which version of the ingestion parser produced the row. Provenance, not benefit data.
parser_artifact_hashstringSHA-256 of the parser artifact/code that produced the row. Provenance/reproducibility.
source_urlstringCMS download URL of the source PUF zip (e.g. .../pbp-benefits-2018-q2.zip). Encodes the year+quarter of the source release; ground-truth provenance.
sha256_content_hashstringSHA-256 of the source file content. Integrity/dedup of the underlying CMS file.

Query it

describe_data_source(source_fqn="medicare_silver.pbp_section_b5_partial_hosp")     # the card, live
query_substrate(sql="SELECT * FROM medicare_silver.pbp_section_b5_partial_hosp WHERE contract_id = '<value>' AND plan_id = '<value>' AND segment_id = '<value>' AND observed_period = '<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_b5_partial_hosp")
Raw doorAthena (read-only via query_substrate): medicare_silver.pbp_section_b5_partial_hosp
NoteGrain-governed; live in Glue / query_substrate. Source family pbp_benefits.

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