Record usage for billing with the API
Learn how to record usage using the Stripe API.
You must record usage in Stripe to make sure you bill your customers the correct amounts each billing period. To record usage, first configure your meter, and then send meter events that include the event name configured on the meter, customer ID, numerical value, and a timestamp (optional).
You can decide how often you record usage in Stripe, for example as it occurs or in batches. Stripe processes meter events asynchronously, so aggregated usage in meter event summaries and on upcoming invoices might not immediately reflect recently received meter events.
Create meter events
Create a Meter Event using the API.
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
Idempotency
Use idempotency keys to prevent reporting usage for each event more than one time because of latency or other issues. Every meter event corresponds to an identifier that you can specify in your request. If you don’t specify an identifier, we auto-generate one for you.
Event timestamps
Make sure the timestamp is within the past 35 calendar days and isn’t more than 5 minutes in the future. The 5-minute window is for clock drift between your server and Stripe systems.
Usage values
The numerical usage value in the payload accepts decimal values. Decimal values are also supported on invoices. If the overall cycle usage is negative, Stripe reports the invoice line item usage quantity as 0.
Dimension cardinality limits
Stripe limits how many unique combinations of configured dimension payload key-value pairs it accepts:
- For each meter, Stripe accepts up to 10,000 unique combinations for each hour that Stripe receives meter events.
- For each customer on a meter, Stripe accepts up to 100 unique combinations across all events.
Events for dimension combinations already counted toward the applicable limit continue to process. Events that introduce a new dimension combination after either limit is reached are invalid and appear in v1.billing.meter.error_report_triggered with the meter_event_dimension_count_too_high error code.
Rate limits
Calls to the Meter Event endpoint in live mode are subject to a separate rate limit, and don’t count against your account’s global rate limit. The Meter Event limit is 1000 calls per second per Stripe account. Meter Events are additionally limited to one concurrent call per customer per meter.
In a sandbox, calls to the Meter Events endpoint count toward your global rate limit. For Connect platforms, calls on a connected account to the Meter Events endpoint also count toward the basic limit.
Meter events also have dimension cardinality limits, which limit the number of unique dimension payload combinations that Stripe accepts. These limits are separate from API request rate limits.
If you anticipate exceeding these limits, you have two options:
- Pre-aggregate your usage data before sending it to Stripe. For example, instead of sending a Event for each individual user action, you could accumulate usage across multiple actions and send a single aggregated event periodically. This reduces the number of API calls while still accurately reporting total usage.
- Use the high-throughput ingestion method with meter event streams for significantly higher volumes.
Note
If you’re a Connect platform making requests on behalf of a connected account using the Stripe-Account header, you’re subject to regular Stripe rate limits, which is 100 operations per second.
You can monitor for 429 status codes and implement a retry mechanism with an exponential back-off schedule to manage request volume.
High-throughput ingestion with higher rate limits API v2
With the API v2, you can send up to 10,000 events per second to Stripe using meter event streams. This works in live mode only.
This endpoint uses stateless authentication sessions. First, create a Meter Event Session to receive an authentication token. Authentication tokens are only valid for 15 minutes, so you must create a new meter event session when your token expires.
Next, use the returned authentication token to create your high-throughput meter events with the Meter Event Stream.
Note
Because of the large volume of API requests, we don’t include meter event stream requests in the Workbench Logs tab.
You can monitor for 429 status codes and implement a retry mechanism with an exponential backoff schedule to manage request volume.
Select a language
Ruby
Python
PHP
Java
Node.js
.NET
Go
No results
require 'stripe'
require 'date'
class MeterEventManager
attr_accessor :api_key
attr_accessor :meter_event_session
def initialize(api_key)
@api_key = api_key
@meter_event_session = nil
Handle meter event errors
Stripe asynchronously processes meter events. If we find an error, we create one of the following Events:
| Event | Description | Payload type |
|---|---|---|
v1.billing.meter.error_report_triggered | This event occurs when a meter has invalid usage events. | thin |
v1.billing.meter.no_meter_found | This event occurs when usage events have missing or invalid meter IDs. | thin |
Warning
To create an event destination that subscribes to thin events, enable Workbench in your Developer settings.
Example payloads
The following is an example payload for a v1.billing.meter.error_report_triggered event.
{
"id": "evt_test_65R2GpwDsnmpzihMjdT16R2GDhI4SQdXJGRbvn7JA8mPEm",
"object": "v2.core.event",
"created": "2024-08-28T20:54:12.051Z",
"data": {
"developer_message_summary": "There is 1 invalid event",
"reason": {
"error_count": 1,
"error_types": [
{
Error codes
The reason.error_types.code provides the error categorization that triggered the error. Possible error codes include:
- meter _ event _ customer _ not _ found
- meter _ event _ no _ customer _ defined
- meter _ event _ dimension _ count _ too _ high
- archived _ meter
- timestamp _ too _ far _ in _ past
- timestamp _ in _ future
- meter _ event _ value _ not _ found
- meter _ event _ invalid _ value
- no _ meter (supported only for the v1. billing. meter. no _ meter _ found event type)
Listen to events
You can listen to events by setting up a webhook endpoint or another type of event destination.
- On the Webhooks tab in Workbench, click Create new destination. Alternatively, use this template to configure a new destination in Workbench with the two event types pre-selected.
- Click Show advanced options, then select the Thin payload style.
- Select
v1.billing.meter.error_report_triggeredandv1.billing.meter.no_meter_foundfrom the list of events. - Create a handler to process the event. Select a language Python Ruby PHP Java Node.js.NET No results
import os from stripe import StripeClient from stripe.events import V1BillingMeterErrorReportTriggeredEvent from flask import Flask, request, jsonify app = Flask(__name__) api_key = os.environ.get('the related setting') webhook_secret = os.environ.get('the related setting') - Test your handler by configuring a local listener with the Stripe CLI to send events to your local machine for testing before deploying the handler to production. Use the
--forward-thin-toflag to specify which URL to forward thethinevents to and the--thin-eventsflag to specify which thin events to forward. You can forward all thin events with an asterisk (*), or a subset of thin events to your application.$ stripe listen --forward-thin-to localhost:4242/webhooks --thin-events "*" - Trigger test events to your handler. Use the trigger function to run the following commands, which simulates the respective events in your account for testing.
$ stripe trigger v1.billing.meter.error_report_triggered --api-key <your-secret-key> $ stripe trigger v1.billing.meter.no_meter_found --api-key <your-secret-key> - If you process events with a webhook endpoint, verify the webhook signatures to secure your endpoint and validate all requests are from Stripe.
- Correct and resend invalid events for re-processing.
