Contract compliance

Put the contract beside the invoice: verify rates, arithmetic, billing periods, caps and credits, then surface the work that still needs a scope review.

For procurement, vendor management, recovery auditors, and finance teams paying service and usage invoices.

Where it fits in your workflow

Use this when procurement or accounts payable needs to check a service or usage invoice before payment, or when a recovery team reviews past billing. The contract’s structured terms determine the checks. Invoice headers and individual lines are separate items so a correct total cannot hide a problem in one line.

  1. Load the terms that applied. Supply the vendor’s contract, effective rate-card rows, term dates, currency, cap, rounding rule, scope text, expense clause and service-level commitments. Preserve the dates of rate changes.
  2. Verify the header and each line. Header checks reconcile the total and credits, billing period, contract cap and duplicates. Line checks compare applicable labor rates and quantity-times-rate arithmetic, then ask whether the work or expense is allowed by the supplied clause.
  3. Take a specific issue back to the vendor. Use the returned facts to identify the line, billed rate, applicable rate or missing credit. Resolve scope questions with the contract owner and keep that review alongside the invoice in your purchasing process.

What to send

  • Invoice header and lines. Contract and vendor IDs, invoice number and date, billing period, currency, total and applied credits; for each line, kind, quantity, rate, amount and description.
  • Contract terms. The contract record with status and dates, rate card, cap where applicable, scope of work, expense clause, service levels, rounding mode and decimal places.
  • Supporting history. Earlier invoices and their lines for cap and duplicate checks, plus service-level measurements for the billing period. Provide the parent invoice and contract when verifying an individual line.
  • Work detail. Role and unit for labor, service date when available, and a concrete description of the work. Keep labor, fixed, usage and expense lines in their correct categories.

Use POST /api/v1/verify for one item or POST /api/v1/audits for a population with shared context. See the request structure.

A correct rate with a scope question still open

The recorded invoice line bills 32.50 hours of senior-developer work at $150.00 per hour, for $4,875.00. The contract’s senior-developer rate rose from $145.00 to $150.00 on July 1; the invoice covers August. The work description concerns code review and payment-gateway maintenance.

The rate and arithmetic checks hold in the recorded response. The work-scope question is unqualified, so the result remains uncertain. Reimbursement is not applicable to this labor line. The reviewer’s next step is to confirm the described work against the scope of work; verifying this line does not verify the invoice header, cap or service credits.

Recorded verdict: uncertain. The table below comes from the saved response.

CheckRecorded outcomeFacts or explanation
A labor line's rate is at or below the rate-card rate for its role and unit when the work was done.holds{"billed_rate": "150.00", "card_rate": "150.00"}
The amount is quantity times rate under the contract's rounding rule.holds{"computed": "4875.00", "stated": "4875.00"}
The work on a labor, fixed or usage line is within the contract's scope of work.unqualifiedThis question is not yet qualified for the running model; its answer is recorded but decides nothing.
An expense line is reimbursable under the contract's expense clause.not_applicableOnly expense lines are reimbursements.

Recorded from the production service on 2026-10-03T04:20:17Z. This page displays a saved example, not a new verification request. Sensitive identifiers are masked in public examples.

Inspect the request and full recorded response

Request

{
  "use_case": "contract-compliance",
  "item": {
    "type": "invoice_line",
    "id": "INV-7731-1",
    "data": {
      "invoice_id": "INV-7731",
      "line_number": 1,
      "kind": "labor",
      "role": "senior_developer",
      "unit": "hour",
      "quantity": "32.50",
      "rate": "150.00",
      "amount": "4875.00",
      "description": "Code review and refactoring of the payment gateway adapter; fixed retry handling"
    }
  },
  "context": {
    "records": {
      "contract": [
        {
          "id": "C-2041",
          "vendor_id": "V-311",
          "start_date": "2026-01-01",
          "end_date": "2026-12-31",
          "status": "active",
          "currency": "USD",
          "cap_amount": "180000.00",
          "rate_card": [
            {"role": "developer", "unit": "hour", "rate": "120.00"},
            {
              "role": "senior_developer",
              "unit": "hour",
              "rate": "145.00",
              "effective_to": "2026-06-30"
            },
            {
              "role": "senior_developer",
              "unit": "hour",
              "rate": "150.00",
              "effective_from": "2026-07-01"
            },
            {"role": "qa_engineer", "unit": "hour", "rate": "95.00"}
          ],
          "scope_of_work": "Vendor will design, build, test and maintain the customer's order management web application and its integrations with the warehouse and payment systems. Services include software development, code review, automated and manual testing, release management and defect fixing. Hardware procurement, end-user training and work on other customer systems are excluded.",
          "expense_clause": "Customer reimburses reasonable travel expenses incurred at its written request, at cost: economy airfare, standard hotel rooms up to 220 per night, ground transport, and meals up to 75 per day. Alcohol, entertainment and personal items are not reimbursable.",
          "sla": [
            {
              "metric": "critical_defect_fix_days",
              "threshold": "2",
              "direction": "max",
              "credit_percent": "2"
            }
          ],
          "rounding": "half_up",
          "decimal_places": 2
        }
      ],
      "invoice": [
        {
          "id": "INV-7731",
          "contract_id": "C-2041",
          "vendor_id": "V-311",
          "invoice_number": "7731",
          "invoice_date": "2026-09-04",
          "period_start": "2026-08-01",
          "period_end": "2026-08-31",
          "currency": "USD",
          "total": "12711.20"
        }
      ]
    }
  }
}

