Measurement Methodology · 2026.2

How one inference becomes carbon measured

This page documents the exact modeled emissions contract emitted by GET /api/v1/inference/attest: the operational-energy boundary, regional grid attribution, indicative procurement basis, and payload-integrity receipt that lets another system round-trip the result.

A versioned operational-energy estimate

METHODOLOGY_VERSION is 2026.2. The endpoint emits a versioned, simulated operational-energy, market-based Scope 2 estimate for a single query-equivalent inference-call workload. It is a reproducible demonstration number, not a live meter reading from a provider's GPU or data centre.

Version2026.2
BoundaryScope 2
Unitkg CO₂e

The endpoint surface is the API Docs; the proof surface is /verify; and the verified removals being calculated against are shown in the CDR portfolio.

Declared energy boundary and grid factors

The declared boundary is one simulated query_equivalent_inference_call with unit kWh per query-equivalent workload. NVIDIA lists H100 SXM maximum configurable TDP as 700 W; using the scenario assumption of 30 seconds, GPU energy is 700 W × 30 s = 5.833 Wh = 0.005833333 kWh. Google Green Computing uses 1.6 as a large-organisation PUE scenario, so the selected energy constant is 0.005833333 kWh × 1.6 = 0.009333333 kWh. The scenario excludes CPU, memory, networking, embodied emissions, batching effects, and provider-metered workload data. Sources: NVIDIA H100 and Google Green Computing. The global grid baseline in public/data/grid-intensity.json is 432 g/kWh; conversion is 432 ÷ 1,000 = 0.432 kg/kWh, with the row's source and date returned in the contract.

gpu_energy_kwh = 700 W × 30 s ÷ 3,600 = 5.833 Wh = 0.005833333 kWh
energy_per_query_kwh = gpu_energy_kwh × PUE 1.6 = 0.009333333 kWh
grid_kg_per_kwh = grid_g_per_kwh ÷ 1,000
per_query_kg_co2e = energy_per_query_kwh × selected_grid_kg_per_kwh

One visible contract. The browser calculator and API use the same simulated single-call boundary, selected regional grid factor, 365-day annualization, explicit rounding, and EUR 100/tonne indicative procurement basis. No physical removal is performed or retired by the demonstration.

Region lookup is exact and lower-case. A recognized row supplies the grid intensity; the contract returns its g/kWh value, the explicit divide-by-1,000 conversion, kg/kWh value, source, and source date.

Lookup keyg CO₂/kWhkg CO₂/kWhSourceSource date
global_average4320.432Ember Global Electricity Review 20252025-05-01
us_avg3730.373EIA eGRID 2024 summary2025-02-01
eu_avg2310.231EEA 2023 final2024-06-01
uk2070.207DEFRA GHG Conversion Factors 20242024-06-01
fr560.056EEA 20232024-06-01
de3380.338EEA 20232024-06-01
in6320.632CEA / Ember 20242024-12-01
ie2960.296SEAI 20242025-01-01

From request inputs to the emitted number

The route accepts a non-empty model label and normalizes the region to one of the published lower-case keys. Missing model, region, or tokens is a 400; an unknown region is rejected. The selected row supplies the grid factor used in the estimate.

energyPerQueryKWh = (700 × 30 ÷ 3600 ÷ 1000) × 1.6 = 0.009333333
perQueryKg = energyPerQueryKWh × grid[region].kgPerKWh
kg_co2e_estimated = tokens × perQueryKg
estimate_status = "demonstration_only"
removal_status = "not_retired"

tokens must parse as a finite, non-negative number. The implementation floors it and then caps it at 1e12: tokens = Math.min(Math.floor(parsedTokens), 1e12).

Estimate versus removal. kg_co2e_estimated is modeled emissions. The endpoint does not emit a removal amount or retirement identifier; any CDR figure is an explicitly labelled procurement estimate.

Worked example: region=eu_avg

For model=gpt-4-class, region=eu_avg, and tokens=10000, the selected row is 0.231 kg/kWh.

perQueryKg = 0.009333333 × 0.231
	            = 0.002156 kg/query-equivalent workload
kg_co2e_estimated = 10000 × perQueryKg
	                    = 21.56 kg
removal_status    = "not_retired"

The response also returns grid_intensity_g_per_kwh: 231 and grid_intensity_source: "EEA 2023 final".

The removed amount follows the measured amount

The attestation contract keeps modeled emissions separate from any purchased or retired removal. It returns estimate_status: "demonstration_only" and removal_status: "not_retired"; a procurement estimate is not a retirement record.

kg_co2e_estimatedRegion-aware estimate for this request, in kg CO₂e.
estimate_statusExplicitly demonstration_only.
removal_statusExplicitly not_retired.

This page documents the fields emitted by the attestation route. The portfolio page remains the source for the verified project list and live GET /api/co2-removals?status=verified inventory; no new removal query runs here.

A deterministic hash with a public round-trip

Before the response is persisted, the route builds a disclosureCore containing the request values, calculated amounts, issue timestamp, and methodology version. canonicalize recursively sorts object keys and emits JSON without whitespace. The receipt hash is then h_ plus the SHA-256 digest of that canonical string.

disclosureCore = {
  model,
  region,
  tokens,
  kg_co2e_estimated,
  estimate_status,
  removal_status,
  issued_at,
  methodology_version
}
receipt.hash = "h_" + SHA256(canonicalize(disclosureCore))

The response's receipt carries hash, type payload_integrity_receipt, and an absolute receipt.verifyUrl. When the database is available, the payload is stored in ai_receipt_certificates with source inference-attest and a server created_at timestamp; the response may also include receipt.attached_at.

Opening the verify URL in a browser renders the existing /verify proof surface. Its client requests /verify/:hash with Accept: application/json, receives the stored payload and integrity envelope, and renders the same fields for inspection. It checks canonical payload/hash round-tripping only; it does not prove physical removal.