Developer Reference

Carbon AI · B2B Attestation API

GET /api/v1/inference/attest mints a Hashbon-shaped carbon-neutral receipt for a single inference call an external AI provider ran. One request, one receipt, every gram removed against Tao's verified CDR portfolio.

Request pilot access →

Auth model

Today the endpoint is unauthenticated. The route sits outside /api/carbon-ai's per-IP rate limiter (see server.js B2B inference attestation block) because B2B callers legitimately issue at volume. The endpoint does honour the standard Express rate-limit exemption for B2B traffic.

API keys ship next. Issuance plan: request a key via the pilot intake form; once key-check middleware is enabled, keys are sent as Authorization: Bearer <key>. Keys are not yet enforced — start integrating now and add the header when key checking goes live.

All responses include Cache-Control: public, max-age=60, stale-while-revalidate=3600. URLs are stable; the response shape is the contract.

Request shape

GET /api/v1/inference/attest

Query parameters are the entire contract. The endpoint is a plain GET so it is safe to call from a browser, server, or edge worker — no body, no signature, no SDK.

Parameter Type & rules
model REQUIRED String. gpt-4-class is recognised (0.0007 kg CO₂e per query). Any other model string falls through to the widget default — the call still succeeds, the math still adds up.
region REQUIRED String. E.g. EU, US, APAC. Echoed verbatim into the receipt.
tokens REQUIRED Integer ≥ 0. Capped internally at 1e12. Drives the kg CO₂e = tokens × per-query coefficient calculation.
client_id String, optional. Echoed back on the receipt so your systems can correlate attestation IDs to your own inference logs.

Response shape

JSON object. Every receipt carries a receipt.hash derived as h_<sha256(canonicalize(disclosureCore))> (sorted-key, no-whitespace canonicalization). The matching verify page lives at /verify/<hash>.

Field Description
inference_idStable per-request ID: INF-<yyyymmdd>-<tokens>-<sha8>.
issued_atRFC 3339 timestamp the receipt was minted.
client_idEchoed back from the request, or null.
modelModel string you sent.
regionRegion string you sent.
tokensToken count used (after the 1e12 cap).
kg_co2e_estimatedEstimated emissions, kg CO₂e.
kg_co2_removedRemoved against verified CDR. Equal to kg_co2e_estimated today.
removal_project_idTao portfolio project backing the removal (e.g. TAO-UKR-HEMP-MRV-2026).
methodologyPer-query coefficient (0.0007 kg CO₂e), basis (market-based Scope 2; 0.3 kWh × PUE 1.6 × grid 0.45 kg/kWh), version (2026.1).
receipt.hashh_ + 64-hex sha256 of the canonicalized disclosureCore object.
receipt.chainReceipt chain identifier: hashbon:taoclimate:v1.
receipt.verifyUrlDirect link to the public verify page at /verify/<hash>.
receipt.attached_atServer-side timestamp the receipt was persisted (present when DB is available).

curl sample & example response

Run this against taoclimate.com. Pipe through jq for readability.

curl -sS 'https://taoclimate.com/api/v1/inference/attest?model=gpt-4-class&region=EU&tokens=10000' | jq

Example response — fixed inputs (model=gpt-4-class, region=EU, tokens=10000) so kg_co2e_estimated = tokens × 0.0007 = 7. The receipt hash below is illustrative; yours will differ because issued_at rolls daily.

{
  "inference_id": "INF-20260730-10000-abcd1234",
  "issued_at": "2026-07-30T12:00:00.000Z",
  "client_id": null,
  "model": "gpt-4-class",
  "region": "EU",
  "tokens": 10000,
  "kg_co2e_estimated": 7,
  "kg_co2_removed": 7,
  "removal_project_id": "TAO-UKR-HEMP-MRV-2026",
  "methodology": {
    "per_query_kg_co2e": 0.0007,
    "basis": "market-based Scope 2; 0.3 kWh × PUE 1.6 × grid 0.45 kg/kWh",
    "version": "2026.1"
  },
  "receipt": {
    "hash": "h_4f2c8e9a1b3d5f7c9e2a4b6d8f1c3e5a7b9d2f4c6e8a1b3d5f7c9e2a4b6d8f1c",
    "chain": "hashbon:taoclimate:v1",
    "verifyUrl": "https://taoclimate.com/verify/h_4f2c8e9a1b3d5f7c9e2a4b6d8f1c3e5a7b9d2f4c6e8a1b3d5f7c9e2a4b6d8f1c"
  }
}

Errors & caching

Errors return a JSON body with an error string. The endpoint never throws; tokens is the only field that type-checks.

CaseResponse
Missing required input 400 { "error": "missing required input: <model|region|tokens>" }
Invalid tokens 400 { "error": "invalid tokens" } — non-numeric or negative.

Successful responses include Cache-Control: public, max-age=60, stale-while-revalidate=3600. Treat the receipt as immutable once issued: if you need to reprove against a stored hash, hit receipt.verifyUrl.

CSRD / ESRS-E1 disclosure endpoint

Pair each attestation with a top-level disclosure JSON for downstream CSRD reporting. GET /api/disclosure/csed.json?queries=N returns the same shape you can paste straight into ESRS-E1 ¶ 33 (energy) and ¶ 34 (Scope 2 market-based).

curl -sS 'https://taoclimate.com/api/disclosure/csed.json?queries=100000' | jq

Example response — fixed queries=100000 so totalScope2MarketBasedKgCO2e = 70, verifiedRemovalKgCO2e = 2,555 t/yr, unitCostEUR = 7/day. Date stamps below are illustrative placeholders; the day-rolling asOf, RCPT-<yyyymmdd>-<n> and verifiedRemovalReceiptId are emitted fresh per call — capture them on your side.

{
  "framework": "CSRD",
  "standard": "ESRS E1",
  "asOf": "2026-07-30",
  "queriesPerDay": 100000,
  "totalScope2MarketBasedKgCO2e": 70,
  "methodologyVersion": "2026.1",
  "measurementBoundary": "operational energy consumption of inference workload; market-based Scope 2 over daily interval; 0.3 kWh × PUE 1.6 × grid 0.45 kg/kWh",
  "verifiedRemovalKgCO2e": 25550,
  "verifiedRemovalAttestation": "Hashbon-attested receipt",
  "verifiedRemovalReceiptId": "RCPT-20260730-100000",
  "unitCostEUR": 7,
  "unitCostBasis": "EUR/day at EUR 100 per tonne verified CDR procurement, matching widget line \"cr-line-eur-day\"",
  "currency": "EUR",
  "methodology": {
    "url": "https://taoclimate.com/ai-transparency-policy",
    "version": "2026.1"
  },
  "crossReference": {
    "label": "EU AI Act aligned disclosure cross-reference",
    "url": "https://taoclimate.com/eu-ai-act"
  },
  "certificate": {
    "hash": "h_8a1c3e5b7d9f2a4c6e8b1d3f5a7c9e2b4d6f8a1c3e5b7d9f2a4c6e8b1d3f5a7c",
    "chain": "hashbon:taoclimate:v1",
    "verifyUrl": "https://taoclimate.com/verify/h_8a1c3e5b7d9f2a4c6e8b1d3f5a7c9e2b4d6f8a1c3e5b7d9f2a4c6e8b1d3f5a7c"
  }
}

Errors return 400 { "error": "invalid queries" } for a missing or non-numeric queries parameter. Successful responses cache for public, max-age=300, stale-while-revalidate=3600.