Response

{
  "id": "ver_c533a525ac718d09",
  "object": "verification",
  "created_at": "2026-10-03T04:20:17Z",
  "use_case": "contract-compliance@1",
  "item": {"type": "invoice_line", "id": "INV-7731-1"},
  "verdict": "uncertain",
  "probability_true": "0.9338",
  "probability_basis": "calibrated",
  "certainty": null,
  "undecided": [
    {
      "assertion": "in_scope",
      "reason": "unqualified",
      "message": "This question is not yet qualified for the running model; its answer is recorded but decides nothing."
    }
  ],
  "assertions": [
    {
      "id": "rate_matches",
      "test": "procedure:rate_matches@1",
      "outcome": "holds",
      "error_bound": "0",
      "facts": {"billed_rate": "150.00", "card_rate": "150.00"},
      "evidence": [
        "/item/data/rate",
        "/item/data/role",
        "/item/data/unit",
        "/context/records/contract/0/rate_card/2/rate",
        "/context/records/invoice/0/period_start",
        "/context/records/invoice/0/period_end"
      ]
    },
    {
      "id": "amount_computes",
      "test": "procedure:amount_computes@1",
      "outcome": "holds",
      "error_bound": "0",
      "facts": {"computed": "4875.00", "stated": "4875.00"},
      "evidence": [
        "/item/data/quantity",
        "/item/data/rate",
        "/item/data/amount",
        "/context/records/contract/0/rounding",
        "/context/records/contract/0/decimal_places"
      ]
    },
    {
      "id": "in_scope",
      "test": "question:line_in_scope@1",
      "outcome": "unqualified",
      "message": "This question is not yet qualified for the running model; its answer is recorded but decides nothing.",
      "answer": {"p_yes": "0.975579"},
      "facts_given": {"rate_matches": true, "hours": "32.50"},
      "evidence": [
        "/context/records/contract/0/scope_of_work",
        "/item/data/description",
        "/item/data/role"
      ]
    },
    {
      "id": "reimbursable",
      "test": "procedure:reimbursable@1",
      "outcome": "not_applicable",
      "message": "Only expense lines are reimbursements.",
      "evidence": []
    }
  ],
  "indicators": [],
  "risk": {
    "points": "0.00",
    "probability": "0.0100",
    "basis": "prior",
    "base_rate": "0.01",
    "reasons": []
  },
  "scope": {
    "stratum": null,
    "evidence": "supplied",
    "skipped": [],
    "certainty_target": "0.995",
    "deterministic_only_verdict": "uncertain"
  },
  "configuration": "cfg_d9f7c8210e4e",
  "input_sha256": "a01c46dc0b85b41a9c07cbbc4858cc598c5df2bd509fa0211d96aae1191915c2",
  "usage": {"questions_asked": 1, "questions_cached": 0, "model_ms": 1732}
}

Supported records and checks

These definitions are generated from the registered use-case pack. A procedure computes a result from the supplied data; a question can decide a check only when it is qualified for the model and meets its thresholds. The descriptions name the checks; they do not authenticate the underlying business events. Supplied fields, defaults and comparison populations determine what each procedure can establish. Risk weights help prioritize review and are not probabilities.

  • invoice: A vendor invoice header: contract, billing period, currency, total and credits. Its lines are verified as invoice_line items.
  • invoice_line: One invoice line, verified with its invoice and contract in context.

invoice

A vendor invoice header: contract, billing period, currency, total and credits. Its lines are verified as invoice_line items. Required data fields: contract_id, vendor_id, invoice_number, invoice_date, period_start, period_end, currency, total.

AssertionRequiresDecided byRisk weight
contract_activeThe invoice is billed under the vendor's own contract, and its billing period falls inside the contract term while the contract was in force.procedure2.5
currency_matchesThe invoice is in the contract currency.procedure1.0
totals_match_linesThe total equals the sum of the invoice's lines less the credits applied.procedure1.5
within_capBilled to date under the contract, including this invoice, stays within the contract cap.procedure2.0
sla_credit_appliedWhen a service-level measurement inside the billing period misses its threshold, at least the contracted credit, a percentage of the period's non-expense lines, is applied.procedure1.5
not_duplicateNo earlier invoice under the same contract covers an overlapping period with the same lines.procedure2.5
IndicatorFires whenFamilyWeight
rate_at_ceiling@1Every labor line, at least two, is billed exactly at its rate-card rate.rate0.5
invoice_spike@1The total is at least twice the median of the contract's other invoices.volume1.0

invoice_line

One invoice line, verified with its invoice and contract in context. Required data fields: invoice_id, line_number, kind, quantity, rate, amount, description.

