Medicare Advantage, Part D, Medicaid

MA Star Ratings — measure cut points

medicare_silver.stars_cutpoints·live·silver·annual·Medicare Advantage Star Ratings
Rows
N/A
Columns
24
History
rating_year 2015 (effective_period_start 2014-10-09) to rating_year 2026 (effective_period_start 2025-10-10)
Card
yesgrain, traps, filters
Typed tools
1

What it is

  1. 1The official CMS Medicare Advantage (Part C) and prescription-drug (Part D) Star Ratings cut points: for each rating year, measure, and star level (1-5), the numeric score threshold band that earns that star count.

Grain

KeyGrain
measure_idstar_levelrating_year
  1. 1One row per (Star Ratings measure x star level x rating year).
  2. 21,815 rows = 46 measures (not all present every year) x 5 star levels x the measure's applicable years. org_subtype is a constant ('ALL') so it is not a real grain dimension.
  3. 3Verified: distinct count of (measure_id, star_level, rating_year) = 1,815 = total row count. calculation_epoch and bronze_publication_id are 1:1 with rating_year so they are interchangeable as the year dimension, but rating_year is the cleanest.

How to read it

  1. 1To find what 99-th-percentile-style band a plan needs for 5 stars on a measure: SELECT star_level, threshold_lower_op, threshold_lower_bound, threshold_upper_op, threshold_upper_bound, raw_threshold_text FROM medicare_silver.stars_cutpoints WHERE rating_year = 2026 AND measure_id = 'C01:' ORDER BY star_level.
  2. 2This returns the five score bands for that measure that year (e.g. star 1 '< 58%', star 5 '>= 84%'), letting an agent map any plan's raw measure score to its star rating.
  3. 3Always include the trailing colon in measure_id and read raw_threshold_text for the authoritative band edges.

Traps

  1. 1Minimal grain is (measure_id, star_level, rating_year) = 1,815 rows. org_subtype looks like a dimension but is constant 'ALL'; calculation_epoch and bronze_publication_id look like keys but are just 1:1 aliases of rating_year (each is per-year, not per-row, so neither alone is the grain).
  2. 2The parsed numeric columns (threshold_lower_bound / threshold_upper_bound and their _op columns) are a LOSSY extraction of raw_threshold_text and are frequently NULL when the actual value exists. E.g. RY2026 C01 star 2 raw text '>= 58 % to < 71 %' is a closed band but threshold_upper_bound is NULL. To reconstruct correct score bands, parse raw_threshold_text - do not trust the numeric bound columns as complete or authoritative.
  3. 3Units are NOT uniform across measures: most thresholds are percentages 0-100, but some measures use small/negative decimals (e.g. '< -0.114'). Never assume a 0-100 scale; the meaning of a threshold depends on the measure_id (measure metadata is not in this table - you must join to a measure dictionary).
  4. 4raw_threshold_text has dirty tokens: a '?' character is corrupted mojibake for the '>=' sign (e.g. '? 87%' = '>= 87%'), plus 'NA', '*', and '100%'. Rows containing these have BOTH parsed bounds NULL - they are unparsed top-band (star 5) thresholds, a real data-quality hole, not genuinely-missing cutpoints. measure_id also carries a trailing colon ('C19:').
  5. 5Coverage holes: rating_year 2022 is entirely absent (COVID-disrupted CMS cycle, years jump 2021->2023). Part D drug measures (D01-D12) appear ONLY in rating_year 2026; for 2015-2025 only Part C (C-prefix) measures exist - so drug-plan cutpoints are essentially missing before RY2026.
  6. 6is_current is TRUE for 100% of rows, effective_period_end / restatement_of are 100% NULL, and cms_vintage_sequence / parse_revision are constant (1 / 0) - the versioning machinery is in place but no restatements or second vintages have happened yet, so today these columns add no filtering value (do not write WHERE is_current logic expecting it to remove duplicates). Also: asserted_at is pipeline load time (May 2026), not source date - use rating_year / effective_period_start for source timing.

Columns (24)

