Skip to content

Cost and FinOpsGuide

Metering AI usage for usage-based billing: units, events, Stripe

Charging customers for AI usage looks like a pricing decision and turns out to be a data problem: which unit to bill, how to record it exactly once, what to do with failed and retried requests, and how to get it into a billing system before the invoice closes.

By INFRO Editorial

Published

6 min read

A dark ground with a ledger of thin amber lines, each line ending in a small lit counter, representing usage events recorded per customer

In short

To bill customers for AI usage, choose a billable unit customers understand (answers, documents, minutes, tasks) rather than raw tokens, record one usage event per completed unit with an idempotency identifier such as your request id, exclude or separately count failed requests, and send events to your billing system within its window. Stripe's Meters API accepts events up to 35 days old at up to 1,000 calls per second per account, and Stripe now recommends Metronome for new usage-based integrations.

Key takeaways

  • Bill in a unit customers understand and you can explain on an invoice; convert it to provider cost internally.
  • Record exactly one event per billable unit, keyed by an identifier you already have, such as your request id.
  • Decide in writing how failed, retried, cached and partially streamed requests are billed before the first invoice.
  • Send usage inside the billing system's window: Stripe Meters accept events up to 35 days old, but usage after an invoice finalizes is not added to it.
  • Reconcile the billing system's totals against your request log every period.

How do you meter AI usage for billing? Pick a billable unit your customers understand, record exactly one usage event for each unit delivered, keyed by an identifier such as your request id, and send those events to your billing system before the invoice closes. Then reconcile the billed totals against your own request log every period. The pricing is the easy part; this guide covers the data underneath it.

Choose the billable unit first

The unit you bill decides everything downstream. There are three common choices:

UnitExampleGood whenProblem
Raw tokens1M tokensYour customers are developers buying model accessUnpredictable for customers; changes with model and tokenizer
Work unitsDocuments, answers, images, audio minutesEach unit has a stable meaning to the customerYou carry the risk of cost per unit changing
OutcomesResolved tickets, completed tasksValue is clear and measurableNeeds a reliable definition of "done"

For most SaaS products, work units are the right answer. A customer can predict "500 documents a month"; nobody can predict tokens. Work units also protect the customer from your model choices: if you move a feature to a model whose tokenizer produces more tokens for the same text, their bill should not change.

Internally, keep both: the unit you bill and the provider cost behind it. The gap between them is your margin per unit, and it is the number to watch. AI feature unit economics shows how to work it out.

Price the unit from cost, then check it against value

A work unit needs a price that survives your heaviest realistic use of it. Start from the provider cost of one unit at the 90th percentile, not the median, because the expensive documents and long conversations are the ones that erode margin. Add the cost of retries and failures you absorb, then your target margin. That is the floor.

Then compare the floor with what the work is worth to the customer. If a reviewed contract saves a lawyer twenty minutes, $0.13 is far below the value and you have room; if the floor is close to the value, the feature needs a smaller model or a different design before it needs a price. Review the floor whenever a provider changes a rate.

Design the usage event

One event per billable unit, written when the unit is delivered. A good event carries:

usage event
{
  "event_id": "req_01JBZ4K2M7",          // unique and stable: your request id
  "customer_id": "cust_42",               // your billing customer, not an email
  "unit": "document_processed",
  "quantity": 1,
  "occurred_at": "2026-10-20T14:03:11Z",
  "feature": "contract-review",
  "model": "anthropic/claude-sonnet-5.5", // for your margin analysis, not the invoice
  "provider_cost_usd": "0.0231"           // estimate, for margin; never billed directly
}

Three rules make it reliable:

  • The identifier is the deduplication key. Derive it from something that already exists once per unit, such as the request id. A retried send of the same event must carry the same identifier.
  • Write it after delivery, not before the call. An event written before the provider call bills requests that later fail.
  • Keep it immutable. Corrections are new events (a negative quantity, or an adjustment in your billing system), not edits, so the history explains itself.

Decide the edge cases before the first invoice

Every AI product meets the same five cases. Write down what each one bills before a customer asks.

  1. Failed requests. The provider erred or timed out and the customer got nothing. Most products bill nothing, but count the failure separately so totals reconcile with the request log.
  2. Retries. Your code retried a timed-out request and the provider billed both attempts. The customer received one result, so bill one unit; absorb the duplicate provider cost and track it.
  3. Streams cut short. The customer's connection dropped halfway through a streamed answer. Decide whether a partial answer is a unit. Usage for a stream often arrives only at its end, so a disconnected stream may have no usage at all from the provider.
  4. Cached answers. If you serve repeats from a cache at no provider cost, decide whether the customer pays for the unit. Billing the unit keeps pricing predictable; not billing it is generous. Either is fine if it is stated.
  5. Internal and trial traffic. Evaluations, demos and free trials should never produce billable events. Keep them under a separate customer id or project.

Getting usage into Stripe

Stripe now offers two routes. Its documentation calls Metronome, now part of Stripe, its primary usage-based billing platform and the recommended starting point for new integrations, with real-time usage visibility and high-volume ingestion; basic usage-based billing on the Meters API remains fully supported for existing integrations12.

