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:
// 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:
- A monthly $29 price, charged in advance at the start of each period.
- 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", becauseunit_amountonly takes whole cents).
Here's what customers pay. A tier with up_to: 100000 includes the 100,000th request.
| Requests in the period | Overage requests | Overage charge | Invoice with next month's fee |
|---|---|---|---|
| 60,000 | 0 | $0.00 | $29.00 |
| 100,000 | 0 | $0.00 | $29.00 |
| 100,020 | 20 | $0.01 | $29.01 |
| 128,400 | 28,400 | $14.20 | $43.20 |
| 1,000,000 | 900,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 minutes | Once per period | |
|---|---|---|
| Meter events per customer per month | About 8,600 at one every 5 minutes | One |
| Stripe's upcoming invoice | Shows usage so far, slightly behind | Shows no usage until the period ends |
| Live mode rate limits | 1,000 calls per second per account, one concurrent call per customer per meter | Rarely relevant |
| Fixing a wrong event | Cancel it by identifier within 24 hours | Recompute before you send |
| Reconciling | Many events against one invoice line | One number against one invoice line |
| Deadline | The last batch must land before the invoice finalizes | The 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.createdfrom 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:
- 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.
- After finalization, find the invoice line for the metered price whose
periodcovers the period, and compare its quantity with your total. Compare itssubtotal, which is in cents before discounts and taxes, with your own tier calculation. - 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:
| Change | When to apply it | Why |
|---|---|---|
| Between plans with only a flat fee | Immediately | No metered usage is at stake |
| Adds, removes or swaps the metered price | At the end of the period, with a subscription schedule | Mid-period swaps can leave usage unbilled; phase-transition invoices pick up grace-period usage |
| Cancellation | At the end of the period | Canceling 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 freeStripe billing isn't live yet. Keys, rate limits, quotas and the portal work today.