MeterCall Offset — dev docs
Embedded renewable energy credit retirement on every API + RPC call. Fractional cents per call, verifiable receipts, enterprise-grade ESG compliance — from the same tollbooth your traffic already passes through.
Overview
Every call your agent, backend, or smart-contract client makes through MeterCall consumes real electricity — server compute, network transit, and (for chain calls) downstream gas. We publish the per-call energy numbers, price them at grid REC cost, mark them up transparently 2×, and retire a proportional renewable energy credit on your behalf. Opt-in. No subscription. One toggle.
Competitors like Watershed, Persefoni, and Sweep help you account for carbon. They can't retire RECs on every API call your software makes. We can — because the calls already pass through us.
Energy model
All figures are published. Sources cited below. Numbers are intentionally conservative (we'd rather over-retire than under).
| Call type | Wh / call | kWh / call | Wholesale REC cost | Retail (2×) |
|---|---|---|---|---|
api_call | 0.4 | 0.0004 | $0.00005 | $0.0001 (0.01¢) |
router_quote | 1.2 | 0.0012 | $0.00015 | $0.0003 (0.03¢) |
bridge | 2.5 | 0.0025 | $0.0003125 | $0.000625 (0.0625¢) |
Sources
- Fly.io 2024 energy transparency report — 0.3–0.5 Wh / request for small compute → we picked 0.4 Wh.
- Cloudflare green compute 2023 figures — 1–2 Wh for cross-datacenter routing → 1.2 Wh for multi-chain router quote.
- Etherscan / L2Beat 2025 tx-energy estimates — bridge calls aggregate a signed tx + downstream RPC + chain gas → 2.5 Wh.
- US EIA 2024 grid average — 0.86 lbs CO₂ / kWh (0.39 kg / kWh).
- NREL Q1 2026 US REC spot — ~$0.125 / kWh-equivalent (national average).
Pricing & markup
We charge exactly 2× the wholesale REC price. Here's the split:
- 1× wholesale — the actual REC we retire on the registry.
- 0.5× verification — registry fees, retirement proof, third-party audit.
- 0.5× MeterCall green fund — grant pool for efficiency R&D on the platform (lower per-call energy, direct wind/solar PPAs, etc). Published quarterly.
rec_usd_per_wh_retail on /v1/offset/stats.Endpoints
curl "https://metercall.ai/v1/offset/estimate?api_calls=1000000&bridge_calls=5000&router_quotes=20000"
# →
{
"ok": true,
"total_wh": 418000.0,
"total_usd": 104.5,
"breakdown": {
"api": { "wh": 400000, "usd": 100.0 },
"bridge": { "wh": 12500, "usd": 3.125 },
"router": { "wh": 24000, "usd": 6.0 }
},
"rec_units": 0.418,
"energy_model": { "api_call": 0.4, "bridge": 2.5, "router_quote": 1.2 }
}
curl -X POST https://metercall.ai/v1/offset/purchase \
-H "content-type: application/json" \
-d '{"amount_usd": 50, "wallet_or_stripe_ref": "acme-corp"}'
# →
{
"ok": true,
"offset_id": "a3c1f9e0b7a4",
"rec_id": "REC-PATCH-4F91A0C2EE",
"provider": "Patch.io",
"registry": "patch.io",
"wh_offset": 200000,
"co2_kg_avoided": 78,
"usd": 50,
"retired_at": "2026-04-17T18:22:10.000Z",
"receipt_url": "/v1/offset/receipt/a3c1f9e0b7a4"
}
call_id. Set auto=true to charge + retire; auto=false returns the estimate only.curl -X POST https://metercall.ai/v1/offset/per-call \
-H "content-type: application/json" \
-d '{"call_id":"req_abc","endpoint":"/v1/bridge/swap","auto":true}'
daily_cap_usd).curl -X POST https://metercall.ai/v1/offset/subscribe \
-H "content-type: application/json" \
-d '{"wallet_or_user":"0xabc...","auto_offset":true,"daily_cap_usd":5}'
reachable=false and route to the next provider in the round-robin.Provider integrations
Round-robin across the public registries and carbon-removal APIs. Each provider flips from stub to live the moment its env var is present. Zero code changes.
| Provider | Registry | Env var | Status |
|---|---|---|---|
| Patch.io | patch.io | PATCH_API_KEY | public API — wire-ready |
| CNaught | cnaught.com | CNAUGHT_KEY | public API — wire-ready |
| Watershed | watershed.com | WATERSHED_API_KEY | enterprise only |
| Climate Impact Partners | climateimpact.com | CIP_API_KEY | enterprise / legacy |
| Puro.earth | puro.earth | PURO_API_KEY | carbon-removal registry |
| Regen Network | regen.network | REGEN_API_KEY | on-chain REC tokens |
| KlimaDAO | klimadao.finance | KLIMA_API_KEY | on-chain carbon market |
| Verra / Gold Standard | registry | (verification only) | cross-check of retired IDs |
BYO REC portfolio
Enterprise customers with an existing REC pool (from Watershed, CIP, etc.) can point MeterCall at it. We'll retire against your portfolio instead of buying spot. Set OFFSET_PORTFOLIO_ID and OFFSET_PORTFOLIO_PROVIDER and the gateway will route retirements to your registry account directly.
Auto-offset subscription
Instead of retiring on every single call (which would add a network hop), subscribe once:
POST /v1/offset/subscribe
{
"wallet_or_user": "acme-corp",
"auto_offset": true,
"daily_cap_usd": 10
}
A server-side bot (internally Bot #26) runs every 60 minutes, sums each subscriber's pending energy, and retires one batch REC up to the daily cap. Receipts are still per-subscriber.
Retirement receipts
Each receipt has:
offset_id— MeterCall-side ID (12-char sha256 prefix, deterministic).rec_id— the provider-side retirement ID. Cross-checkable on their registry.provider,registry— which issuer retired the REC.wh_offset,kwh_offset,co2_kg_avoided.mode—stub(dev) orlive(provider env var set).retired_at(ISO-8601) and areceipt_url.
On-chain attestation (optional)
For crypto-native teams: every retirement receipt can be anchored on-chain through /v1/bridge/attest, which writes to Arweave or creates an EAS attestation on Base. One call; the attestation transaction hash is appended to the receipt.
POST /v1/bridge/attest
{
"kind": "rec_retirement",
"offset_id": "a3c1f9e0b7a4",
"chain": "base"
}
Enterprise invoicing
Monthly invoice rolls every retirement into one line item: "MeterCall REC retirement — N kWh — $X.XX". Attach ?invoice=2026-04 to /v1/offset/receipts for a filterable feed. Audit-ready CSV export planned for May.
SDK
Drop /sdks/offset.js anywhere — UMD, no deps, browser + Node:
<script src="/sdks/offset.js"></script>
<script>
MeterCallOffset.estimate({ api_calls: 1e6, bridge_calls: 5000, router_quotes: 20000 })
.then(q => console.log(q.total_usd));
</script>