ColumnTypeMeaning
measure_idstringCMS Star Ratings measure code, e.g. 'C01:', 'C19:', 'D04:'. C-prefix = Part C (Medicare Advantage health-plan) measures (C01-C34 observed); D-prefix = Part D (prescription-drug-plan) measures (D01-D12 observed). 46 distinct. GOTCHA: every value carries a trailing colon (parser artifact) - join/filter with the colon included or strip it first. The numeric suffix is just a sequential index within a year and is NOT stable across years (the measure behind 'C30:' can differ year to year).
star_levelintThe star band this threshold defines, integer 1-5 (exactly 363 rows at each level). 1 = lowest performance band, 5 = highest. Each (measure_id, rating_year) has all five levels, forming five contiguous score bands.
org_subtypestringOrganization subtype the cut point applies to. CONSTANT 'ALL' for every row (1,815/1,815) - cutpoints are not split by contract type in this table. Effectively a placeholder; do not use it as a grain or filter dimension.
threshold_lower_bounddoubleParsed numeric lower edge of the band (float). NULL means no lower bound (band is open at the bottom, typically star_level 1). Units vary by measure: most are percentages (0-100), but some measures (CAHPS/HOS-style) use small decimals incl. negatives (e.g. -0.114). GOTCHA: this is a LOSSY parse of raw_threshold_text - for many middle-band rows it is populated while the upper bound is left NULL even though both edges appear in the raw text.
threshold_upper_bounddoubleParsed numeric upper edge of the band (float). NULL means no upper bound (band open at top, typically star_level 5). GOTCHA: under-populated relative to raw_threshold_text - e.g. RY2026 C01 star_level 2 raw text is '>= 58 % to < 71 %' (a closed [58,71) band) but threshold_upper_bound is NULL and only the lower side was extracted. To reconstruct full bands reliably, parse raw_threshold_text yourself rather than trusting these numeric columns alone.
threshold_lower_opstringComparison operator for the lower bound: '>=' or '>' (or NULL when there is no lower bound). NULL exactly when threshold_lower_bound is NULL.
threshold_upper_opstringComparison operator for the upper bound: '<' or '<=' (or NULL when there is no upper bound). NULL exactly when threshold_upper_bound is NULL. Band logic by level: star 1 mostly '< X' (bottom-open), stars 2-4 mostly '>= X to < Y' (closed), star 5 mostly '>= X' (top-open).
raw_threshold_textstringThe verbatim threshold string as it appeared in the CMS source table, e.g. '< 77', '>= 61 to < 65', '>= 53 % to < 80 %', '< -0.114'. 1,151 distinct, never NULL - this is the audit/ground-truth value and is more complete than the parsed bound columns. GOTCHA: contains messy artifacts - inconsistent spacing ('< 27 %' vs '< 27%'), trailing '%', and a corrupted '?' character that is a mojibake of the >= sign (e.g. '? 87%' means '>= 87%'); rows with that '?' or with 'NA'/'*'/'100%' have BOTH parsed bounds NULL because the parser could not interpret them.
effective_period_startdateDate this rating year's cutpoints take effect (the CMS publication/effective date). One distinct value per rating_year, 11 total, ranging 2014-10-09 (RY2015) to 2025-10-10 (RY2026), normally early October. ANOMALY: RY2024 is 2024-07-02 (a mid-year republication). This is the table's primary time column; periodicity ~402 days = annual.
effective_period_enddateDate the cutpoints stop being effective. 100% NULL across all 1,815 rows - cutpoints are stored with an open-ended window and are never end-dated/superseded in this snapshot.
calculation_epochstringLogical version label for the cutpoint set, formatted 'ry<YYYY>_v<n>', e.g. 'ry2025_v1'. 11 distinct, 1:1 with rating_year, all '_v1' (no v2+ yet). Interchangeable with rating_year as the year key; the '_v' suffix is reserved for future CMS re-releases of the same year.
restatement_ofstringPointer (id) to a prior row this row restates/corrects. 100% NULL - no restatements have occurred yet. Reserved provenance column for when CMS reissues a vintage.
parse_revisionintInteger revision of the parser run that produced the row. CONSTANT 0 for all rows - only one parse generation exists. Bumps if the data is re-parsed from the same source.
parser_artifact_hashstringHash identifying the parser code/artifact version. 1 distinct value across the whole table - a single parser version produced every row.
source_urlstringURL of the official CMS Star Ratings ZIP the row was extracted from (one per rating_year, 11 distinct), e.g. 'https://www.cms.gov/files/zip/2025-star-ratings-data-tables.zip'. Confirms provenance as the CMS annual 'Star Ratings data tables' / 'star ratings and display measures' releases on cms.gov.
sha256_content_hashstringSHA-256 of the source content the row came from. 11 distinct (one per source file / rating_year) - content-addressed provenance tying each year's rows to a specific bytes-exact source download.
bronze_publication_idstringUUID of the bronze-layer publication batch. 11 distinct, 1:1 with rating_year. Identifies the ingestion event; usable as an alternate year key but rating_year is more legible.
asserted_attimestampTimestamp Vlada ingested/asserted the row (UTC), ranging 2026-05-17 to 2026-05-28. This is the PIPELINE load time, NOT the CMS source date - do not use it for source recency; use effective_period_start / rating_year instead.
rating_yearintThe Star Ratings year these cutpoints belong to (the year the ratings are published/branded). Observed 2015-2026, 11 distinct. GOTCHA: 2022 is MISSING (jumps 2021 -> 2023; CMS disrupted the 2022 measurement cycle during COVID). This is the recommended primary year filter.
performance_yearintThe measurement/data-collection year the cutpoints score. Deterministically = rating_year - 2 in every row (e.g. RY2025 -> performance_year 2023). Fully derivable from rating_year; carries no independent information.
payment_yearintThe MA payment year tied to the ratings. Deterministically = rating_year in every row. Redundant with rating_year.
is_currentbooleanWhether this is the live/current version of the cutpoint. 100% TRUE for all 1,815 rows - no superseded/historical versions are retained, so this column is effectively a no-op today (but exists to support future versioning alongside calculation_epoch/cms_vintage_sequence).
cms_vintage_sequenceintSequence number for multiple CMS vintages of the same rating year (1 = first/original release). CONSTANT 1 for all rows - no year has a second vintage yet. Increments if CMS republishes corrected cutpoints for a year.
qbp_payment_yearint

Query it

describe_data_source(source_fqn="medicare_silver.stars_cutpoints")     # the card, live
query_substrate(sql="SELECT * FROM medicare_silver.stars_cutpoints WHERE measure_id = '<value>' AND star_level = '<value>' AND rating_year = '<value>' LIMIT 100")
ItemValue
Typed tools that read itget_stars_cutpoints
Identity keymeasure_id
Joinhow_to_join(source_fqn="medicare_silver.stars_cutpoints")
Raw doorAthena (read-only via query_substrate): medicare_silver.stars_cutpoints (filter is_current = true)
NoteGrain-governed (medicare_ma_stars).

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