Medicare Part D Drug Spending Delta & Top Movers API (CMS) avatar

Medicare Part D Drug Spending Delta & Top Movers API (CMS)

Pricing

from $4.40 / 1,000 results

Go to Apify Store
Medicare Part D Drug Spending Delta & Top Movers API (CMS)

Medicare Part D Drug Spending Delta & Top Movers API (CMS)

Year-over-year Medicare Part D drug spending deltas and top movers from the keyless CMS API. Get spend change %, per-claim and per-beneficiary cost change, claims and beneficiary deltas, and CAGR per drug. Filter by drug, manufacturer, min spend or min change. No API key.

Pricing

from $4.40 / 1,000 results

Rating

0.0

(0)

Developer

Kyle Maloney

Kyle Maloney

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

3 days ago

Last modified

Share

CMS Medicare Part D Spending by Drug - Year-over-Year Delta and Top Movers

Turns CMS's annual Medicare Part D Spending by Drug file into ranked per-drug spending deltas: total spend, claims, beneficiaries, average spend per claim / per beneficiary / per dosage unit, plus CMS's own change and CAGR figures. Keyless, official CMS data-api.

v1.1 makes drug launches visible. Measured live on 2026-08-01: 197 of the 3,625 drugs (5.4%) have only one year of data because they entered Part D in the latest year. A percentage change from a base that does not exist is undefined, so they can never appear on a percentage ranking - and in v1.0 they sorted to the top of a "biggest decliners" list. Acthar Selfject spent $32,500,305.86 in its first Part D year and would have been reported as one of the programme's largest declines. Fixed, and launches are now labelled and rankable on their own key.

Who it's for

  • Pharma and payer analytics teams tracking Part D spend shifts by drug.
  • Health-policy researchers studying drug pricing and utilisation.
  • Investors and market-access teams watching launches and losses of exclusivity.
  • AI agents needing a "what is moving in Medicare Part D" tool.

Example input

{
"mode": "top_movers",
"sortBy": "spending_change_abs_incl_new_entrants",
"sortDirection": "desc",
"minSpendLatest": 100000000,
"topN": 100
}

Just the launches:

{ "newEntrantsOnly": true, "sortBy": "new_entrant_spending_usd", "topN": 50 }

Only genuine one-year deltas:

{ "requireYearOverYear": true, "sortBy": "spending_change_pct", "topN": 100 }

Inputs

InputTypeNotes
modestringtop_movers or search.
drugName / manufacturerstringCase-insensitive substring filters.
minSpendLatestintegerMinimum latest-year spend, USD.
minAbsChangePctnumberMinimum absolute percentage change.
sortBystringSee the note below on ranking launches.
sortDirectionstringdesc or asc. Rows with no value for the chosen key sort last in both directions.
requireLatestYearbooleanKeep only drugs present in the newest data year.
includeManufacturerBreakdownbooleanPull per-manufacturer rows as well as per-drug Overall rows.
newEntrantsOnlybooleanNew in v1.1. Only drugs in their first published Part D year. Default false.
requireYearOverYearbooleanNew in v1.1. Drop rows whose latest and prior years are more than one year apart. Default false.
topN / maxResultsintegerResult caps.

Ranking a launch

A drug in its first Part D year has no spending_change_pct - the base does not exist. Sort by spending_change_abs_incl_new_entrants to rank launches alongside continuing drugs: for a launch it is the full latest-year spend, from an implied zero base; for a continuing drug it is the ordinary absolute delta.

Output fields

One row per drug (or per drug x manufacturer with the breakdown on). 63 declared fields.

Drug identity

FieldDescription
brand_nameDrug brand (trade) name.
generic_nameGeneric (chemical) drug name.
manufacturer_nameManufacturer name, or "Overall" for the drug-level summary row.
manufacturer_countNumber of manufacturers CMS reports for this drug.
manufacturer_breakdown_includedTrue when per-manufacturer rows were pulled as well as the per-drug Overall rows.

Years covered

