The Rate Card
What if pricing isn't a data model? Six customers built as traps, seventeen invoice lines, and a billing run from a policy written in plain English.
I ran an experiment last week that started as a throwaway Slack question and ended with an AI assistant producing billing-grade invoices from a pricing policy written in plain English. Seventeen invoice lines, all correct. One deliberately ambiguous case, and instead of guessing, it escalated to a human.
Parts of it broke, and parts of it prove nothing yet. Both are worth showing, because the result points at something bigger than billing.
It started with a question, not a plan
The question was mundane: do we have a way to track API calls or LLM usage per company?
I asked it in Slack, where a few AI agents live alongside the team. One acts inside our finance platform. One is a read-only investigator with access to our logs, traces, and code. One reads the codebase and scopes engineering work.
What happened next is the part I keep thinking about. The platform agent said no, we can't track usage, that data isn't in the platform. The investigator then read the actual request-logging code and corrected it: every request carries a company ID. Usage is traceable, it just lives in telemetry rather than a billing ledger. Then the platform agent claimed no pricing primitives existed for usage billing at all, and the investigator read the data models and corrected that too. Rate times quantity already exists. Custom properties exist. Billing recurrence exists.
The agents were doing adversarial discovery on each other. By the end of the thread, "we can't do usage-based billing" had collapsed into two specific missing pieces: a metered pricing type, and a path to feed usage counts into an invoice line. Two gaps, not ten. That's a very different engineering conversation.
The reframe
Somewhere in that thread came the idea that changed the shape of the whole thing. What if the rate card isn't a data model at all?
Billing logic normally lives in code. Tiers are enums. Changing a rate means a PR, a review, a deploy. The alternative we sketched puts pricing in a policy document the AI reads, while the platform keeps doing what platforms are good at: deterministic line math, invoice records, approval gates. The document defines what to charge. The system guarantees how it gets recorded.
This felt either elegant or dangerous, and I couldn't tell which. So I did the only reasonable thing and built a test designed to make it fail.
Every customer was a trap
I didn't test with friendly data. The pricing policy had real complexity: graduated tiers, a use-case discount, a per-customer negotiated override, a minimum monthly fee, explicit rounding rules, and mandatory escalation clauses. This is what that looks like, verbatim:
| Tier | Call range (per period, per customer) | Rate per call |
|---|---|---|
| Tier 1 (included) | 1 – 50,000 | €0.0000 |
| Tier 2 | 50,001 – 250,000 | €0.0020 |
| Tier 3 | 250,001 and above | €0.0012 |
Boundary rule: a customer with exactly 50,000 calls owes €0.00 for API usage. A customer with exactly 250,000 calls pays Tier 2 rates on 200,000 calls and nothing at Tier 3.
§8 Fallback rule. If, after applying this policy, exactly one rate cannot be resolved for a usage record, treat it as an escalation under §7 — never default to €0.00 and never guess a tier.
That's the whole trick, if there is one. No DSL, no pseudo-code. Rules a finance lead would write, stated the way they'd state them to a careful new hire.
Then I built six fictional customers, each targeting a specific failure mode.
The rounding trap. One customer's usage produces a line of exactly €7.725. The policy says round half-up, so €7.73. Banker's rounding, the default in a lot of software, gives €7.72.
The boundary trap. Exactly 50,000 API calls, sitting right on an inclusive tier ceiling. The right answer is €0.00. Billing even one call at the next tier means the boundary rule was misread.
The graduated vs. volume trap. A customer crossing into the third tier. Graduated pricing gives €595.30. Volume pricing, one rate applied to the whole amount, gives €495.30 or €725.50. Both wrong answers are more natural to compute than the right one.
The override trap. A negotiated flat rate that supersedes the standard tiers. Standard pricing says €478.75. The contract says €396.75.
The zero trap. No usage at all. The correct answer is no invoice. Not a minimum-fee invoice, and not a €0.00 invoice mailed to a confused customer.
The escalation trap. Usage that includes a credits metric the policy deliberately doesn't price. The policy says to hold the entire customer and ask a human. Not invoice the part you can price, not guess, not default to zero.
I computed the ground truth programmatically, so "correct" wasn't a vibe. Then I handed the assistant the policy and the usage data and asked for the invoices.
What happened
The plumbing fought me first. File attachments didn't forward from Slack to the assistant, and two large generations flat-out errored before I gave up and pasted everything as text. Real workflows have to survive real plumbing, and this one barely did.
Once the data landed, the run was clean. All six outcomes correct. All seventeen invoice lines correct, down to the descriptions, quantities, rates, and amounts. It rounded €7.725 to €7.73. It billed the boundary customer exactly nothing. It split the three tiers correctly. It applied the override and skipped the tier break the override says to skip. It issued no invoice for the zero-usage customer instead of triggering the minimum.
On the trap I cared most about, it held the entire Fjord Health invoice, including the 12,000 API calls it could have priced, flagged the unmapped credits metric, and asked a human what to do. Its actual output, unedited:
§7 escalation hold. Usage includes metric credits (1,200 units) which is not mapped in §1. Per §7.1, I must hold the entire invoice and request human confirmation — including the api_calls line (12,000 calls, which would be €0.00 in Tier 1 anyway) — before issuing anything for this customer.
Action needed: Please confirm how credits should be priced, or confirm it should be excluded, before I proceed with Fjord Health Oy's invoice.
Then it went a step further than the calculation. Before creating anything it asked whether the two products referenced in the policy actually existed in the system, and it checked the €5,000 spike-review threshold on its own. Both were behaviors we'd specced in the discovery thread. Nobody prompted either in the run.
The part that surprised me
Afterwards I asked a different kind of question: based on this sample, what pricing experiments would you run?
It stopped being a calculator and became an analyst. It noticed the minimum fee was covering 99% of one customer's invoice, which is a churn signal wearing a revenue costume. It noticed the enterprise override sat exactly between our Tier 2 and Tier 3 rates, quiet evidence that the band is defensible. It noticed the discounted use case was one customer's dominant workload, meaning the discount is subsidizing our most expensive traffic.
Is a sample of six a pricing study? No. But every observation was the kind of thing I'd expect from a decent analyst looking at the same table, and it came for free, thirty seconds after the billing run.
What this proves, and what it doesn't
It proves an LLM can apply a well-structured pricing policy with billing-grade fidelity. Tiers, overrides, minimums, rounding discipline, and the harder part: escalation discipline. Knowing when to stop is worth more than the arithmetic.
It leaves a lot unproven.
- The usage data was hand-fed. Production needs an idempotent ingestion path from telemetry, which is precisely the thing that doesn't exist yet.
- Six customers, one period. No claim about scale or month-over-month repeatability.
- I wrote the policy to be machine-readable. Customer-drafted policies will be messier, which is why the flow includes a policy-improvement step, the AI proposing an unambiguous rewrite for the customer to approve. We didn't test that here.
- No versioning, no rollback, no governance on the policy itself. A policy edited mid-period by the wrong person is the systemic risk in this whole design.
We pre-mortemed the flow before building anything, and the conclusion was that the policy is the highest-leverage failure point. If it's ambiguous, every downstream step compounds the ambiguity. This test doesn't refute that. It shows what happens when the policy is good.
The PRD I didn't write
It's worth naming what this experiment replaced, because historically it has a very specific shape.
Usage-based billing is a PRD. You write it, you hand it to an engineering team, and they build custom logic: tier evaluation, override handling, minimums, rounding, escalation paths. Then a migration, then a quarter or two of roadmap, then every future pricing change is another ticket in another sprint. And that's the good outcome. The conventional wisdom on billing engines is right: in 9.5 out of 10 cases you should not build one internally. Billing is where edge cases go to compound, and entire companies exist to sell you out of that problem.
But build and buy share a premise. Both assume pricing complexity has to be encoded as logic somewhere, either in your code or in a vendor's. The vendor path just moves the enum.
What this experiment points at is a third option: an ERP built expecting this. The platform carries the deterministic primitives, the lines and quantities and approvals and records, and treats the pricing rules themselves as a governed document that an AI applies. On that architecture, a new tier structure is an edit. A negotiated exception for one customer is a paragraph. The change that used to be a project becomes a diff and an approval.
This doesn't make billing less scary. It relocates the scary part. The risk stops being "did engineering implement proration correctly" and becomes "is the policy unambiguous, and who approved this version." That's a governance problem, and governance is a problem finance teams already know how to run. I'd much rather review a document than review a state machine.
Where this goes
The build list is short, and it got shorter because of the reframe: a metered pricing type, a usage ingestion path with idempotency keys, policy versioning with approval, a pre-flight validation step, and a dry-run mode for batch invoicing. The rate-card data model we thought we needed? We don't. The document is the rate card.
The division of labor that emerged is the thing I'd generalize. The document defines the rules. The platform guarantees the mechanics. The AI translates between them. A human approves anything ambiguous.
I suspect that pattern applies well beyond billing, anywhere the logic changes faster than you want to deploy code and the cost of a silent wrong answer is high. Which describes most of what an ERP does.
The whole test is reproducible: the policy, the usage data, and the expected results. I'd encourage running it against whatever stack you're betting on. The arithmetic is table stakes. Watch what it does with the trap it can't price. The system you can trust with billing is the one that knows when to ask.
