Contract terms
Contract terms represent customer-specific commercial terms that influence billing behavior.
Use contract terms when you have enterprise customers with negotiated exceptions:
- contract-term-based pricing overrides
- special rating parameters
- negotiated credits or grant behavior
Contract model
Contracts are account-scoped and time-effective.
- A contract has
effective_atand status (activeordisabled). - Contract terms are versioned by
(kind, term_key, effective_at). - Query can resolve latest applicable term as-of a timestamp.
JSON value contract
Contract term payload is stored in contract_terms.value_json.
value_jsonis required for every term write.- The tuple
(kind, term_key, effective_at)is immutable as a version identity. - Writing the same version identity with a different
value_jsonis rejected as conflict.
Practical rule:
- add a new
effective_atfor a new term value - never rewrite a historical value in place
Supported term kinds
pricinge2r_param
Use stable term_key naming so terms can be safely queried and evolved.
Pricing term v2
kind=pricing is not arbitrary JSON. value_json must use the exact rational
billing/contract_pricing:v2 schema, and value_json.meter_code must equal the
outer term_key:
{
"kind": "pricing",
"term_key": "openai.gpt-4o.tokens.input",
"effective_at": "2026-08-13T00:00:00Z",
"value_json": {
"schema": "billing/contract_pricing:v2",
"meter_code": "openai.gpt-4o.tokens.input",
"cost": {
"base": "catalog_cost",
"adjustments": [
{ "op": "multiplier", "multiplier": "0.9" }
]
},
"price": {
"base": "resolved_cost",
"adjustments": [
{
"op": "delta",
"numerator_xusd": "1000000",
"denominator_minor": "1000000"
}
]
}
}
}
The two sides resolve in this order:
- Resolve provider cost from
cost.base(catalog_costby default, orcatalog_price), then applycost.adjustmentsin array order. - Resolve customer price from
price.base(catalog_priceby default,catalog_cost, or the just-resolvedresolved_cost), then applyprice.adjustmentsin array order.
Each adjustment transforms the current exact rational rate:
op | Meaning |
|---|---|
fixed | Replace it with numerator_xusd / denominator_minor |
multiplier | Multiply by a non-negative decimal (up to 18 decimal places) or N/D ratio |
delta | Add the signed rate numerator_xusd / denominator_minor |
Rates remain rational throughout resolution. The system does not round a configured per-million quote into a per-token integer, and the denominator is not a billing block.
Unknown properties, invalid numbers, a non-positive denominator, an unsupported
base/op/schema, or a meter_code/term_key mismatch returns 422 when the term
is written. Both cost and price are optional; omitting a side preserves its
default catalog base with no adjustments.
Contract pricing only adjusts a configured meter rate. If no active catalog
meter_prices row exists at the rating time, the term cannot manufacture a
rate: commit reports missing pricing and is quarantined. A selected malformed
stored term is a configuration failure and does not silently fall back to the
catalog rate.
Term write rules
term_keymust be a normalized identifier.- New effective versions should use a new
effective_at, not mutate historical values.
Prereqs
- Outcome-based model understanding: Outcome-based billing model (events then ratings).
Recommended approach
- Keep contract terms explicit and auditable.
- Prefer additive overrides rather than redefining your entire catalog.
- Ensure support can explain how a contract term affected an outcome.
Verify
- You can trace a billed output back to the effective contract term.
Next
- DSL reference: Events to ratings DSL