Skip to content
UsageRail

Metered billing for APIs

Updated October 20, 2026

Metered billing charges each customer for measured usage at the end of every billing period. For an API, the usual setup is a monthly fee that includes a block of requests plus a price per 1,000 requests beyond it, with usage counted per customer in your API and sent to Stripe when the period closes. This guide covers the setup decisions; the usage-based billing guide explains how the whole pipeline fits together.

Count usage per customer

Metered usage starts in your API server, after authentication has told you which customer is calling and after the response status is known. Counting at the end of the request lets you skip errors and rate-limited calls:

js
// Express: count once the response is sent, and only successful ones
app.use((req, res, next) => {
  res.on('finish', () => {
    if (req.customer && res.statusCode >= 200 && res.statusCode < 300) {
      usage.increment(req.customer.id, currentMinute());
    }
  });
  next();
});

Store counts per customer per minute rather than one row per request. That caps storage at 43,200 rows per customer per 30-day month however busy the customer gets, and it's enough detail to answer "what happened at 3 a.m. on the 9th?" Keep a mapping from each of your customers to their Stripe customer ID, and keep counts for at least as long as invoices can be disputed.

Decide what happens to counts held in memory. Batching writes is cheap but loses whatever hasn't been flushed when a process dies. UsageRail's SDK makes that trade: if a process is killed hard, up to about 10 minutes of unsent counts are lost and never billed. If that's not acceptable at your volumes, write through to a database on every request.

Included units and overage, worked through

Take a plan at $29 a month that includes 100,000 requests and charges $0.50 per 1,000 after that. On Stripe it's two prices on one subscription:

  1. A monthly $29 price, charged in advance at the start of each period.
  2. A metered price on your meter, charged in arrears, with graduated tiers: up to 100,000 at $0, then everything above at 0.05 cents per request (unit_amount_decimal: "0.05", because unit_amount only takes whole cents).

Here's what customers pay. A tier with up_to: 100000 includes the 100,000th request.

Requests in the periodOverage requestsOverage chargeInvoice with next month's fee
60,0000$0.00$29.00
100,0000$0.00$29.00
100,02020$0.01$29.01
128,40028,400$14.20$43.20
1,000,000900,000$450.00$479.00

Three setup details decide whether those numbers come out right.

Use graduated, not volume. With volume tiers, the tier the total lands in prices every unit, so the 128,400-request customer would pay $64.20 for usage instead of $14.20, and the included 100,000 wouldn't be free anymore.

Keep the base fee in its own price. A flat_amount on the first tier looks tidy, but it's billed in arrears with the usage, and Stripe bills the first tier's flat amount even when usage is zero. And because transform_quantity (billing per package of 1,000) can't be combined with tiers, the overage rate goes in unit_amount_decimal.

Expect rounding. Stripe rounds each invoice line to a whole cent, and its docs show 1.5 cents becoming 2. At this rate, any overage that isn't a multiple of 20 requests leaves a fraction of a cent, so check how a test invoice rounds before you hard-code a rule in your own checks. How to pick the numbers themselves is covered in the usage-based pricing guide.

Report as you go, or once per period

You can send usage to Stripe in small batches all month or as one total per customer after the period ends. Both work; they fail differently.

Every few minutesOnce per period
Meter events per customer per monthAbout 8,600 at one every 5 minutesOne
Stripe's upcoming invoiceShows usage so far, slightly behindShows no usage until the period ends
Live mode rate limits1,000 calls per second per account, one concurrent call per customer per meterRarely relevant
Fixing a wrong eventCancel it by identifier within 24 hoursRecompute before you send
ReconcilingMany events against one invoice lineOne number against one invoice line
DeadlineThe last batch must land before the invoice finalizesThe one event must land before the invoice finalizes

For a monthly plan with included units, we'd report once per period and show customers your own counts mid-month. It's the pattern UsageRail uses: one event per customer per period, sent 2 hours after the period ends. The cost is that Stripe's own invoice preview shows no usage until then, and that your grace period has to cover the delay.

Grace periods and invoice finalization

