Hybrid usage pricing is the shape enterprise AI contracts converge on: a per-unit rate for the thing the platform actually does, a floor under it so the vendor is not funding a quiet quarter, a ceiling over it so the customer's finance team can forecast, and toggles that turn categories of charge on and off as the relationship changes. Three out of five SaaS companies now use some form of usage-based pricing (OpenView, 2023), and enterprise contracts are where the model stops being a pricing page and becomes an engineering problem.
The engineering problem is not metering. It is that none of those rules exists in isolation. A minimum, a cap, and a category toggle all land on the same invoice line, and the order in which they are applied changes the number the customer receives. Off-the-shelf billing tools price one dimension well and two dimensions if the two do not interact. The interaction is the product, and it is the part they do not build.
ML LABS designed and built the complete billing system behind HeartSciences' AI ECG platform — the cloud backend ML LABS engineered, live in clinical production across the US and the UK. Enterprise customers there needed per-unit processing fees across multiple pricing categories, per-site monthly minimums, annual spending caps, and role-based finance access with auditable invoices. The build ran from deployment infrastructure through invoice PDF generation, deployed across three environments with self-service access for finance teams.
How Rule Interactions Break Invoices
Every pair of pricing rules produces a specific failure mode that the engine has to handle explicitly, and each one produces an invoice that is technically defensible and commercially wrong. A site under its monthly minimum still gets charged the minimum — but only the rated portion of that bill counts against the annual cap, and rolling the whole minimum into the cap calculation quietly overstates it for the rest of the contract year. A site over its minimum gets the rated total, but if a category toggle is disabled mid-period, that category has to leave the rated total without moving the minimum baseline. A site approaching its cap needs the cap enforced at the line-item level, so the last invoice of the year stops at the ceiling instead of stepping over it.
These are not edge cases. They appear on the regular invoice cycle for the largest accounts, because the largest accounts are the ones whose contracts contain all three dimensions at once — which means the failure mode is concentrated exactly where the revenue and the scrutiny are.
Take a schematic contract — illustrative, not a client's — to see the trap in one page. A site carries a $10k monthly minimum, two billable categories, and a $100k annual cap on the rated total. In a quiet month, category A rates to $4k and category B to $3k. The rated total is $7k, so the invoice charges the $10k minimum. A naive engine then debits $10k against the cap, leaving $90k of headroom. But the contract says only the rated $7k reduces the cap, because the $3k top-up is a floor, not a consumption charge. Over a year of quiet months, that single misclassification hands the customer tens of thousands of dollars of cap headroom they never bought — or takes it away, which is worse, because they will find it.
Now disable category B mid-period for a renegotiation. The rated total drops to $4k, the minimum still applies, the cap contribution must be recomputed from category A alone, and none of the closed periods may be re-rated retroactively. Three rules, one invoice line, four ways to get it wrong. The bug surface is not arithmetic — it is sequencing and attribution: which dollar counts toward which limit, and in what order the rules apply.
graph TD
A1["Processing Events"] --> A2["Classification<br/>and Aggregation"]
A2 --> A3["Per-Unit<br/>Rating"]
A3 --> A4["Minimum and Cap<br/>Enforcement"]
A4 --> A5["Verified<br/>Invoice Totals"]
style A1 fill:#1a1a2e,stroke:#0f3460,color:#fff
style A2 fill:#1a1a2e,stroke:#0f3460,color:#fff
style A3 fill:#1a1a2e,stroke:#ffd700,color:#fff
style A4 fill:#1a1a2e,stroke:#16c79a,color:#fff
style A5 fill:#1a1a2e,stroke:#16c79a,color:#fffEvery processing event emits a billing event tagged with site, category, and timestamp. The metering layer captures, classifies, and aggregates those events by period and site. The pricing engine applies the contractual rules — per-unit rates, minimums, caps, and toggles — with the interactions made explicit rather than emergent. Billing events are treated the way payment systems treat idempotency (Stripe): a retry that double-counts a processing event is not a logging defect, it is an overcharge, and an overcharge is the one bug a finance team never forgets.
Reconciliation Is The Standing Guard
The billing dashboard shows the current period in near real time. The invoice shows the period after it closes. Those two numbers have to match, and the architecture that makes them match is the one where both derive from the same reconciled dataset — deriving state from an ordered log of events (Fowler, 2005) rather than maintaining two independently mutable totals that agree only by luck.
A dashboard and an invoice that disagree are two systems computing the same number twice. The fix is not a better reconciliation report. It is one dataset with two renderings.
Automated reconciliation runs inside the billing cycle, and discrepancies above a threshold block the invoice from releasing until someone has looked. That is a standing guard rather than a one-time fix, and it belongs in the same class as any other production alarm: an alert that requires a human means something is broken that a human has to decide about (Google, 2016). Everything else in the pricing surface — new sites with their own minimums, renegotiated rates, category toggles per site, cap values — is configuration, effective at the next period boundary, with full change history for audit. That is deliberate, and it is the difference between a pricing change taking an afternoon and taking a release: configuration is where a surprising share of production debt accumulates (NeurIPS, 2015), and a billing engine whose contract terms live in code is a system that will fight every renewal its own sales team wins. It is the same property that lets the platform's search layer absorb a new AI output type without a deploy: on this platform, the things most likely to change were designed as configuration from the start.
The finance surface is part of the product, not a report bolted to it. Invoices generate as structured documents with summary totals, per-site breakdowns, and verification totals that prove the breakdown sums to the header. A multi-site organization's invoice runs to many pages, and consistency across all of them is what makes it auditable rather than merely long. Finance teams reach it through role-based authentication with MFA — they get self-service access to invoices and dashboards without seeing anything operational, because the person who reconciles the bill and the person who runs the platform are not the same person and should not have the same permissions.
Signals This Scope Applies
The operational tells show up long before the architecture problem reaches an engineering backlog. Invoices ship late because someone is reconciling categories in a spreadsheet. The same customer disputes the same line item across consecutive cycles, and the resolution is a one-off credit rather than a rule fix. The dashboard and the PDF disagree by an amount large enough to argue about and small enough that nobody wants to escalate it. Each of those is a symptom of a billing system that cannot natively express the contract it is billing against.
The harder signal is internal. Sales agrees to a new pricing dimension during a renewal, and engineering is asked whether the system can support it by next quarter — and the answer is yes, then no, then yes with caveats, because rating and invoicing are tangled and a small contract change means touching both. When configuration changes are gated on code deploys, and finance has stopped trusting the dashboard enough to share it with a customer, the cost of the wrong abstraction has already passed the cost of building the right one.
When This Scope Is Premature
Not every AI product needs a custom billing system, and building one early is an expensive way to feel sophisticated. If pricing is a single per-unit rate with no minimums, no caps, and no category splits, Stripe's metered billing handles it, and it will keep handling it for longer than most teams expect.
The threshold is interaction, not volume — a distinction that gets sharper as agents start consuming the product instead of users, because per-seat pricing has no answer for a caller that never logs in. One dimension is a pricing page. Two dimensions that never touch are a configuration. The moment two or more rules must be enforced on the same invoice line simultaneously — a minimum that interacts with a cap, a toggle that interacts with both — generic tools stop saving work and start creating reconciliation work, and the reconciliation work is unbounded because it recurs every cycle. Until you cross that line, this whole article is a description of a problem you do not have.
First Steps
- Map the rule interactions, not the rules. Write down every pair of pricing dimensions in your largest contract and state what happens when both apply to one line. If more than two interact, no off-the-shelf tool is going to price your contract.
- Wire reconciliation before the first invoice. Automated dashboard-to-invoice comparison belongs in the architecture from the start, not in the post-mortem. The first run is supposed to surface gaps — that is what it is for.
- Separate metering, rating, and invoicing at the seams. A pricing change should touch rating configuration only. A new site should touch metering only. If either one touches all three, the abstraction is wrong and it will be wrong again next quarter.
Separate Metering, Rating, Invoicing
Capture every billable event with tenant, site, and category metadata. Feed aggregated usage into a pricing engine that enforces the contractual rules as configuration rather than code. Generate invoices from the same reconciled dataset that powers the dashboard, and put the finance team behind role-based access so they can serve themselves without an engineer in the loop. The architecture holds because it separates the three concerns that tangle in every generic billing tool: metering is what happened, rating is what it costs, invoicing is what the customer sees — and pricing models evolve without structural rework only when those three can move independently.
Wiring a billing engine into a live AI platform is one contained workflow with a hard correctness bar and a finance team who will notice every mistake, which is exactly the shape a production workflow build is built for: targets written into the SOW before work starts, and the first 30 days of Operate included, run by the person who built it — because the first invoice cycle in production is the real test, and it is not a test you want to take alone. If your contracts already have minimums and caps and toggles in them, the interactions are already priced into what you charge. They may as well be priced into what you bill.
References
- OpenView Partners. The State of Usage-Based Pricing: 2nd Edition. OpenView, 2023.
- Stripe. Idempotent Requests. Stripe API Reference.
- Fowler, M. Event Sourcing. martinfowler.com, 2005.
- Google. Monitoring Distributed Systems. Site Reliability Engineering, 2016.
- Sculley, D., et al. Hidden Technical Debt in Machine Learning Systems. NeurIPS, 2015.