AssertionRequiresDecided byRisk weight
rate_matchesA labor line's rate is at or below the rate-card rate for its role and unit when the work was done.procedure2.0
amount_computesThe amount is quantity times rate under the contract's rounding rule.procedure1.5
in_scopeThe work on a labor, fixed or usage line is within the contract's scope of work.procedure, then question line_in_scope@1 if undecided1.8
reimbursableAn expense line is reimbursable under the contract's expense clause.procedure, then question expense_reimbursable@1 if undecided1.2
IndicatorFires whenFamilyWeight
rate_at_ceiling@1A labor line on an invoice that bills every labor line exactly at its rate-card rate.rate0.5
invoice_spike@1A line on an invoice whose total is at least twice the contract's median invoice.volume1.0
round_hours@1Labor hours of at least 40 in whole 8-hour days.volume0.3
weekend_work@1Labor performed on a weekend or holiday.timing0.3

Judgment questions and qualification

QuestionAsksStatusHoldout error bounds
expense_reimbursable@1Is this expense reimbursable under the contract's expense clause?no published qualification–
line_in_scope@1Is the work on this line within the contract's scope of work?no published qualification–

The table describes published evaluation evidence. For the qualification attached to the running service, inspect this use case’s live definition. A model answer can be recorded without deciding a check. How qualification works.

Scope and limits

  • A line verification covers that line. Submit the header and all relevant lines to cover the invoice-level assertions as well.
  • Caps, duplicates and service credits depend on the billing history and measurements you supply. Omitted history cannot support a population-wide conclusion.
  • This pack checks the represented contract terms. It does not interpret an entire contract’s legal effect, discover amendments elsewhere or negotiate a billing dispute.
  • A rate or credit calculation can reconcile while the supplied amendment, service measurement or approval still needs source verification. Header and line results do not authenticate those records.

A true verdict means all applicable, unskipped checks hold within the decision gates; false means at least one qualifying failure decided the item. Other assertions can remain unresolved even with a false verdict. An uncertain verdict means the evidence and decision gates do not support a decided result. Review the assertion outcomes and evidence before taking a business action. Read the decision method.

Published evaluation results

These measurements use synthetic populations with generator-stated truth. Coverage is the share receiving true or false verdicts, not measured accuracy on your records. Read the metrics and their limits.

Results for contract-compliance@1.

ConfigurationItemsDecided coverageCoverage gain (pp)Uncertain per 1,000True, rules: errors / nTrue, with modelFalse, rulesFalse, with model
Rules only445827.1%0.0 pp729.50 / 814, ≤ 0.37%–0 / 392, ≤ 0.76%–
With smalldecide 00607d88f6e1:float32-cpu445827.1%0.0 pp729.50 / 814, ≤ 0.37%–0 / 392, ≤ 0.76%–

Faults

FaultItemsFalse verdictsFalse or uncertain
amount_miscomputed41100.0%100.0%
billed_outside_term38100.0%100.0%
cap_exceeded30100.0%100.0%
currency_mismatch44100.0%100.0%
duplicate_invoice36100.0%100.0%
non_reimbursable_expense410.0%100.0%
out_of_scope_work390.0%100.0%
rate_above_card41100.0%100.0%
rate_increase_early43100.0%100.0%
sla_credit_missing46100.0%100.0%
total_mismatch37100.0%100.0%
unlisted_role36100.0%100.0%

Look-alikes

Look-alikeItemsFalse verdictsUncertain
borderline_in_scope300.0%100.0%
borderline_reimbursable200.0%100.0%
cap_reached_exactly100.0%0.0%
final_invoice_after_term200.0%0.0%
goodwill_credit200.0%0.0%
half_cent_rounding230.0%100.0%
rate_increase_effective570.0%100.0%
recurring_fixed_fee120.0%0.0%
sla_at_threshold200.0%0.0%
sla_breach_credited200.0%0.0%
supplementary_invoice200.0%0.0%
weekend_cutover200.0%100.0%

Holdout seeds 101, 102, 103, 104, 105, 106, 107, 108, 109, 110; dataset SHA-256 5192466d83436be8….

Run identity and dataset
ConfigurationRecorded atSource commitModel artifact SHA-256Dtype
deterministic_only2026-10-02T16:08:36+00:009bc3424a301c36ce532c2422dee9968dacc8fa71nonenone
smalldecide:00607d88f6e1:float32-cpu2026-10-02T18:51:58+00:009bc3424a301c36ce532c2422dee9968dacc8fa7100607d88f6e152b471e557f6a814471ab5a6faf900cae427d8b3d50d4614be17float32-cpu

Dataset SHA-256: 5192466d83436be8a81ec0efdfe6dee5440eea7f30cc03a0fdcc831fe66f01d5.

Schemas and integration

Every item, record and reference schema is at GET /api/v1/use-cases/contract-compliance.

Supported context record types: contract, sla_measurement, invoice, invoice_line.

Supported reference sets: calendar.

Start with a reviewable sample

Start with one contract and one billing period. Reconcile the supplied terms with the signed agreement, include the invoice lines and prior billing, and review the returned facts with the contract owner.

Try the console · API quickstart · Full API reference

From the blog