If you use the Meters API, these limits shape the design3:

  • Event fields. Each meter event carries the meter's event name, the Stripe customer id, a numerical value (decimals allowed) and an optional timestamp.
  • Idempotency. Every meter event has an identifier you can set; if you do not, Stripe generates one. Set it, from your request id.
  • Time window. Timestamps must be within the past 35 calendar days and not more than 5 minutes in the future. Stripe notes that accepting an event does not guarantee it reaches an invoice: usage must be reported before the period's invoice finalizes.
  • Rate. Live-mode meter events are limited to 1,000 calls per second per account and one concurrent call per customer per meter. The v2 meter event stream accepts up to 10,000 events per second.
  • Dimensions. Each meter accepts up to 10,000 unique dimension combinations per hour, and 100 per customer across all events.
send_usage.py
import stripe

def report_usage(event: dict) -> None:
    stripe.billing.MeterEvent.create(
        event_name="documents_processed",
        identifier=event["event_id"],  # same id on every retry: counted once
        payload={
            "stripe_customer_id": event["stripe_customer_id"],
            "value": str(event["quantity"]),
        },
        timestamp=event["occurred_at_unix"],
    )

The per-customer concurrency limit is the one that surprises teams: a busy customer generating many units per second will hit it. Stripe's own advice is to pre-aggregate usage before sending, for example one event per customer per minute, or to use the meter event stream for high volumes3. Pre-aggregation also reduces how much of your request path depends on a third-party API being up.

Reconcile every period

Usage billing goes wrong quietly: an event that failed to send, a duplicate with a fresh identifier, a timezone boundary. Close each period with a reconciliation:

  1. Sum billable units per customer from your request log.
  2. Sum the same customers' metered usage in the billing system.
  3. Investigate every difference above a small threshold before invoices finalize.

Do the same on the cost side: sum your estimated provider cost and compare it with the provider's invoice. A customer's share of provider cost is always an estimate, because provider cost APIs report organization totals; the organization total is what reconciles. Reconciling estimated LLM spend covers the cost side.

Limits before invoices

A usage price without a limit turns an infinite loop in a customer's integration into a large invoice and a dispute. Put a spend or quota ceiling on every usage-billed customer, with a notice at a threshold and an explicit opt-in to go above it. Per-customer AI usage limits covers the enforcement.

Exporting usage per customer from INFRO

If your AI requests go through INFRO, each one is already attributed to the end-customer id your app sends in metadata.user_id or the X-INFRO-User-Id header. From the Team plan, GET /v1/usage/end-customers returns one row per end customer, period, project and model — requests, unpriced and failed requests, cached responses, tokens, media units and the estimated provider cost at the rate in force when each request ran — as JSON pages or one CSV, ready to aggregate into meter events. INFRO measures; your billing system bills at your prices. INFRO never charges your customers and takes no part in that billing.

Summary

Bill a unit customers can predict, record one immutable event per unit with an identifier you already have, settle the edge cases in writing, send events within your billing system's window, and reconcile billed usage against your request log before every invoice closes.

Questions readers ask

Should I bill customers per token?
Usually not. Customers cannot predict tokens, token counts differ between models and tokenizers, and a model change would change their bill for the same work. Bill a unit they understand, such as documents processed, answers, minutes of audio or completed tasks, and price it from your provider cost plus margin.
How do I avoid double-billing usage events?
Give every usage event an identifier derived from something unique you already have, such as your request id, and send it with the event. Stripe treats each meter event as corresponding to an identifier and supports idempotency keys, so a retried send does not count twice.
Should failed AI requests be billed?
Most products do not bill a request the customer did not get a result from. Record failures anyway, as their own count, so your billing totals reconcile with your request log and you can see what failures cost you at the provider.

From the team that builds it

Where this shows up in INFRO

INFRO is a control plane in front of the provider accounts you already hold. The capabilities below are the parts of it this article touches, each with the documentation that defines its behaviour.

  • Usage per end customer, for billing

    Available with a plan

    Requests, tokens and estimated provider cost for each end customer, by day or month, project and model, as a CSV from the console or JSON from the API — for you to bill your own users from in your billing system. From the Team plan.

  • Spend attribution

    Available with a plan

    Group cost by model, project, key, or an end-user id you attach to the request.

    Read the documentation for Spend attribution
  • Usage and cost per request

    Available with a plan

    Every request records its model, latency, token or unit counts, and estimated provider cost, queryable by project and key.

    Read the documentation for Usage and cost per request
  • Negotiated provider rates

    Available with a plan

    Enter the rates your contracts actually carry, per model and optionally per provider, so estimated cost uses them before the vendor's list rate. Included from the Team plan.

    Read the documentation for Negotiated provider rates

INFRO accounts are self-serve. Provider usage is billed to you by your providers; INFRO charges a software subscription and takes 0% of model spend. See plans.

Sources

Numbered in order of first citation. Each was opened and checked against the claim on the date shown.

  1. 1.Basic usage-based billing (opens in a new tab) — Stripe. Accessed Oct 20, 2026.
  2. 2.Usage-based billing (opens in a new tab) — Stripe. Accessed Oct 20, 2026.
  3. 3.Record usage for billing with the API (opens in a new tab) — Stripe. Accessed Oct 20, 2026.

About this article

Stripe's behaviour is taken from its usage-based billing and meter event documentation, opened on 2026-10-20. The event design is general engineering practice and the code is illustrative. INFRO's export is described from its public documentation. Written by the team that builds INFRO, which measures usage but never bills its customers' customers.

Last checked against its sources on . The next review is due by . No separate named reviewer is recorded for this article.

How articles are written, sourced and corrected is set out in the editorial standards.