API REFERENCE
The buildout, as your agent calls it.
An agent-first, source-cited data layer for the US buildout. Two transports, one contract — call it from MCP or REST and get identical, cited JSON. The authoritative, machine-readable reference is always the live /v1/capabilities and each tool's describe schema.
The loop
Designed so an agent never has to guess:
- discover —
list_capabilitieslists every data point + how they join (anchors). - describe — each tool's schema returns its exact filters, group-bys, measures, and what it does not answer.
- query — filters +
group_by+ server-sideorder_by/top_n→ cited rows + summary. - verify —
get_source_evidencere-opens the raw file, re-hashes it (SHA-256), and returns the literal source cell.
Two surfaces, one contract
| Surface | Endpoint |
|---|---|
| Agent discovery card | GET /.well-known/agent.json |
| MCP discovery | GET /.well-known/mcp |
| MCP (streamable-http) | https://api.exascale.build/mcp |
| REST — discover | GET /v1/capabilities |
| REST — schema | GET /v1/power/capacity/schema |
| REST — query | POST /v1/power/capacity/query |
| REST — evidence | POST /v1/evidence/source-row |
Point an agent at the discovery card and it gets the whole map — endpoints, capabilities, and auth posture — in one GET.
Capabilities
| Data point | What it answers | |
|---|---|---|
power.capacity | Operating / planned / retired generator capacity (MW) — EIA-860M | live |
power.generation | Net generation (MWh) by fuel, state, BA — EIA-923 | live |
power.capacity_factor | How hard a fleet runs — generation ÷ (capacity × hours), cited to both sources | live |
power.demand | Hourly electricity demand (MW) by balancing authority — EIA-930 | live |
power.retail_sales | Annual retail sales (MWh), revenue, and customers by state & sector — EIA-861 | live |
| AI infra · Space · Robotics | The machine-economy packs, on the power substrate | rolling out |
A query, and what comes back
curl -X POST https://api.exascale.build/v1/power/capacity/query \
-H 'content-type: application/json' \
-d '{"group_by":["state"],"order_by":"nameplate_mw","top_n":3}'
{
"as_of": "2026-04-01",
"summary": { "group_count": 51, "totals": { "nameplate_mw": 1392666.4 } },
"rows": [
{ "group": {"state":"TX"}, "metrics": {"nameplate_mw": 200429.4},
"lineage": {"citation_ref": "c1"} }
],
"citations": { "c1": { "source_rows_count": 2437,
"verify": { "source_id":"energy.eia.eia860m", "source_file":"april_generator2026.xlsx",
"sheet":"Operating", "source_row":26, "raw_file_sha256":"ec15…",
"as_of":"2026-04-01" } } }
}
Pass that verify object to /v1/evidence/source-row and the response includes "hash_verified": true with the literal row values — proof, in one call.
Honesty by design
Each tool declares what it won't answer (e.g. capacity is MW, not generation MWh), so your agent declines out-of-scope questions instead of fabricating. Results also carry scope notes on known traps (cumulative vs. flow, region scope, signed measures). Defaults are sensible (current operating fleet, US-only) and never gate what you can reach.
Troubleshooting
Errors are designed to tell an agent what to do next, not just fail:
- 429 — rate limited. You hit a fair-use limit; the response includes
retry_after(seconds). Back off and retry. - 400 — invalid query. The error names the offending parameter and the allowed values; call the tool's
describe/schemafor valid filters, group-bys, and measures. - Empty result. Your filters matched no rows — widen them, or check the data point's scope in
describe. Defaults are the current operating fleet, US-only. - Evidence won't verify. A
raw_hash_mismatchorcitation_not_servederror means the snapshot was superseded — re-query for the currentas_ofand pass the freshverifyhandle. - Connection / health. Endpoint is
https://api.exascale.build/mcp(streamable HTTP, no auth). Health check:GET https://api.exascale.build/v1/health.
Still stuck? Email team@exascale.build.