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
- 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).
- 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
| Key | Grain |
|---|---|
contract_idplan_idsegment_idobserved_periodquarter |
|
How to read it
- 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.
- 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).
- 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
- 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.
- 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.
- 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.
- 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.
- 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.
- 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)
| Column | Type | Meaning |
|---|---|---|
contract_id | string | CMS Medicare Advantage contract number (e.g. 'H0028'). 1,972 distinct. Part of the grain key. Joins to contract/enrollment tables. |
plan_id | string | Plan 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_id | string | Plan segment within the plan (service-area split), string (e.g. '0','1','2'). 27 distinct. Part of grain key. Most plans are segment '0'. |
version | double | CMS 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_year | double | Contract/benefit calendar year as a double (2001-2026). Equals YEAR(observed_period). This is the plan year the benefits apply to. |
quarter | double | CMS 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_id | string | Composite 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. |
orgtype | string | Organization 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_cov | string | Section-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_type | string | Section-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_auth | string | Free/numeric auth detail field. Almost entirely null in modern eras (61,700 nulls); superseded by pbp_b5_auth_yn. Legacy. |
pbp_b5_auth_pos | string | Place-of-service ('_pos') variant of the auth field. Effectively always null (only 29 non-null, all in 2001). Inert column. |
pbp_b5_auth_yn | string | Does 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_cov | string | Coinsurance coverage-scope descriptor. Almost entirely null. Legacy/rarely populated. |
pbp_b5_coins_cov_pos | string | Place-of-service variant of coins_cov. Effectively all null. Inert. |
pbp_b5_coins_pct | double | Coinsurance 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_max | double | Upper 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_min | double | Lower 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_pos | double | Place-of-service variant of coinsurance percent. Effectively all null (18 rows, 2001 only). Inert. |
pbp_b5_coins_yesno | string | Legacy yes/no coinsurance descriptor (string). Almost entirely null; superseded by pbp_b5_coins_yn. |
pbp_b5_coins_yesno_pos | string | Place-of-service variant of coins_yesno. All null. Inert. |
pbp_b5_coins_yn | string | Does 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_pos | double | Place-of-service copay-amount-per-day variant (double). Effectively all null. Inert. |
pbp_b5_copay_mcia_amt | double | Copay 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_max | double | Upper 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_min | double | Lower 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_mciaamt | double | Oldest-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_yesno | string | Legacy yes/no copay descriptor (string). Almost entirely null; superseded by pbp_b5_copay_yn. |
pbp_b5_copay_yesno_pos | string | Place-of-service variant of copay_yesno. All null. Inert. |
pbp_b5_copay_yn | string | Does 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_amt | double | Deductible 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_pos | double | Place-of-service variant of the deductible amount. All null. Inert. |
pbp_b5_ded_yesno | string | Legacy yes/no deductible descriptor. Almost entirely null. Legacy. |
pbp_b5_ded_yesno_pos | string | Place-of-service variant of ded_yesno. All null. Inert. |
pbp_b5_ded_yn | string | Does 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_amt | double | Per-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_pos | double | Place-of-service variant of maxenr_amt. All null. Inert. |
pbp_b5_maxenr_per | string | Per-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_d | string | Per-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_yesno | string | Legacy yes/no per-enrollee-max descriptor. Almost all null. Legacy. |
pbp_b5_maxenr_yn | string | Does 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_pos | string | Place-of-service variant of maxenr_yn. All null. Inert. |
pbp_b5_maxplan_yesno_pos | string | Plan-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_pos | double | Plan-level maximum dollar amount, place-of-service variant. All null. Inert. |
pbp_b5_maxpln_cov_pos | string | Plan-level maximum coverage scope, place-of-service variant. All null. Inert. |
pbp_b5_maxpln_per_pos | string | Plan-level maximum periodicity, place-of-service variant. 100% null. Inert. |
pbp_b5_refer_yn | string | Is a referral required for partial hospitalization? '2'=No (144,584), '1'=Yes (44,369), null=12,535. |
pbp_b5a_coins_pct | double | Coinsurance 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_amt | double | Copay dollar amount for sub-benefit B5A. NEW CY2026 only (4,444 rows in 2026, null elsewhere). |
pbp_b5b_auth_yn | string | Prior-auth flag for sub-benefit B5B. NEW CY2026 only (7,002 rows). Null for all years before 2026. |
pbp_b5b_coins_pct | double | Coinsurance percent for sub-benefit B5B. CY2026 only (903 rows). |
pbp_b5b_coins_pct_max | double | Upper bound of B5B coinsurance percent. CY2026 only. |
pbp_b5b_coins_pct_min | double | Lower bound/single B5B coinsurance percent. CY2026 only. |
pbp_b5b_coins_yn | string | Does B5B sub-benefit charge coinsurance? CY2026 only. Gate for b5b_coins_pct*. |
pbp_b5b_copay_amt | double | Copay dollar amount for B5B. CY2026 only (4,495 rows). |
pbp_b5b_copay_amt_max | double | Upper bound of B5B copay dollar amount (range). CY2026 only. |
pbp_b5b_copay_amt_min | double | Lower bound/single B5B copay dollar amount. CY2026 only. |
pbp_b5b_copay_yn | string | Does B5B charge a copay? CY2026 only. Gate for b5b_copay_amt*. |
pbp_b5b_ded_amt | double | Deductible dollar amount for B5B. CY2026 only. |
pbp_b5b_ded_yn | string | Does B5B have its own deductible? CY2026 only. |
pbp_b5b_maxenr_amt | double | Per-enrollee maximum dollar amount for B5B. CY2026 only. |
pbp_b5b_maxenr_per | string | Per-enrollee-max periodicity number for B5B. CY2026 only (only 7 rows populated). |
pbp_b5b_maxenr_per_d | string | Per-enrollee-max period unit for B5B. 100% null even in 2026. Inert. |
pbp_b5b_maxenr_yn | string | Does B5B apply a per-enrollee maximum? CY2026 only. |
pbp_b5b_refer_yn | string | Is a referral required for B5B? CY2026 only. |
observed_period | date | Vlada-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_at | date | Vlada 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_start | date | DATE the benefit takes effect = Jan 1 of report_year. Identical to observed_period (verified 0 diffs). Redundant with observed_period. |
effective_period_end | date | DATE the benefit period ends = Dec 31 of report_year (e.g. 2018-12-31). Annual coverage window close. |
cms_vintage_sequence | int | Vlada integer ordering CMS source vintages (e.g. 2). Sequence of the CMS PUF vintage this row came from; provenance/ordering aid. |
parse_revision | int | Vlada integer parser revision (e.g. 2). Which version of the ingestion parser produced the row. Provenance, not benefit data. |
parser_artifact_hash | string | SHA-256 of the parser artifact/code that produced the row. Provenance/reproducibility. |
source_url | string | CMS 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_hash | string | SHA-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")
| Item | Value |
|---|---|
| Typed tools that read it | get_pbp_benefit |
| Identity key | contract_id |
| Join | how_to_join(source_fqn="medicare_silver.pbp_section_b5_partial_hosp") |
| Raw door | Athena (read-only via query_substrate): medicare_silver.pbp_section_b5_partial_hosp |
| Note | Grain-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