Skip to main content

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_at and status (active or disabled).
  • 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_json is 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_json is rejected as conflict.

Practical rule:

  • add a new effective_at for a new term value
  • never rewrite a historical value in place

Supported term kinds

  • pricing
  • e2r_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:

  1. Resolve provider cost from cost.base (catalog_cost by default, or catalog_price), then apply cost.adjustments in array order.
  2. Resolve customer price from price.base (catalog_price by default, catalog_cost, or the just-resolved resolved_cost), then apply price.adjustments in array order.

Each adjustment transforms the current exact rational rate:

opMeaning
fixedReplace it with numerator_xusd / denominator_minor
multiplierMultiply by a non-negative decimal (up to 18 decimal places) or N/D ratio
deltaAdd 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_key must be a normalized identifier.
  • New effective versions should use a new effective_at, not mutate historical values.

Prereqs

  • 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