When a period ends, Stripe creates the invoice as a draft and finalizes it after a grace period: 1 hour by default, up to 72 hours. You set it on the Invoice settings page in the Dashboard, either as the account default or as rules with conditions such as "Has a metered price" or "Invoice is from a subscription cycle." Usage reported after finalization appears in the meter's summaries but is never added to that invoice or the next one.

How long to make it:

  • If you report within minutes of the period ending, the default hour works, but a few hours gives a stuck job room to recover.
  • If you report once, hours after the period ends, use 72 hours. Customers get their invoices up to three days later.
  • If your billing period is a day, keep the grace period under 24 hours. Stripe's docs warn against a grace period as long as the service period.

Stripe's docs add a few rules that are easy to miss:

  • Only invoices from a subscription cycle, and from schedule phase transitions that change metered items, wait for grace-period usage.
  • The first invoice of a subscription that charges automatically finalizes immediately, whatever your rules say.
  • If Stripe doesn't get a successful response to invoice.created from your webhook endpoint, it delays finalizing all invoices with automatic collection for up to 72 hours, so one broken endpoint holds up all of them.

Reconcile every period

Usage billing goes wrong quietly, so check every customer every period:

  1. Before the invoice finalizes, read the meter's event summary for the customer and the period and compare it with your own total. Stripe processes events asynchronously, so give new events time to show up. The summary window has to start and end on whole minutes.
  2. After finalization, find the invoice line for the metered price whose period covers the period, and compare its quantity with your total. Compare its subtotal, which is in cents before discounts and taxes, with your own tier calculation.
  3. Record the result per customer per period, and alert on any difference.

When a finalized invoice is wrong, Stripe won't move the missing usage to the next invoice for you, so you decide whether to bill the difference separately or absorb it, then fix the cause. The Stripe usage-based billing tutorial has tested Node and Python code for both checks.

Trials and plan changes

Stripe doesn't bill usage recorded during a free trial, though it shows up in the meter's summaries, and a new billing period starts when the trial ends. If trial users can make real calls, cap them, for example at the plan's included amount, because you serve every trial request for free.

For plan changes, the safe defaults:

ChangeWhen to apply itWhy
Between plans with only a flat feeImmediatelyNo metered usage is at stake
Adds, removes or swaps the metered priceAt the end of the period, with a subscription scheduleMid-period swaps can leave usage unbilled; phase-transition invoices pick up grace-period usage
CancellationAt the end of the periodCanceling immediately without prorate discards the period's metered usage

The usage-based billing guide explains what Stripe does with usage when a metered price changes mid-period in each billing mode.

What metered billing software adds on top of Stripe

Stripe handles the meter, the prices, the invoices, payment collection, retries and, if you turn it on, Stripe Tax. Stripe Billing's pay-as-you-go fee is 0.7% of billing volume on top of card processing (prices checked October 2026); the Stripe fee calculator adds it up for a given invoice.

What you still build yourself:

  • counting in your API, including what counts as billable
  • the reporting job, its identifiers and its ledger
  • reconciliation against meter summaries and invoices
  • usage pages and alerts for your customers
  • quotas and hard stops, because a meter records usage but never blocks a request
  • trial caps and plan-change rules

Metered billing software takes over some of that list. Stripe itself now recommends Metronome, a Stripe product, for new usage-based integrations, and says its meters remain fully supported for existing ones. Meters still handle a base fee plus overage, you can set them up yourself, and Stripe's comparison gives them fuller Checkout and Dashboard support, so they remain a reasonable choice for plans like the one above. Stripe has changed its recommended approach before, so check its current guidance when you start.

Other tools focus on the API side: counting, keys and limits in your server, with Stripe still sending the invoices. Our comparison of usage-based billing software covers what each option includes and what it costs. If your plans are a base fee plus overage and your customer count is in the hundreds, Stripe plus a careful reporting job is enough. Buy software when the API-side work starts taking real time every week.

Set the included units and the overage price. Skip the plumbing.

With UsageRail you define plans in a dashboard; it creates the prices on your Stripe account, counts usage in your API process and reports each period once it has closed.

Start free

Stripe billing isn't live yet. Keys, rate limits, quotas and the portal work today.