Medicare Part D Drug Spending Delta & Top Movers API (CMS)
Pricing
from $4.40 / 1,000 results
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
Maintained by CommunityActor 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
| Input | Type | Notes |
|---|---|---|
mode | string | top_movers or search. |
drugName / manufacturer | string | Case-insensitive substring filters. |
minSpendLatest | integer | Minimum latest-year spend, USD. |
minAbsChangePct | number | Minimum absolute percentage change. |
sortBy | string | See the note below on ranking launches. |
sortDirection | string | desc or asc. Rows with no value for the chosen key sort last in both directions. |
requireLatestYear | boolean | Keep only drugs present in the newest data year. |
includeManufacturerBreakdown | boolean | Pull per-manufacturer rows as well as per-drug Overall rows. |
newEntrantsOnly | boolean | New in v1.1. Only drugs in their first published Part D year. Default false. |
requireYearOverYear | boolean | New in v1.1. Drop rows whose latest and prior years are more than one year apart. Default false. |
topN / maxResults | integer | Result 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
| Field | Description |
|---|---|
brand_name | Drug brand (trade) name. |
generic_name | Generic (chemical) drug name. |
manufacturer_name | Manufacturer name, or "Overall" for the drug-level summary row. |
manufacturer_count | Number of manufacturers CMS reports for this drug. |
manufacturer_breakdown_included | True when per-manufacturer rows were pulled as well as the per-drug Overall rows. |
Years covered
| Field | Description |
|---|---|
latest_year | Most recent data year available for this drug. |
prior_year | Second-most-recent data year, used as the delta baseline. |
first_year | Earliest data year available for this drug. |
years_covered | Count of years with spending data for this drug. |
years_available | Every data year CMS publishes a spending figure for on this drug. |
delta_span_years | How 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_year | True 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_available | Newest data year present in the retrieved CMS rows. |
data_year_lag | Calendar years between the newest CMS data year and today. Measured 2026-08-01: 2. |
New market entrants
| Field | Description |
|---|---|
is_new_entrant | True 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_status | new_entrant, continuing, or unknown. |
new_entrant_spending_usd | Latest-year spending for a new entrant, in USD. Null for continuing drugs. |
spending_change_abs_incl_new_entrants | Absolute 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
| Field | Description |
|---|---|
total_spending_latest | Total Medicare Part D spending in USD for the latest year. |
total_spending_prior | Total spending in USD for the prior year. |
total_spending_first_year | Total spending in the earliest year CMS publishes for this drug. |
spending_change_pct | Year-over-year percent change in total spending (latest vs prior). |
spending_change_abs | Year-over-year absolute change in total spending, USD. |
spending_change_pct_full_span | Percent change in spending from the first published year to the latest - the full multi-year trend, not just the last step. |
spending_trend | Coarse trend label from the YoY spending change: rising, falling, or flat. |
Claims and beneficiaries
| Field | Description |
|---|---|
total_claims_latest | Total Part D claims (fills) in the latest year. |
total_claims_prior | Total claims in the prior year. |
claims_change_pct | Year-over-year percent change in total claims. |
total_beneficiaries_latest | Distinct Medicare beneficiaries in the latest year. |
total_beneficiaries_prior | Distinct beneficiaries in the prior year. |
beneficiaries_change_pct | Year-over-year percent change in beneficiaries. |
Unit economics
| Field | Description |
|---|---|
avg_spend_per_claim_latest | Average Medicare spending per claim, latest year (USD). |
avg_spend_per_claim_prior | Average spending per claim, prior year (USD). |
avg_spend_per_claim_change_pct | Year-over-year percent change in average spend per claim. |
avg_spend_per_beneficiary_latest | Average spending per beneficiary, latest year (USD). |
avg_spend_per_beneficiary_prior | Average spending per beneficiary, prior year (USD). |
avg_spend_per_beneficiary_change_pct | Year-over-year percent change in average spend per beneficiary. |
avg_spend_per_dosage_unit_latest | Weighted average spending per dosage unit, latest year (USD). |
avg_spend_per_dosage_unit_prior | Weighted average spending per dosage unit, prior year (USD). |
avg_spend_per_dosage_unit_change_pct | Year-over-year percent change in average spend per dosage unit. |
total_dosage_units_latest | Total dosage units dispensed in the latest year. |
total_dosage_units_prior | Total dosage units in the prior year. v1.0 emitted only the latest year. |
CMS-supplied figures
| Field | Description |
|---|---|
cms_chg_avg_spend_per_dosage_unit | CMS-supplied change in average spend per dosage unit (decimal fraction) over its reported year pair. |
cms_chg_year_pair | Year pair CMS used for the above change figure. |
cms_cagr_avg_spend_per_dosage_unit | CMS-supplied compound annual growth rate of average spend per dosage unit (decimal fraction). |
cms_cagr_year_range | Year range CMS used for the CAGR figure. |
outlier_flag_latest | CMS high-cost outlier flag for the latest year (1 = flagged). |
outlier_flag_prior | CMS 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
| Field | Description |
|---|---|
spending_by_year_json | JSON object of year to total spending USD, for every year CMS publishes. v1.0 fetched five years and emitted two. |
claims_by_year_json | JSON object of year to total claims. |
beneficiaries_by_year_json | JSON object of year to total beneficiaries. |
dosage_units_by_year_json | JSON object of year to total dosage units. |
Completeness, status and provenance
| Field | Description |
|---|---|
cms_dataset_status | Per-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_error | Error text if the CMS pull degraded. Null on a healthy run, which is good news, not a dead column. |
cms_distribution_uuid | The CMS data-api distribution that answered this run. |
cms_uuid_source | catalog_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_modified | Last-modified date CMS publishes for the dataset in its catalog. |
source_rows_expected | Exact row count CMS reports for this query via /data/stats found_rows, which respects the same filter as the data call. |
source_rows_fetched | Rows actually retrieved and analysed. |
source_rows_complete | True 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_at | UTC timestamp when this run queried CMS. |
source_system | Originating dataset. |
source_url | CMS 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.
- 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. - Row-count band - measured 2026-08-01: 14,536 total rows, 3,625
Overallper-drug rows. - Negative control - an impossible manufacturer filter must return an empty
array. If CMS ever stops applying
filter[Mftr_Name], anOverallpull would silently become the whole 14,536-row file with per-manufacturer rows masquerading as drug totals. - Reconciliation -
/data/statsreturns afound_rowsthat 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. - 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_pctis a multi-year change;delta_is_year_over_yearisfalseon those rows, andrequireYearOverYearremoves them. Overallrows are per-drug totals across all manufacturers. Turn onincludeManufacturerBreakdownfor 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.
Related actors
- CMS Open Payments Roll-up - industry payments to prescribers.
- CMS NADAC Price Movers - pharmacy acquisition-cost movement.
- Drug Shortage Delta Monitor - openFDA shortage changes.