Stripe Usage Records
Report metered usage to Stripe Billing via the Meter Events API for usage-based pricing
Instructions
Stripe Usage Records
Report customer product usage to Stripe so it can be aggregated into billable charges. This fundamental covers the Meter Events API (the current approach) rather than the legacy Usage Records API.
Authentication
Stripe API key (secret key) with billing:write scope. Set as environment variable STRIPE_SECRET_KEY. All requests go to https://api.stripe.com/v1/.
Prerequisites
- A Stripe Meter object created via Dashboard or API (defines how events aggregate: sum, count, max, etc.)
- A Price object linked to the Meter (recurring price with
meterparameter) - A Subscription containing that Price, assigned to the customer
Create a Meter
curl https://api.stripe.com/v1/billing/meters \
-u "$STRIPE_SECRET_KEY:" \
-d "display_name=API Requests" \
-d "event_name=api_request" \
-d "default_aggregation[formula]=sum" \
-d "value_settings[event_payload_key]=request_count"
Response includes id (e.g., mtr_xxx). Store this — you need it to create prices.
Report a Meter Event
curl https://api.stripe.com/v1/billing/meter_events \
-u "$STRIPE_SECRET_KEY:" \
-d "event_name=api_request" \
-d "payload[stripe_customer_id]=cus_xxx" \
-d "payload[request_count]=150" \
-d "timestamp=$(date +%s)"
event_namemust match the meter'sevent_namepayload[stripe_customer_id]is required — identifies the customerpayload[{value_key}]must matchvalue_settings.event_payload_keyon the metertimestampis optional (defaults to now); use it for backfilling
Batch Reporting via n8n
For high-volume reporting, build an n8n workflow:
- Trigger: cron every 1 hour (or webhook from your app)
- HTTP Request node: query your product database for usage since last report
- Loop node: for each customer, POST to
/v1/billing/meter_events - Error handling: retry on 429 (rate limit) with exponential backoff
Rate limit: 1,000 meter events per second per meter. Batch if needed.
Query Usage Summary
curl "https://api.stripe.com/v1/billing/meters/mtr_xxx/event_summaries?customer=cus_xxx&start_time=1709251200&end_time=1711929600&value_grouping_window=day" \
-u "$STRIPE_SECRET_KEY:"
Returns daily aggregated usage per customer. Use this to build usage dashboards or validate billing accuracy.
Error Handling
400 invalid_request_error: Checkevent_namematches a meter,stripe_customer_idis valid404 resource_missing: Meter does not exist429 rate_limit_error: Back off and retry. Queue events if sustained.- Events with future timestamps are rejected. Events older than 35 days are rejected.
Tool Options
| Tool | API | Notes |
|------|-----|-------|
| Stripe | Meter Events API | Native, recommended |
| Chargebee | Metered Billing API | POST /api/v2/subscriptions/{id}/usages |
| Recurly | Measured Units API | POST /v2/subscriptions/{uuid}/add_ons/{code}/usage |
| Paddle | Usage API | POST /transactions with metered items |
| Orb | Events API | Purpose-built for usage-based; POST /v1/ingest |
| Metronome | Events API | Real-time metering; POST /v1/ingest |
| OpenMeter | CloudEvents-based | Open-source; POST /api/v1/events |