> ## Documentation Index
> Fetch the complete documentation index at: https://evalgate.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Authoritative cost parity

> How EvalGate calculates, classifies, attributes, and presents model-call spend consistently across the API, UI, exports, reports, CLI, and SDKs.

# Authoritative cost parity

> Treat `cost_records` as the billing ledger, keep unknown spend unknown, and use the same eight-decimal USD contract on every surface.

EvalGate uses one authoritative cost contract for model calls and evaluation runs. Dashboard totals, Model Gateway call detail, workflow and Arena views, evaluation exports, signed reports, CLI output, and SDK payloads all derive known money from `cost_records`. A model-call ledger row can explain what happened, but it cannot invent or replace a monetary amount.

**Status:** Beta · **Owner:** Gateway & Providers / Evidence & Reporting · **Last verified:** 3.7.0-rc (2026-07-13)

## The contract

All serialized monetary values use USD with exactly eight decimal places. Numeric view models may parse those strings for charting, but they must use the same rounding contract when displayed or serialized again.

```json theme={null} theme={null}
{
  "currency": "USD",
  "decimalPlaces": 8,
  "totalUsd": "0.12345678",
  "verifiedUsd": "0.10000000",
  "estimatedUsd": "0.02345678",
  "verifiedCount": 1,
  "estimatedCount": 1,
  "unknownCount": 2,
  "recordCount": 2,
  "attribution": {
    "retryCount": 1,
    "retryUsd": "0.01000000",
    "fallbackCount": 1,
    "fallbackUsd": "0.02345678",
    "cachedCallCount": 1,
    "cachedInputTokens": 640,
    "cancelledCount": 0,
    "cancelledUsd": "0.00000000",
    "streamedCount": 1,
    "streamedUsd": "0.10000000",
    "duplicateRecordsIgnored": 0
  }
}
```

`totalUsd` is always `verifiedUsd + estimatedUsd`. It never includes a guessed amount for an unknown call. `recordCount` counts unique cost records after duplicate protection; confidence counts describe those unique records plus calls that have no cost record where applicable.

## Confidence classes

| Class         | Sources                                                                             | Monetary behavior                         | What the UI says                                                       |
| ------------- | ----------------------------------------------------------------------------------- | ----------------------------------------- | ---------------------------------------------------------------------- |
| **Verified**  | Server-computed, container-reported, gateway-reported, or EvalGate-computed records | Included in `verifiedUsd` and `totalUsd`  | Shows the amount and verified-call count                               |
| **Estimated** | SDK fallback or explicitly estimated records                                        | Included in `estimatedUsd` and `totalUsd` | Shows the amount as estimated and reports the estimated-call count     |
| **Unknown**   | Unknown model/source or a call with no cost record                                  | Excluded from every monetary total        | Shows an unknown-call count; never substitutes `$0` or a catalog guess |

<Warning>
  `$0.00000000` and **unknown** are different states. Zero is a known monetary value. Unknown means EvalGate has insufficient authoritative billing evidence and therefore omits the amount from the total.
</Warning>

Provider- or gateway-reported totals are stored without recomputing them from local catalog pricing. When a reported total and component prices differ, the reported total remains authoritative and the input/output components are scaled proportionally for a consistent breakdown.

## Attribution rules

<AccordionGroup>
  <Accordion title="Retries">
    Each provider attempt with its own cost record is charged once. Retry dollars are the sum of explicit retry records only. If the gateway reports a retry count but no per-attempt billing record exists, EvalGate reports the retry count without guessing retry dollars.
  </Accordion>

  <Accordion title="Fallbacks">
    A fallback call is identified from its terminal state or fallback chain. Its amount comes from the linked cost record. A fallback without a cost record increments the unknown count and contributes no dollars.
  </Accordion>

  <Accordion title="Cached input">
    Cached calls keep the amount actually charged by the provider. `cachedInputTokens` records the cache attribution and potential savings; it is not subtracted from spend a second time.
  </Accordion>

  <Accordion title="Cancellation and streaming">
    A cancelled or streamed call may still be billable. EvalGate includes money only when the call has a known cost record, while preserving separate cancelled and streamed counts. Partial streaming is not automatically free.
  </Accordion>

  <Accordion title="Blocked calls">
    A policy or budget block before provider egress is known zero and produces no cost record. It is not counted as unknown. A call that may have reached a provider but lacks billing evidence remains unknown.
  </Accordion>

  <Accordion title="Duplicate delivery">
    Cost records are deduplicated by durable record identity and Model Gateway call ID. The database permits at most one linked cost record per non-null model-call ID. Historical duplicates are retained for auditability but unlinked and marked unknown so they cannot inflate known spend.
  </Accordion>
</AccordionGroup>

## Surface consistency

The same ledger and rounding rules apply to every supported surface:

