Stripe Legacy Usage Records Are Dead: The Meter Events Migration

Stripe removed usage records in API version 2025-03-31.basil. Pinning to acacia works but freezes you out of everything since. The migration is not a URL swap: usage records were keyed on a subscription item and supported an absolute set action, meter events are keyed on the customer and only aggregate — which makes set a code change, not an integration change.

8 min read

stripeusage recordsbilling metersmigrationusage metering

TL;DR: Stripe removed the legacy usage-records API in version 2025-03-31.basil. If you are still calling it, you are pinned to 2025-02-24.acacia or earlier, which freezes you out of everything Stripe has shipped since. Billing meters are now the only usage-based path. The migration is not a URL swap: usage records were keyed on a subscription item and supported an absolute set action, meter events are keyed on the customer and only aggregate. If you use set, you are changing how your application reports usage, not just where it posts.

This is the migration most teams discover by trying to upgrade their Stripe SDK and finding that a resource they depend on no longer exists.

What was removed, exactly

In API version 2025-03-31.basil, Stripe removed:

  • UsageRecord and UsageRecordSummary, and their endpoints
  • aggregate_usage on prices
  • billing_thresholds

Billing meters are the replacement, and Stripe is explicit that they are now the only solution for usage-based billing. There is no parallel track being maintained.

The pin is not a plan

You can keep sending usage records indefinitely by staying on 2025-02-24.acacia or earlier. A lot of teams have quietly done this, and it works.

It is worth being clear about what it costs, because the cost is invisible until you need something:

  • Every Stripe feature since early 2025 is unavailable to you. Not deprecated — unavailable, because you are on an older contract.
  • SDK upgrades become selective. You take security patches and skip everything else, and the gap widens each release.
  • The migration does not get cheaper. It gets more expensive, because you accumulate more usage history and more call sites against the old shape.

Pinning is a legitimate way to buy a quarter. It is not a way to avoid the work.

The part that is not a URL swap

This is where the migration bites, and it is skipped in most write-ups because it only shows up once you look at your own call sites.

Usage records (old)Meter events (new)
Keyed on Subscription item Customer, plus a meter event name
Needs a subscription first Yes — no subscription item, nowhere to report No. You can collect usage before the subscription exists
Absolute values action: 'set' overwrites the period total No equivalent. Meters aggregate; they do not accept a total
Deduplication Effectively your problem identifier on the event
Late arrivals Undocumented in practice A stated grace period — roughly an hour before invoice generation

If you used action: 'increment'

You are in the easy case. Increment maps onto meter events almost directly: each report becomes an event with a value, and the meter sums them. The work is plumbing — resolve the Stripe customer instead of the subscription item, name your meters, and start sending an identifier.

If you used action: 'set'

You have an application change, not an integration change.

set exists for systems that hold the authoritative total and periodically declare it: "this customer is at 4,210 units this month". Meters cannot accept that, because a meter is a sum of deltas. Declaring 4,210 twice would produce 8,420.

There are two honest ways out:

  1. Start emitting deltas. Report each unit of usage as it happens, with an identifier derived from the thing that happened — a request id, a job id, a row id. This is the correct destination and it is also the larger change, because your product code now has to emit at the moment of use rather than reconcile on a timer.
  2. Compute the delta yourself. Keep your own running total, and on each cycle send the difference against what you last reported. This preserves your existing architecture, and it moves the correctness problem into your code: you now own a counter that must survive restarts, must not double-report after a retry, and must be reconciled if it ever drifts.

Option 2 is often the pragmatic first step. Be aware that you have just built half a metering system, and that the half you built is the half that fails silently. If you go that way, write down where the running total lives, what happens if the reporting job runs twice, and how you would detect drift — because you will need all three answers eventually.

The one-hour grace period is an architectural fact

Meter events come with a reporting grace period of roughly an hour before invoice generation. That is a genuinely useful guarantee and it should change how you think about your pipeline.

It means your ingestion path has an hour of slack against Stripe's invoicing, not zero. A queue backing up for twenty minutes is survivable. It also means the reverse: anything arriving more than an hour after the period closes is your problem to handle, and you need a policy for it. Fold it into the next period, reject it, or correct the invoice — all defensible, and the failure mode is not choosing.

This is the same question every metering system has to answer, and it is worth reading the general version of it before you decide.

A migration order that does not risk revenue

  1. Inventory your call sites and actions. Specifically: how many use set. That number decides whether this is a week or a quarter.
  2. Create meters and prices alongside the old ones. Do not modify live prices; make new ones.
  3. Dual-report. Send usage records and meter events for a full billing period. Stripe's own guidance is to keep sending usage records until the migration is complete — take that literally.
  4. Reconcile per customer, per meter, per period. Matching grand totals is not agreement. Check each key, and expect the discrepancies to cluster around retries and period boundaries.
  5. Migrate subscriptions onto the new prices at a period boundary. Never mid-period.
  6. Bump the API version last, once nothing calls the old resources.
  7. Keep the old data readable for at least one dispute cycle. The first argument about a number will happen after you have cut over.

The question worth asking while you are in here

You are about to re-instrument every usage call site in your product. That is the expensive part, and it is the part you would have to repeat if you ever changed billing vendor — which, after Stripe bought Metronome, Adyen bought Orb and Salesforce bought m3ter, is no longer a hypothetical.

So it is a reasonable moment to ask whether your product code should be posting to your payment processor at all, or whether it should emit events into a metering layer that rates and forwards. The second shape costs a little more now and makes the next migration a configuration change instead of another quarter of re-instrumentation. If your pricing is simple and you have no intention of leaving Stripe, it is over-engineering — say so and move on.

Related reading

Key Topics

  • stripe
  • usage records
  • billing meters
  • migration
  • usage metering

Related Articles

Explore more articles on similar topics to deepen your understanding of usage-based billing.

Stripe Billing Alternatives for Usage-Based Billing in 2026

Most teams looking for a Stripe Billing alternative have a metering problem, not a Stripe problem — and Stripe's own ans...

8 min readRead more

Designing Billing Meters: Value Types, Units, and the Four Aggregations That Decide the Invoice

A billing meter is a small schema decision with invoice-sized consequences: value type, aggregation (sum, count, max, un...

8 min readRead more

AI API Billing in 2026: Tokens, Credits, Requests or Outcomes?

The unit you measure and the unit you bill are not the same unit, and collapsing them is what makes AI pricing impossibl...

11 min readRead more

Explore More Articles

Discover our complete collection of usage-based billing guides and implementation patterns.

View all articles