FieldDescription
latest_yearMost recent data year available for this drug.
prior_yearSecond-most-recent data year, used as the delta baseline.
first_yearEarliest data year available for this drug.
years_coveredCount of years with spending data for this drug.
years_availableEvery data year CMS publishes a spending figure for on this drug.
delta_span_yearsHow many years separate latest_year from prior_year. 23 live rows span more than one year (Ayuna jumps 2020 to 2024), so their spending_change_pct is a multi-year change.
delta_is_year_over_yearTrue only when delta_span_years is exactly 1. When false, spending_change_pct is NOT a year-over-year figure and is not comparable with rows where it is.
latest_data_year_availableNewest data year present in the retrieved CMS rows.
data_year_lagCalendar years between the newest CMS data year and today. Measured 2026-08-01: 2.

New market entrants

FieldDescription
is_new_entrantTrue when CMS publishes only ONE year of spending for this drug, i.e. it entered Medicare Part D in the latest year. 197 of the 3,625 drugs (5.4%) were new entrants in the 2024 edition.
entrant_statusnew_entrant, continuing, or unknown.
new_entrant_spending_usdLatest-year spending for a new entrant, in USD. Null for continuing drugs.
spending_change_abs_incl_new_entrantsAbsolute year-over-year spending change; for a new entrant it is the full latest-year spend, since a launch enters from an implied zero base. This is the only key on which a launch is rankable - the percentage from a non-existent base stays undefined.

Spending

FieldDescription
total_spending_latestTotal Medicare Part D spending in USD for the latest year.
total_spending_priorTotal spending in USD for the prior year.
total_spending_first_yearTotal spending in the earliest year CMS publishes for this drug.
spending_change_pctYear-over-year percent change in total spending (latest vs prior).
spending_change_absYear-over-year absolute change in total spending, USD.
spending_change_pct_full_spanPercent change in spending from the first published year to the latest - the full multi-year trend, not just the last step.
spending_trendCoarse trend label from the YoY spending change: rising, falling, or flat.

Claims and beneficiaries

FieldDescription
total_claims_latestTotal Part D claims (fills) in the latest year.
total_claims_priorTotal claims in the prior year.
claims_change_pctYear-over-year percent change in total claims.
total_beneficiaries_latestDistinct Medicare beneficiaries in the latest year.
total_beneficiaries_priorDistinct beneficiaries in the prior year.
beneficiaries_change_pctYear-over-year percent change in beneficiaries.

Unit economics

FieldDescription
avg_spend_per_claim_latestAverage Medicare spending per claim, latest year (USD).
avg_spend_per_claim_priorAverage spending per claim, prior year (USD).
avg_spend_per_claim_change_pctYear-over-year percent change in average spend per claim.
avg_spend_per_beneficiary_latestAverage spending per beneficiary, latest year (USD).
avg_spend_per_beneficiary_priorAverage spending per beneficiary, prior year (USD).
avg_spend_per_beneficiary_change_pctYear-over-year percent change in average spend per beneficiary.
avg_spend_per_dosage_unit_latestWeighted average spending per dosage unit, latest year (USD).
avg_spend_per_dosage_unit_priorWeighted average spending per dosage unit, prior year (USD).
avg_spend_per_dosage_unit_change_pctYear-over-year percent change in average spend per dosage unit.
total_dosage_units_latestTotal dosage units dispensed in the latest year.
total_dosage_units_priorTotal dosage units in the prior year. v1.0 emitted only the latest year.

CMS-supplied figures

FieldDescription
cms_chg_avg_spend_per_dosage_unitCMS-supplied change in average spend per dosage unit (decimal fraction) over its reported year pair.
cms_chg_year_pairYear pair CMS used for the above change figure.
cms_cagr_avg_spend_per_dosage_unitCMS-supplied compound annual growth rate of average spend per dosage unit (decimal fraction).
cms_cagr_year_rangeYear range CMS used for the CAGR figure.
outlier_flag_latestCMS high-cost outlier flag for the latest year (1 = flagged).
outlier_flag_priorCMS outlier flag for the prior year: 1 when CMS marks the drug an outlier, 0 when not, null when CMS published no flag.

Full published series

FieldDescription
spending_by_year_jsonJSON object of year to total spending USD, for every year CMS publishes. v1.0 fetched five years and emitted two.
claims_by_year_jsonJSON object of year to total claims.
beneficiaries_by_year_jsonJSON object of year to total beneficiaries.
dosage_units_by_year_jsonJSON object of year to total dosage units.