| Surface                | Source of money                                        | Confidence and attribution behavior                                                                |
| ---------------------- | ------------------------------------------------------ | -------------------------------------------------------------------------------------------------- |
| Costs dashboard        | Organization-scoped `cost_records`                     | Separates verified, estimated, and unknown calls; charts and tooltips use eight decimals           |
| Model Gateway calls    | Cost record linked by `costRecordId` or `modelCallId`  | A missing or unknown-source record returns `costUsd: null`, not the ledger estimate                |
| Evaluation run export  | Run-scoped cost records                                | Exports canonical `costSummary`; per-call unknown cost is `null`                                   |
| Signed/shared reports  | Run-scoped cost records included in the signed payload | Signature covers the canonical summary and its confidence counts                                   |
| Report cards           | Selected run cost records                              | Total and average cost exclude unknown amounts and display eight decimals                          |
| Workflow dashboard     | Workflow-run-linked cost records                       | Run and workflow totals ignore the legacy denormalized total and expose confidence counts          |
| Arena leaderboard      | Model-call-linked cost records                         | Historical results without model-call linkage appear as unknown rather than using stored estimates |
| CLI and TypeScript SDK | `CostParitySummary` schema                             | Human and JSON output use the same eight-decimal strings and explicit counts                       |
| Python SDK             | `CostParitySummary` Pydantic model                     | Camel-case aliases round-trip the API payload without changing precision                           |

<Note>
  Catalog prices are useful for planning and preflight estimates. They do not replace a post-call cost record in reports, gates, or dashboards.
</Note>

## API and SDK usage

Consumers should preserve the decimal strings when storing or signing results. Parse them only when numeric calculation is required, then round back to eight decimal places.

```ts theme={null} theme={null}
import {
  CostParitySummarySchema,
  serializeCostSummary,
} from "@evalgate/sdk";

const summary = CostParitySummarySchema.parse(apiResponse.costSummary);

console.log(serializeCostSummary(summary, "human"));
// Cost (USD): $0.12345678
// Verified: $0.10000000 (1)
// Estimated: $0.02345678 (1)
// Unknown: 2

const machineReadable = serializeCostSummary(summary, "json");
```

```python theme={null} theme={null}
from evalgate_sdk import CostParitySummary

summary = CostParitySummary.model_validate(api_response["costSummary"])
assert summary.total_usd == "0.12345678"
assert summary.unknown_count == 2
```

For offline CLI budget estimates, EvalGate marks the amount as estimated. It does not create a synthetic verified record merely because the client can calculate a catalog price.

## Operational checklist

<Steps>
  <Step title="Confirm the call identity">
    Open Model Gateway call detail and confirm the organization, model-call ID, terminal status, and linked cost-record ID.
  </Step>

  <Step title="Inspect confidence before comparing totals">
    Compare `verifiedCount`, `estimatedCount`, and `unknownCount`. Two surfaces can show the same known dollars while one has more incomplete billing evidence.
  </Step>

  <Step title="Check attribution">
    Review retry, fallback, cache, cancellation, streaming, and duplicate counts. A higher total can be legitimate when retries have explicit provider-attempt records.
  </Step>

  <Step title="Compare exact serialized values">
    Use the eight-decimal strings in API, export, report, CLI JSON, and SDK payloads. Avoid comparing a two-decimal screenshot with an eight-decimal export.
  </Step>

  <Step title="Reconcile missing records">
    If a provider call completed but no cost record is linked, keep it unknown and use provenance reconciliation. Do not patch the report with a hand-calculated estimate.
  </Step>
</Steps>

## Limits and failure behavior

* Provider billing can arrive late. Until the authoritative record exists, the call remains unknown.
* Unknown-source historical rows remain auditable but do not contribute dollars.
* A retry count alone does not prove retry spend; explicit attempt records are required for dollars.
* Workflow and Arena history created before durable model-call linkage can have unknown counts even when old JSON contains an estimated `cost` field.
* Signed reports are immutable snapshots. Reconciled cost evidence requires a newly generated report rather than mutation of an existing signature.
* Organization scoping applies to every cost lookup. A cost record from another organization is never used to fill a missing amount.

## Verification evidence

* [Canonical contract and attribution tests](https://github.com/evalgate/ai-evaluation-platform/blob/main/tests/unit/costs/cost-parity-contract.test.ts)
* [Cross-surface parity matrix](https://github.com/evalgate/ai-evaluation-platform/blob/main/tests/unit/costs/cost-surface-parity-matrix.test.ts)
* [Duplicate-delivery database invariant](https://github.com/evalgate/ai-evaluation-platform/blob/main/tests/integration/costs/cost-duplicate-delivery.db.test.ts)
* [Evaluation export API tests](https://github.com/evalgate/ai-evaluation-platform/blob/main/tests/api/evaluation-run-export.route.test.ts)
* [Real-database report export tests](https://github.com/evalgate/ai-evaluation-platform/blob/main/tests/integration/reports/export-route-real-db.test.ts)

<Tip>
  Treat unknown count as a release-evidence quality signal. A low known total with unresolved unknown calls is not proof that the run was inexpensive.
</Tip>
