Medicare Advantage, Part D, Medicaid

MA mpf benefit summary annual

medicare_silver.mpf_benefit_summary_annual·live·silver·annual·Medicare Advantage Plan Benefit Packages (PBP)
Rows
N/A
Columns
22
History
2020 (contract_year 2020; effective_period 2020-01-01 to 2020-12-31) to 2026 (contract_year 2026; effective_period 2026-01-01 to 2026-12-31)
Card
yesgrain, traps, filters
Typed tools
0

What it is

  1. 1A flattened, multi-year history of the cost-sharing rules that Medicare Advantage (Part C) plans publish on the CMS Medicare Plan Finder.
  2. 2Each row states, for one plan in one contract year, what an enrollee pays (copay / coinsurance / deductible / MOOP) for one benefit category or sub-service, plus whether prior authorization or a referral is required and whether the benefit is limited.
  3. 3It is the benefit-design / out-of-pocket-cost layer for Medicare Advantage, parsed from CMS's annual "MPF Benefit Summary" ZIP files (CY2020-CY2026).

Grain

KeyGrain
contract_idplan_idsegment_idcontract_yearcategory_nameservice_descnetwork_descriptioncost_sharelimit_flagauthorization_flagreferral_flag
  1. 1One row per (contract_id, plan_id, segment_id, contract_year) plan-year x (category_name, service_desc, network_description) benefit line x distinct cost_share/flag variant.
  2. 2IMPORTANT: this table has NO unique key.
  3. 3Even using every plan key AND every descriptive column (org_name, plan_type_desc, category_name, service_desc, cost_share, network_description, limit_flag, authorization_flag, referral_flag), the physical 2,775,723 rows collapse to only 2,240,145 distinct combinations -- 535,578 rows are exact byte-for-byte duplicates (up to 7 identical copies of the same plan-benefit line, e.g. a Kaiser H0524/043 2021 'Comprehensive dental / Not covered' row appears 7x).
  4. 4The duplication comes from a finer source grain (plan x county/service-area) that was flattened away and not carried into this table.
  5. 5Treat the grain as the deduped logical row above and ALWAYS query with SELECT DISTINCT or GROUP BY; do not COUNT(*) raw rows as benefit lines.

How to read it

  1. 1"What does each 2026 PPO plan charge for an in-network specialist visit?" -> SELECT DISTINCT org_name, contract_id, plan_id, segment_id, cost_share, authorization_flag, referral_flag FROM mpf_benefit_summary_annual WHERE contract_year=2026 AND category_name='Doctor visits' AND service_desc='Specialist' AND network_description='In-Network'.
  2. 2Use SELECT DISTINCT (not COUNT(*)) because of the duplicate rows, and note 2026 encodes the auth/referral flags as 'Yes'/'No'/'N/A' whereas 2020-2024 use '0'/'1'/'2' and 2025 uses '0.0'/'1.0'/'2.0'.
  3. 3Join to other mpf_/Stars tables on (contract_id, plan_id, segment_id, contract_year); the synthetic 'Original Medicare' contract H0001 is the FFS baseline for benchmarking.

Traps

  1. 1NO unique key exists. Physical rows (2,775,723) exceed distinct combinations of plan-key + ALL descriptive columns (2,240,145) by 535,578 -- up to 7 byte-identical duplicate rows per plan-benefit line. The source grain is finer (plan x county/service-area) and was flattened away. ALWAYS SELECT DISTINCT / GROUP BY; never COUNT(*) raw rows as a benefit or plan count.
  2. 2The auth/referral/limit flags are encoded DIFFERENTLY in every era: '0'/'1'/'2' (2020-2024), '0.0'/'1.0'/'2.0' (2025), and 'No'/'Yes'/'N/A' (2026, auth/referral only). Decode 0=No, 1=Yes, 2=N/A. Cross-year filters/aggregations on these flags are WRONG unless you normalize the encodings first.
  3. 3plan_type_desc AND category_name are free-text and vintage-drifted -- the same plan-type or benefit category appears under multiple spellings/casings across years ('Local Preferred Provider Organization' vs 'Local PPO'; 'Comprehensive dental' vs 'Comprehensive Dental'). Canonicalize (lower/trim/map) before grouping or you will split one category/plan-type into several.
  4. 4cost_share is FREE TEXT, not numeric, and 0% null: it mixes percentages, dollar copays, deductible/MOOP amounts, prose ('Not covered'), and even embedded HTML ('<br />'); the same logical value differs by year ('$0' vs '0' vs '0.0'). You must parse it to get numbers.
  5. 5Single snapshot, no versioning: asserted_at=2026-05-16, cms_vintage_sequence=1, parse_revision=1 for every row, and there is NO is_current column. The provenance columns (sha256/source_url/parser hashes) only vary by contract_year (one file each) and cannot be used to dedup the within-year duplicate rows or to pick a 'latest' version.
  6. 6contract H0001 / plan 001 / segment 000 labelled 'Original Medicare' is a SYNTHETIC fee-for-service baseline injected by CMS for comparison (present 2021-2026, ~36-37 rows/yr), not a real MA plan -- include it for benchmarking, exclude it (plan_type_desc <> 'Original Medicare') when you want only real MA plans.
  7. 7network_description NULL and service_desc NULL carry meaning, not just absence: NULL network = single-network (HMO) or plan-level line (deductible/MOOP); NULL service_desc (~61% of rows) = category-level benefit with no sub-service breakdown.

