How to meter usage for Stripe usage-based billing
Stripe can charge per unit, but the numbers have to come from you. This guide covers what a billing-grade usage meter needs before those numbers reach an invoice.
1. Decide the unit your customer pays for
Pick one unit per price: tokens, API calls, jobs, GB stored, active users. Each maps to an aggregation: a sum (tokens, bytes), a count (calls, jobs) or a unique count (active users, seats). Keep the unit simple enough that a customer can check it against their own logs.
2. Record raw events, not running totals
Send one event per billable thing, with who it belongs to (the Stripe customer), the amount and when it happened. Raw events let you recompute totals, answer disputes and fix mistakes. A counter you increment in your database can't tell you why it's wrong.
3. Make every event retry-safe
Networks fail and workers retry. Without deduplication, every retry is a customer overcharged. Give each event a stable idempotency key so a resend is recognised and counted once. See deduping usage events with idempotency keys.
4. Handle late events on purpose
Queues back up and batch jobs run overnight, so some usage arrives after the month it belongs to. Decide a window (Usage Lab accepts events up to 30 days late), put the event in the month it happened, and decide what happens if the invoice already went out. Pushing the difference since the last sync, rather than the full total again, lets late usage top up without double-billing.
5. Roll up per customer per month
At period close you need one quantity per customer per price. Compute it from the raw events so late arrivals are included, and keep track of how much you've already reported to Stripe.
6. Hand the quantity to Stripe
Stripe's usage-based billing takes usage you report through its API and prices it on the subscription. Follow Stripe's usage-based billing docs for the current API and meter setup.
Doing it with Usage Lab
Usage Lab covers steps 2–5 with one endpoint: POST /api/v1/usage with an idempotency key, a 30-day late window and monthly rollups per subscription. Step 6, automatic push to Stripe Billing Meters, is coming soon and runs in dry-run today; for now you read the rollup and report it yourself.
curl -X POST https://usage-lab.marc-cf2.workers.dev/api/v1/usage \
-H "Authorization: Bearer $USAGE_LAB_KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: req_8f2c1" \
-d '{"meter":"tokens","subscription":"cus_123","value":1500}'