Completeness, status and provenance

FieldDescription
cms_dataset_statusPer-source outcome for the CMS data-api. Never blank on a healthy row. If CMS never answered, the run fails and emits nothing.
cms_dataset_errorError text if the CMS pull degraded. Null on a healthy run, which is good news, not a dead column.
cms_distribution_uuidThe CMS data-api distribution that answered this run.
cms_uuid_sourcecatalog_confirmed when the pinned distribution is the one CMS lists as latest, catalog when it was discovered, pinned_fallback otherwise. The run fails if the distribution is not the current edition.
cms_catalog_modifiedLast-modified date CMS publishes for the dataset in its catalog.
source_rows_expectedExact row count CMS reports for this query via /data/stats found_rows, which respects the same filter as the data call.
source_rows_fetchedRows actually retrieved and analysed.
source_rows_completeTrue when every row CMS reports for this query was retrieved. A ranking over an arbitrary subset would be wrong, not merely incomplete, so a shortfall fails the run.
retrieved_atUTC timestamp when this run queried CMS.
source_systemOriginating dataset.
source_urlCMS dataset landing page.

Reliability - what this Actor asserts live, on every run

An offline fixture cannot see a superseded edition, because the fixture was shaped from the superseded data. Before any billable row is emitted, the run fails if any of these regress. Every measured value is logged.

  1. Vintage - the distribution being queried must be the one CMS's own catalogue lists as latest. v1.0 probed a pinned UUID first and returned it whenever it still had rows, so a superseded edition that stayed online would be answered from indefinitely. Three actors in this portfolio shipped exactly that failure.
  2. Row-count band - measured 2026-08-01: 14,536 total rows, 3,625 Overall per-drug rows.
  3. Negative control - an impossible manufacturer filter must return an empty array. If CMS ever stops applying filter[Mftr_Name], an Overall pull would silently become the whole 14,536-row file with per-manufacturer rows masquerading as drug totals.
  4. Reconciliation - /data/stats returns a found_rows that respects the same filter as the data call. Retrieving fewer rows than that fails the run: a ranking computed over an arbitrary subset is wrong, not merely incomplete.
  5. Freshness - the newest data year must be within four calendar years of today (measured 2026-08-01: data year 2024, lag 2).

If the CMS data-api never answers, the run fails with an explicit message. It never emits "no drugs matched", which is a different fact.

Limits you should know

  • CMS publishes this file annually, roughly 18 months after year end. The 2026 edition covers data years 2020-2024.
  • 23 drugs have a gap of more than one year between their latest and prior published years. Their spending_change_pct is a multi-year change; delta_is_year_over_year is false on those rows, and requireYearOverYear removes them.
  • Overall rows are per-drug totals across all manufacturers. Turn on includeManufacturerBreakdown for per-manufacturer detail.
  • Spending is gross Part D spend before manufacturer rebates, which CMS does not publish at drug level.

Use as an MCP tool

Available to AI agents through Apify's MCP server. An agent can read is_new_entrant and delta_is_year_over_year to know whether a percentage is even defined and comparable before quoting it.

Pricing

Pay per result: one event per emitted drug record. A run that fails a drift assertion or never reaches CMS emits nothing and bills nothing.

FAQ

Why is spending_change_pct null on some drugs? Because CMS publishes only one year for them - they launched. Sort by spending_change_abs_incl_new_entrants to rank them.

Did the v1.1 changes alter my existing results? Only one ordering changed, and only because it was wrong: rows with no value for the chosen sort key used to rank as the extreme low value, which put launches at the top of an ascending "biggest decliners" list. They now sort last in both directions. Every output field keeps its v1.0 value; the new inputs default to off.

Is this the same as the CMS quarterly file? No. This is the annual Medicare Part D Spending by Drug dataset.

  • CMS Open Payments Roll-up - industry payments to prescribers.
  • CMS NADAC Price Movers - pharmacy acquisition-cost movement.
  • Drug Shortage Delta Monitor - openFDA shortage changes.