Termco
Termco

One Pricing Clause, Two Invoices

17 August 2026

Here's a sentence that sits in thousands of commercial agreements:

$0.10 per unit for the first 10,000 units, $0.08 per unit thereafter.

It has two defensible readings, and they don't produce the same invoice.

Read it as graduated and each rate prices only the units inside its own band. At 12,400 units that's 10,000 at ten cents plus 2,400 at eight cents, or $1,192. Read it as all-units and crossing 10,000 reprices the entire quantity at eight cents, or $992. The gap is $200 on one line item, and it recurs every period they stay above the threshold.

For tiered prices, Stripe's Billing API makes you declare which reading you mean: tiers_mode takes graduated or volume. Nothing about that field reads your contract. Somebody picked a value during implementation, working from a sentence that doesn't contain the distinction.

The ambiguity is in the paper

Tier basis is only the first fork. That sentence never says what window the 10,000 units is measured over.

Take a customer running about 1,100 units a month. Measured monthly, they never cross the threshold, so all twelve invoices bill at ten cents. Measured cumulatively across the contract year, they cross in month ten and the last three invoices change shape. Same usage, same clause, and the cumulative reading bills them less. A spot check in month three would find the two readings in perfect agreement.

Boundaries go wrong when the tiers get restated. An order form listing the bands as "0–10,000" and "10,000+" claims unit number 10,000 twice. Under graduated rating that overlap is worth two cents, small enough that a variance report rounds it into the noise. Under all-units it decides whether a customer landing precisely on 10,000 pays $1,000 or $800.

Verifying against the wrong source

Two comparisons are available here, and only one of them is verification.

If your monthly check ties the invoice to what the rating engine computed, you have confirmed that the invoice printed correctly. The engine and the invoice agree because one produced the other. That check passes when a side letter moves the measurement window, and it passes when the tier basis was configured wrong on day one, because consistency between engine and invoice is the only property it tests.

flowchart LR
  A["Contract text"] --> B["Parsed terms"]
  B --> C["Expected charge"]
  A -.->|"config set once"| D["Rating engine"]
  E["Meter reading"] --> D
  D --> F["Invoice"]
  F --> G["Check 1: engine vs invoice"]
  C --> H["Check 2: contract vs invoice"]
  F --> H

The other comparison re-derives the charge from the agreement text. Doing that forces you to represent the clause as parameters a machine can check: tier basis, measurement window, boundary inclusion, reset behavior, and whether tiers accumulate at the signing entity or across its subsidiaries. Each one has a default sitting somewhere in your stack. Defaults are how you get a clean year followed by an ugly true-up.

The objection worth answering

A technical buyer should push back here. A system that reads clauses this closely will read some of them wrong, and hundreds of exceptions a month that nobody triages is worse than silence. Fair. The number to interrogate is how many flags survive a human look. Timing differences shouldn't reach a person: usage landing on the far side of a period cutoff reconciles the following month, and flagging it generates work. A clause that can be read two ways should reach a person, with both readings priced and the sentence quoted. We do ask, someone on your team answers, and we'd rather say so now than sell you a system that stays quiet by guessing.

Pull the most recent invoice for your largest tiered customer and find the person who can point at the sentence that produced the total. If the answer is "that's how it's configured," you have a consistent invoice, not a verified one.