Medicare Advantage, Part D, Medicaid
MA Star Ratings — contract metadata
Rows
N/A
Columns
25
History
RY2007 (effective_period_start 2006-11-09) to RY2026 (effective_period_start 2025-10-10)
Card
yesgrain, traps, filters
Typed tools
1
What it is
- 1The CMS Medicare Advantage / Part D Star Ratings CONTRACT MASTER (dimension/header) table: one descriptive record per Medicare health-plan or drug-plan contract per annual Star Ratings vintage.
- 2It identifies the contract (org name, marketing name, parent organization, org type, SNP flag, disaster-affected enrollment %) for each rating year 2007-2026.
- 3It is the spine you join Star measure/summary scores onto and the bridge from a CMS contract_id (e.g.
- 4H0028, S5601) to its parent payer (UnitedHealth, Humana, Centene, etc.) -- useful for attributing MA/Part D contracts to carriers when analyzing healthcare cost data.
- 5It contains NO star score columns itself; it is the contract identity layer, not the ratings values.
Grain
| Key | Grain |
|---|---|
contract_idrating_year |
|
How to read it
- 1Map a CMS contract to its parent payer for a given Star year, or list a carrier's MA/PDP footprint.
- 2Example: SELECT rating_year, contract_id, contract_name, marketing_name, org_type, snp_flag FROM medicare_silver.stars_contracts WHERE parent_org LIKE '%Humana%' AND rating_year = 2026 ORDER BY contract_id; -- answers 'which Medicare contracts did Humana operate in the 2026 Star vintage, and which are SNP / what org type'.
- 3To attribute scores, join a Star measure/summary table ON (contract_id, rating_year).
- 4Always pin rating_year (the grain), never rely on effective_period_end (always NULL)."
Traps
- 1GRAIN TRAP: contract_id is NOT unique (1,905 distinct across 14,138 rows -- a contract recurs every year it operated; H5859 appears in all 20 years). The real key is (contract_id, rating_year). The profiler's (contract_id, contract_name, bronze_publication_id) is a redundant superset since bronze_publication_id == rating_year 1:1 and contract_name is sometimes NULL.
- 2NULLS CARRY MEANING (vintage coverage): descriptive columns are NULL not because a contract lacks the attribute but because that year's CMS source file didn't include the column. org_type/marketing_name/parent_org are NULL for RY2007/2008/2011; contract_name NULL for RY2008-2010 & 2012; snp_flag only from RY2013+; disaster_2023_pct only in RY2025-2026; disaster_2024_pct only in RY2026. Don't infer 'unknown contract type' from a NULL in early years.
- 3is_current is 100% TRUE and cms_vintage_sequence/parse_revision are constant (1 and 0), restatement_of is 100% NULL -- this is a clean single-version-per-year load with NO superseded rows yet. The SCD/restatement machinery (is_current, restatement_of, calculation_epoch '_v1', cms_vintage_sequence) is scaffolding that is inert today; code defensively for when restatements arrive but don't expect dedup to be needed now.
- 4effective_period_end is 100% NULL -- you CANNOT do as-of/point-in-time filtering with the effective_period_start/end pair. Use rating_year (or effective_period_start, which is a single release date per year) to pick a vintage. Also note RY2024's release date is an outlier (2024-07-02 mid-year vs the usual October-of-prior-year cadence).
- 5payment_year == rating_year and performance_year == rating_year - 2 in EVERY row -- these are deterministic derivations, not independent facts. asserted_at is the May-2026 backfill load time, NOT data validity; never use it for time-series. This table has NO star score/measure columns -- it is the contract dimension only; join Star measure/summary tables on (contract_id, rating_year) to get the actual ratings.
- 6parent_org is free-text and not normalized: Anthem appears as both 'Anthem Inc.' and 'Elevance Health, Inc.' across years, 'Molina Healthcare, Inc.,' has a trailing comma, 'CIGNA' is all-caps. Normalize/fuzzy-match before grouping payers. Also 6 empty-string (not NULL) values exist in org_type and snp_flag, confined to RY2013.
Columns (25)
| Column | Type | Meaning |
|---|---|---|
contract_id | string | CMS Medicare contract identifier (the H/S/R/E number). Part of the grain. Prefix encodes contract type: H=MA/MA-PD or cost (12,685 rows, 1,699 distinct), S=standalone PDP (1,042 rows, 149 distinct), R=regional PPO (352 rows, 37 distinct), E=employer/EGWP direct-contract (48 rows, 10 distinct), plus a handful of stray single rows. NOT unique on its own -- unique only within a rating_year. |
org_type | string | CMS contract organization type. Top values: 'Local CCP' (9,870 -- local coordinated-care MA HMO/PPO, the bulk), 'PDP' (798 standalone Part D), 'Demo' (606), 'Regional CCP' (310), 'PFFS' (236), '1876 Cost' (205), 'National PACE' (134), 'MSA' (47), 'Employer/Union Only Direct Contract PDP' (44), '1833 Cost/HCPP' (25), 'Chronic Care' (8), plus a few more. NULL for some early vintages (2007,2008,2011) where the source file lacked it; 6 EMPTY-STRING rows exist only in RY2013 (parse artifact). |
contract_name | string | Legal/contract name of the organization (e.g. 'CHA HMO, INC.', 'SUPERIOR HEALTHPLAN, INC.'). Inconsistently populated by vintage: present for RY2007, RY2011, and RY2013+, but NULL for RY2008-2010 and RY2012 (those source files did not carry it). |
marketing_name | string | Consumer-facing brand name the plan markets under (e.g. 'Humana', 'Wellcare', 'Wellcare By Allwell'). Often differs from contract_name. NULL for RY2007 and RY2008 (not in early source files); populated RY2009+. |
parent_org | string | Parent organization / ultimate payer the contract rolls up to (e.g. 'UnitedHealth Group, Inc.' 1,326 rows, 'Humana Inc.' 823, 'Centene Corporation' 742, 'Aetna Inc.', 'CVS Health Corporation', 'Anthem Inc.'/'Elevance Health, Inc.', 'CIGNA', 'Kaiser Foundation Health Plan, Inc.'). This is THE column for attributing a contract to a carrier. NULL for RY2007,2008,2011. Note free-text inconsistency: Anthem appears as both 'Anthem Inc.' and 'Elevance Health, Inc.' across years; 'Molina Healthcare, Inc.,' has a trailing comma. |
snp_flag | string | Whether the contract includes any Special Needs Plan (SNP): 'Yes' (4,492) or 'No' (5,765). Only populated from RY2013 onward (NULL for RY2007-2012); 6 empty-string rows in RY2013. |
disaster_2023_pct | double | Percent of the contract's enrollment affected by a 2023 FEMA-declared disaster (0-100, used by CMS for the Star Ratings 'extreme and uncontrollable circumstances' adjustment). Range observed 0.0-97.0, mean ~1.16, only 28 distinct values. ONLY populated in the RY2025 and RY2026 vintages (NULL everywhere else) -- a year-specific adjustment column carried in recent data tables. |
disaster_2024_pct | double | Percent of the contract's enrollment affected by a 2024 FEMA-declared disaster (0-100; CMS disaster adjustment). Range 0.0-100.0, mean ~8.08. ONLY populated in the RY2026 vintage (NULL all other years). |
sanction_deduction | string | |
effective_period_start | date | CMS release/effective date of that year's Star Ratings data-table vintage -- exactly ONE distinct date per rating_year (RY2026=2025-10-10, RY2025=2024-10-11, RY2023=2022-10-06...). This is the table's primary temporal anchor. Note RY2024 is anomalous at 2024-07-02 (mid-year, vs the usual Oct of the prior calendar year). Earliest 2006-11-09 (RY2007), latest 2025-10-10 (RY2026). |
effective_period_end | date | Intended SCD close date for the vintage, but 100% NULL across all 14,138 rows -- never populated, even for old vintages. Do NOT use it for point-in-time/as-of filtering; treat every row as open-ended and disambiguate by rating_year instead. |
calculation_epoch | string | Logical vintage label, format 'ry{YYYY}_v1' (e.g. 'ry2026_v1'). Maps 1:1 to rating_year. The '_v1' suffix and the all-v1 reality signal a restatement-versioning scheme that currently has only first versions loaded. |
restatement_of | string | Provenance pointer to a prior vintage this row restates. Currently 100% NULL (no restatements have been ingested yet) -- lineage scaffolding for future CMS data-table reissues. |
parse_revision | int | Parser revision number for the row. Constant 0 across all rows (single parser generation in this load). |
parser_artifact_hash | string | Short hash (e.g. '86dfb448d9b9beb9') identifying the parser code/artifact that produced the row -- provenance for reproducibility. |
source_url | string | Original CMS download URL the vintage was parsed from -- exactly one distinct URL per rating_year (20 distinct). URL pattern evolved: early years '..._plan_ratings.zip', recent years '...-star-ratings-data-tables.zip' (e.g. RY2026 = https://www.cms.gov/files/zip/2026-star-ratings-data-tables.zip). |
sha256_content_hash | string | SHA-256 of the source bronze file content -- one value shared by all rows from the same vintage (content-addressed provenance/dedup of the raw download). |
bronze_publication_id | string | UUID of the bronze ingestion/publication event. Maps 1:1 to rating_year (20 distinct). Looks key-like but is NOT a row key -- it groups ~600-875 rows (all contracts in that vintage). Equivalent to rating_year for partitioning. |
asserted_at | timestamp | Pipeline ingest/load timestamp (when this row was written to silver), NOT data validity time. All rows loaded in a tight backfill window 2026-05-18 to 2026-05-28 (8 load days). Do not use for temporal analysis -- use effective_period_start / rating_year. |
rating_year | int | The CMS Star Ratings rating year -- the headline temporal dimension and part of the grain. Ranges 2007-2026 (20 values). This is the year the ratings are PUBLISHED/labeled (e.g. '2026 Star Ratings'), released in autumn of the prior calendar year. |
performance_year | int | The measurement/performance year the ratings reflect. Deterministically = rating_year - 2 for EVERY row (verified: offset always 2). Reflects CMS's standard ~2-year lag between data collection and rating publication. Derived, not independent. |
payment_year | int | The year CMS payment/bonus adjustments apply. Deterministically = rating_year for EVERY row (verified equal in 100% of rows). Derived/redundant with rating_year in this table. |
is_current | boolean | SCD current-version flag. 100% TRUE for all 14,138 rows -- there are NO superseded/historical shadow rows in this table. Filtering on is_current=true is a harmless no-op today; it exists for the restatement model (when restatements arrive, old versions would flip false). |
cms_vintage_sequence | int | Ordinal of the CMS publication for a given rating_year (1=first/original release, 2=reissue, etc.). Constant 1 across all rows -- only original releases ingested so far; would increment if CMS reissues a year's tables. |
qbp_payment_year | int |
Query it
describe_data_source(source_fqn="medicare_silver.stars_contracts") # the card, live query_substrate(sql="SELECT * FROM medicare_silver.stars_contracts WHERE contract_id = '<value>' AND rating_year = '<value>' LIMIT 100")
| Item | Value |
|---|---|
| Typed tools that read it | get_stars_rollup |
| Identity key | contract_id |
| Join | how_to_join(source_fqn="medicare_silver.stars_contracts") |
| Raw door | Athena (read-only via query_substrate): medicare_silver.stars_contracts (filter is_current = true) |
| Company names | parent_org resolve to a permanent Vlada ID: resolve_entity(text=<name>); the company pages hold owners and holdings |
| Note | Grain-governed (medicare_ma_stars). |
This page as markdown: /docs-md/data/medicare_silver_stars_contracts.md · every page in one file: /llms-full.txt