%20(1).png)
Event-Based Billing: How It Works and How to Build It
Build an event-based billing system with reliable events, metering, pricing, customer attribution, and invoicing for SaaS, APIs, and AI products.
See how to design a billing structure across subscriptions, usage pricing, credits, entitlements, event schemas, limits, and billing systems.
%20(1).png)
A seat-based plan can look fine until AI agents start doing most of the work. Usage rises while the billing structure still assumes people are the main unit of consumption.
Engineering feels the mismatch first. Counters appear in application code, credits arrive later, and one package change starts touching metering, access rules, billing webhooks, and several services.
A good billing structure gives each part of that flow a clear owner.
A billing structure defines how product access and usage become customer charges, and which systems own each step along the way.
The structure reaches further than the amount shown on a pricing page. Engineering still needs clear answers for identity, metering, access, balances, billing, and payment.
A billing structure should define:
A usage-based plan might charge for API requests. Engineering still has to decide which requests count, which account owns each event, how retries behave, and what happens when the account reaches its allowance.
AI products add a request-time requirement. The product may need to decide whether usage can continue before another model call, tool execution, or agent workflow starts.
A useful billing structure separates product access, usage state, financial calculation, and payments.
One architecture looks like this:
Product catalog → entitlements → metering and credits → billing → payments
That separation keeps product behavior from depending on invoice state.
An entitlement is a commercial allowance attached to what the customer bought.
Entitlements can represent:
RBAC answers authorization questions such as whether a user has an admin role. An entitlement answers a commercial question such as whether the account can use a premium model or consume another unit under its current package.
Billing providers then own the financial record. The entitlement layer owns the product-facing answer needed while the application runs.
AI products often need more than one charging mechanism because inference, tools, storage, and agent workloads can create very different usage patterns.
Subscription billing charges a recurring amount for a defined package.
The architecture stays manageable when access and consumption track the package closely. AI workloads can weaken that relationship because two accounts on the same plan may create very different amounts of inference or tool usage.
A subscription can still include a controlled usage boundary:
Monthly plan → included allowance → additional usage policy
Engineering then has to track the allowance alongside feature access.
The product also needs a defined response when usage reaches the boundary. That response may stop more consumption, draw from a credit pool, or move the account into an overage path.
Usage-based billing measures consumption and applies a rate to it.
Typical AI usage units include:
Each event needs a stable customer identity, timestamp, quantity, and event ID. Extra dimensions may identify the model, feature, workflow, or region when those fields affect pricing.
Retries need careful handling too. One retried request should still represent one billable event when the underlying work happened once.
Credits give several workloads one customer-facing unit. A lightweight classification request might burn fewer credits than an agent workflow using retrieval, several model calls, and external tools.
That abstraction can make the pricing model easier to work with, but the underlying credit system still needs detailed state.
Production credit infrastructure may need:
Those requirements appear once credits need to support reconciliation, refunds, promotions, and several grant types.
A single credits_remaining field cannot explain why a balance changed or which grant funded a request.
Hybrid billing combines a recurring package with variable consumption.
A common structure looks like:
Base plan + included credits + additional usage
The fixed component defines access and a starting allowance, and the variable component handles consumption beyond that included amount.
Engineering now has to keep two types of state aligned:
Mid-cycle plan changes make this more demanding, since an upgrade can change access and allowance while the current billing period remains open.
Committed usage gives the customer a defined amount of consumption for a contract period.
The application may need to track:
The contract can live at the account level while usage originates from users, agents, or departments below it.
That makes account hierarchy part of the billing structure too.
A clean implementation starts by deciding which system owns each piece of state. Eight steps cover the main architecture without turning the billing flow into a collection of patches.
The billable entity is the account or object that owns the commercial relationship.
That could be:
The paying entity and consuming entity can be different. One enterprise account might pay the contract while individual users and agents create usage beneath it.
A hierarchy could look like:
Account → department → team → user → agent
Usage can start at the agent level and still need to roll up to an account-level allowance, and that relationship should exist in the identity model before metering starts.
The billable unit needs a stable technical definition. “Agent run” sounds clear until one run includes retrieval, several model calls, retries, and external tools.
Engineering should define:
Retries need clear deduplication rules too. AWS Marketplace deduplicates metering requests by product, customer, hour, and billing dimension, which is a good example of why idempotency belongs in the usage event design from the start.
A simple event can look like:
{
"event_id": "evt_123",
"customer_id": "cus_456",
"feature": "research_agent",
"quantity": 1,
"timestamp": "2026-08-31T10:45:00Z"
}
The schema can carry more context when pricing requires it, but every additional pricing dimension becomes another field that producers and consumers need to interpret consistently.
Plan rules become difficult to operate when each service carries its own copy. A product catalog gives package definitions one home.
The catalog can hold:
Application services can consume the resulting entitlement state without embedding pricing definitions directly in request handlers.
That also reduces how many services routine package updates need to touch. Keep product catalog and entitlement state separate from billing-provider logic.
A customer can receive commercial access from several sources at the same time.
The effective entitlement may depend on:
The runtime needs to combine those inputs into one usable answer.
When those sources disagree (say, when a base plan says 100 credits, an add-on says 500, and a promotional grant says unlimited) the most generous value wins. That's the resolution rule the runtime applies before returning a single entitlement decision to the caller.
A useful entitlement response can include:
The application can then allow the request, apply a usage boundary, or show an upgrade path. This is where account hierarchy starts to matter too.
A parent account may own the contract while a department receives its own limit and several agents share the department allowance.
The billing structure should be able to represent that relationship directly.
Credits need rules before they reach production.
Start with the lifecycle:
Grant → available balance → consumption → expiry or adjustment
Then define how the balance behaves when several credit blocks exist.
One account could hold:
The burn policy should decide which credits are used first.
The product also needs defined depletion behavior.
Concurrency deserves attention here. Several agents may attempt to spend the same shared balance at the same time.
Credit deduction returns the updated balance synchronously in the same call, before the async metering pipeline settles. The next concurrent check sees the new balance.
Every usage report carries an idempotency key, so a retried request after a timeout or dropped connection is counted once.
Billing providers still have clear responsibilities.
They can own:
The runtime needs to react to financial events that change what the product should allow.
Stigg’s billing-integration guidance covers credit grants, consumption, refunds, revocations, top-ups, and tenant-level state alongside the existing billing provider.
Billing infrastructure gets interesting when dependencies stop behaving perfectly.
Production tests should cover:
Each case needs a defined owner and expected result. A timeout during an entitlement check should not leave every application service inventing its own fallback policy.
The Stigg pattern here is to fail closed: a timeout or unreachable upstream returns your configured defaults, and every service in the fleet gets the same answer instead of inventing its own.
The same principle applies to duplicate events. The event pipeline should define whether an event is idempotent and how duplicate delivery is detected.
Plans change while existing customers continue using the product, which means a new package may offer different credits, model access, or usage limits. Existing enterprise contracts might need to preserve older terms.
A versioned catalog can retain:
Historical state gives engineering a way to reconstruct what a customer was entitled to at a particular time.
That becomes especially useful during migrations, support investigations, and billing disputes.
AI products can create cost as soon as work starts, so a billing structure should define what happens before an expensive action reaches the model or tool layer.
A request path can look like:
Request → resolve account → resolve entitlement → check credits or allowance → execute workload → meter usage → update state
The entitlement and credit checks answer whether execution can proceed, and the metering step records what happened after execution.
That distinction matters because billing receives usage after the application has already done the work.
Metering records consumption, while the product still needs current entitlement and limit state to decide whether more usage can proceed.
Feature gating controls whether the product permits access to a feature based on entitlement state. The backend and frontend have different jobs.
A hidden button is a presentation choice, and a backend entitlement check is the enforcement mechanism.
The product can still show a locked premium feature while the backend rejects execution until the relevant entitlement becomes active.
A credit-based AI product needs clear ownership across catalog, credits, usage, and billing. A practical architecture can look like this:
This setup gives upgrades, refunds, and new credit purchases a defined path through the system without forcing every request handler to understand billing logic.
Billing architecture tends to become painful when the same commercial rule has several owners. You can spot that problem through a few recurring symptoms:
A custom implementation can serve a small catalog for a long time. The pressure increases once the product adds shared credits, several products, account hierarchy, concurrent agents, grandfathered packages, or customer-specific contracts.
At that point, engineering is maintaining a state machine that spans product access, usage, credits, and billing.
A custom billing layer is a reasonable choice when the product has one billing provider, a small number of workflows, and domain logic that engineering already understands.
The workload changes once another billing provider appears, refunds start interacting with credits, migrations become frequent, or customer identity needs to stay aligned across several systems.
Retries, schema changes, webhook versions, and identity mapping are recurring maintenance work once the surrounding stack grows.
The architectural question becomes which billing-related systems are valuable enough to keep owning internally for the next few years.
Stigg sits between the product and billing layer, where pricing and usage rules need to become live application behavior.
A billing provider records purchases, invoices, and payments, and Stigg keeps the usage state the application needs when the next AI request arrives.
Stigg gives engineering:
Miro shipped a credit-based AI pricing model in under 6 weeks on this architecture, saved 5,000 engineering hours, and migrated tens of millions of existing subscriptions with no custom scripts and no customer-facing disruption.
The Sidecar is the piece that brings those rules into the hot path. The application can make the usage decision before compute is consumed, using current entitlement and credit state rather than waiting for billing data to arrive later.
The Stigg docs are a useful next stop if you want to see how these runtime checks are implemented in a real AI product stack.
A billing structure defines who gets billed, what gets measured, how charges are calculated, and which systems manage access, usage state, invoices, and payments.
For AI products, the structure may also define request-time limits and credit checks before model or agent workloads run.
An AI billing structure should include customer identity, account hierarchy, billable units, usage events, entitlements, credit rules, limit behavior, billing integration, and failure handling.
The exact components depend on the product’s charging model and usage architecture.
Billing calculates and records financial charges. Entitlements define the access and usage rights associated with the customer’s package.
A billing system can record that an account purchased a plan, but the entitlement layer tells the application which features and limits currently apply to that account.
A credit ledger becomes useful when grants can expire, refunds affect balances, or paid and promotional credits follow different rules.
The ledger gives engineering a traceable record behind the current balance, including grants, consumption, expiry, refunds, and adjustments.
Usage limits should have a defined enforcement path.
A hard limit can reject further consumption. A soft limit can allow usage under an overage policy. The product may also surface an upgrade state when the customer reaches the allowance.
The relevant entitlement and usage state needs to be available before the protected workload runs.
Yes, Stigg works alongside existing billing infrastructure. The billing provider can handle invoices, payments, and other financial processes while Stigg manages product-facing credits, entitlements, metering, limits, and request-time usage state.