Procedure · 6 steps
- 1Choose the billing unitDecide whether customers are billed in tokens, in a work unit, or in cost-weighted units such as cents of model cost, and fix the conversion.
- 2Create a meterIn Stripe Billing create a meter with an event name, sum aggregation, and the payload keys for the customer ID and value.
- 3Create a usage price on the meterCreate a recurring usage-based price linked to the meter, with graduated tiers if the plan includes an allowance.
- 4Add the price to subscriptionsAttach the usage price to each customer subscription alongside the base fee price.
- 5Send idempotent meter eventsSend events per tenant with a stable identifier so retries never double count, mapping X-PalmSouq-Tenant to the Stripe customer ID.
- 6Reconcile before invoicingCompare Stripe meter totals with the attributed usage per tenant before invoices finalize and investigate any gap.
Stripe Billing supports usage-based prices through meters: you define a meter, attach a price to it, and send meter events as usage happens. Stripe aggregates the events per customer and bills them on the next invoice. This guide covers the decisions specific to LLM usage, which has more than one token class and more than one model price.
Step 1: choose the unit
Raw tokens are the obvious unit, but a token on one model can cost many times a token on another, and a cache read costs a fraction of an uncached input token. If you bill raw tokens at one price, your margin moves whenever the model mix moves.
The alternatives are a work unit (documents, runs, conversations) with a fixed price, or a cost-weighted unit that already reflects the model mix. A common cost-weighted choice is cents of model cost: PALM SOUQ prices each request per tenant, sums it, and reports it to Stripe as cents. A tenant whose month cost $412.37 reports 41,237 units, and the Stripe price per unit applies your markup.
Step 2: create the meter
Create a meter with an event name such as llm_cost_cents, sum aggregation, and the default payload keys: stripe_customer_id for the customer and value for the quantity. Pick the event name carefully; it is the contract between your metering layer and Stripe.
Step 3: price and attach
Create a recurring usage-based price linked to the meter. If the plan includes an allowance, use graduated tiers: the first tier covers the allowance at zero, the next tier carries the overage price. Add the price to each subscription next to the base fee, so the invoice shows the base fee and the overage as separate lines.
Step 4: send meter events
Each event names the customer, the value and a unique identifier. Stripe uses the identifier to deduplicate, which makes retries safe. Sending one event per model request works but generates a lot of events at scale; most teams aggregate per tenant over a short window and send one event per tenant per window, with an identifier derived from the tenant and the window.
import Stripe from "stripe";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
await stripe.billing.meterEvents.create({
event_name: "llm_cost_cents",
identifier: "tg_2026-04-21_cus_Q8r2_1412",
payload: { stripe_customer_id: "cus_Q8r2", value: "41237" },
});Mapping tenants to Stripe customers
The simplest mapping is to use the Stripe customer ID as the tenant ID in X-PalmSouq-Tenant. If you use your own account IDs, keep a mapping table and make the billing sync look it up, never the application. PALM SOUQ billing sync stores the mapping per tenant and refuses to send events for tenants without one, raising an alert instead, so usage is never silently dropped or billed to the wrong account.
Step 5: reconcile
- Before invoices finalize, compare Stripe's aggregated meter value per customer with the attributed usage per tenant for the same period.
- Watch the period boundary: usage at 23:59 on the last day must land in the right invoice, so align the aggregation window with the billing period in UTC.
- Keep the raw per-request ledger. If a customer disputes an overage, you can show them the requests, models and token counts behind it.
With PALM SOUQ billing sync
PALM SOUQ runs steps 4 and 5 for you. You connect Stripe, choose the meter and the unit (tokens, cost in cents, or a custom work unit), and map tenants. The gateway prices every request, aggregates per tenant, sends idempotent meter events, and shows a reconciliation view per billing period. The same ledger drives quotas, so the number that caps a tenant is the number that bills them.
Nisha Pillai
Head of Customer Engineering, PALM SOUQ
BITS Pilani. Previously solutions architect at Wipro for generative AI rollouts. Runs onboarding, breaker tuning workshops and the 15-minute demo.