Columns (22)

ColumnTypeMeaning
org_namestringParent organization / carrier marketing name for the contract (e.g. 'Kaiser Permanente', 'UPMC for Life', 'Original Medicare'). Free text, NOT stable per contract across years: 241 of 1,014 contract_ids carry more than one org_name over time (rebrands/acquisitions/relabeling). Use as a label, not a join key.
contract_idstringCMS Medicare Advantage contract identifier. 1,014 distinct. Prefixes observed: 'H' (986 contracts, standard local MA/HMO/PPO incl. the synthetic Original-Medicare contract H0001) and 'R' (28 contracts, Regional PPO). No S/E/D prefixes present (this table is MA benefit data, not standalone PDP/employer). Part of the plan key; not unique on its own.
plan_idstringPlan benefit package (PBP) number within the contract, zero-padded 3 chars (e.g. '001', '043'). 564 distinct values but only meaningful in combination with contract_id (+segment+year). Not unique on its own.
segment_idstringService-area segment within a plan, zero-padded 3 chars. '000' for the overwhelming majority (2,414,868 of 2,775,723 rows); non-zero segments ('001'..'011') exist only for PPO/regional plans whose benefits vary by geographic segment. Part of the plan key; usually '000'.
plan_type_descstringPlan type label (HMO, Local PPO, HMOPOS, Regional PPO, Cost Plan, PFFS, MSA, Medicare-Medicaid Plan, 'Original Medicare', etc.). GOTCHA: free-text and vintage-drifted -- the SAME plan-key shows different labels across years (3,362 plan-keys have >1 value) because CMS changed wording: 'Local Preferred Provider Organization'->'Local PPO', 'HMO with POS Option'->'HMOPOS', 'Private Fee for Service'->'PFFS', 'Medical Savings Account'->'MSA'. Normalize before grouping by plan type.
contract_yearintThe plan/benefit calendar year (2020-2026). This is the canonical time dimension and aligns 1:1 with effective_period_start/end (year Y -> Y-01-01..Y-12-31) and observed_period (Y-01-01). One source ZIP file per contract_year (7 files, 7 sha256 hashes).
category_namestringBenefit category label, 32 distinct values (Vision, Comprehensive dental, Mental health services, Diagnostic procedures/lab services/imaging, Doctor visits, Health plan deductible, Maximum out-of-pocket..., etc.). GOTCHA: NOT normalized across vintages -- several values are case/wording variants of one category: 'Comprehensive dental' vs 'Comprehensive Dental'; 'Diagnostic and Preventive dental' vs 'Diagnostic and Preventive Dental'. Lower-case / canonicalize before grouping.
service_descstringSub-service within the category (70 distinct, e.g. 'Specialist', 'Primary', 'Lab services', 'Endodontics', 'Diagnostic radiology services (e.g., MRI)'). NULL for ~61% of rows (1,702,642) -- meaning the benefit is captured only at category level with no sub-service breakdown. A NULL here is structural, not missing-data.
limit_flagstringWhether the benefit has a quantity/dollar limit. GOTCHA: encoding varies by contract_year -- '1'/'0' (int strings, 2020-2024), '1.0'/'0.0' (decimal strings, 2025), and large NULL share (1,719,487 rows, mostly categories where a limit is inapplicable). 1=limited, 0=not limited. Normalize ('1'='1.0') for cross-year use. (Note: unlike auth/referral, 2026 limit_flag was not observed as Yes/No text in the sampled distribution.)
authorization_flagstringWhether prior authorization is required for the benefit. THREE-valued and encoded DIFFERENTLY each year: 2020-2024 use '0'/'1'/'2'; 2025 uses '0.0'/'1.0'/'2.0'; 2026 uses 'No'/'Yes'/'N/A'. Decode: 0=No, 1=Yes, 2=N/A (verified by cross-year counts). ~190K NULL. Any cross-year analysis MUST normalize these encodings.
referral_flagstringWhether a referral is required for the benefit. Same three-valued, year-dependent encoding as authorization_flag: '0'/'1'/'2' (2020-2024), '0.0'/'1.0'/'2.0' (2025), 'No'/'Yes'/'N/A' (2026); decode 0=No, 1=Yes, 2=N/A (confirmed: 2024 '2'=101,682 maps to 2026 'N/A'=129,962). ~190K NULL. Normalize before cross-year comparison.
network_descriptionstringNetwork tier the cost_share applies to: 'In-Network' (1,040,965), 'Out-of-Network' (623,164), or NULL (1,111,594). NULL is meaningful: it marks single-network plans (HMO) and plan-level lines (deductible/MOOP) where the in/out split does not apply. For PPO/POS plans each benefit appears as separate In-Network and Out-of-Network rows with different cost_share.
cost_sharestringThe enrollee's cost as FREE TEXT (13,859 distinct, 0 nulls). Mixed formats: percentages ('20%'), dollar copays ('$30 copay per visit'), deductible/MOOP dollar amounts ('$3,400 In-network', '$10,000 In and Out-of-network<br />$6,700 In-network' -- note embedded HTML), and prose ('Not covered', 'Yes, contact plan for further details'). GOTCHA: same value rendered differently by year ('$0' vs '0' vs '0.0' for a $0 deductible). NOT numeric -- must be parsed/regex'd to extract amounts.
observed_perioddateDate the benefit is observed/effective-from; always Jan 1 of contract_year (e.g. 2023-01-01). Redundant with contract_year and effective_period_start. A provenance/as-of date, not an independent dimension.
asserted_atdateIngest/assertion date of this silver build. Constant 2026-05-16 for ALL rows -- the entire table is a single ingest/snapshot. Not a versioning column; carries no SCD/is_current semantics.
effective_period_startdateFirst day the plan year is in effect; Jan 1 of contract_year. The profiler's chosen time column; aligns 1:1 with contract_year. Span 2020-01-01 .. 2026-01-01, annual cadence.
effective_period_enddateLast day of the plan year; Dec 31 of contract_year. Together with effective_period_start it just brackets the contract_year; no partial-year periods exist.
cms_vintage_sequenceintSource-vintage sequence number. Constant = 1 for every row. There is only one vintage per contract_year and one overall ingest; this column does NOT distinguish snapshots and cannot be used to pick a 'latest' version.
parse_revisionintParser revision number. Constant = 1 for every row. No re-parses recorded; not useful for dedup or version selection.
parser_artifact_hashstringSHA-256 of the parser artifact that produced the row. 7 distinct values, one per contract_year file. Provenance only.
source_urlstringCMS download URL of the source ZIP, e.g. 'https://www.cms.gov/files/zip/cy-2023-mpf-benefit-summary.zip'. Exactly 7 distinct URLs = one file per contract_year (CY2020-CY2026). Lineage column; functionally determined by contract_year.
sha256_content_hashstringSHA-256 of the source file content. 7 distinct values (one per contract_year ZIP). Provenance/integrity; identical across all rows from the same year, so it does not help distinguish the duplicate benefit rows within a year.

Query it

describe_data_source(source_fqn="medicare_silver.mpf_benefit_summary_annual")     # the card, live
query_substrate(sql="SELECT * FROM medicare_silver.mpf_benefit_summary_annual WHERE contract_id = '<value>' AND plan_id = '<value>' AND segment_id = '<value>' AND contract_year = '<value>' AND category_name = '<value>' AND service_desc = '<value>' AND network_description = '<value>' AND cost_share = '<value>' AND limit_flag = '<value>' AND authorization_flag = '<value>' AND referral_flag = '<value>' LIMIT 100")
ItemValue
Typed tools that read itnone; raw SQL
Identity keycontract_id,plan_id,segment_id
Joinhow_to_join(source_fqn="medicare_silver.mpf_benefit_summary_annual")
Raw doorAthena (read-only via query_substrate): medicare_silver.mpf_benefit_summary_annual
Company namesorg_name resolve to a permanent Vlada ID: resolve_entity(text=<name>); the company pages hold owners and holdings
NoteGrain-governed; live in Glue / query_substrate. Source family mpf_benefit_summary_report.

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