Docs API reference

Power Retail Sales API v1

Generated from core.contract.describe_power_retail_sales_v1() and checked fixture-backed examples. Do not hand-edit the example JSON files.

Capability

What It Can Answer

Represented Facts

Data Point Contract

Does not answer:

REST Surface

MCP Surface

Local MCP Setup

Some MCP clients launch servers from the user's home directory or ignore a configured cwd. Use uv run --directory so the server always starts from the repository project.

{
  "command": "uv",
  "args": [
    "run",
    "--directory",
    "/absolute/path/to/OSINT",
    "python",
    "-m",
    "core.mcp_server"
  ]
}

Leave EXASCALE_PARQUET_BASE / EXASCALE_RAW_BASE unset: the one server hosts every data point's tools, and with no override it resolves each block's promoted snapshots and raw archive from the repository layout. Setting either env var points ALL tools at one directory — a per-block path breaks every other block's tools. They exist only for single-source sandboxes and tests.

Request Schema

Filters:

Group by:

Date range parameters:

Controls:

Ranking (how order_by / top_n / order join — order_by ranks groups by a metric, never a group_by dimension; top_n needs both a group_by and an order_by):

{
  "no_ranking": "Omit order_by and top_n to return all groups in group-key order.",
  "order": {
    "default": "desc",
    "valid_values": [
      "desc",
      "asc"
    ]
  },
  "order_by": {
    "accepts": "one of output.metrics",
    "note": "Ranks the groups by a metric (a measure). Not a group_by dimension \u2014 rows already come back grouped by each group_by field.",
    "requires": [
      "group_by"
    ],
    "valid_values": [
      "sales_mwh",
      "revenue_thousand_dollars",
      "customers_count",
      "distinct_utility_count",
      "source_record_count"
    ]
  },
  "top_n": {
    "note": "Keeps the top N groups by order_by; the rest fold into one (other) remainder (additive metrics sum into it, non-additive ones are nulled) so the result still reconciles to summary.totals.",
    "requires": [
      "group_by",
      "order_by"
    ],
    "type": "positive integer"
  }
}

Output Schema

Aggregate metrics:

Metric groups:

{
  "customers": [
    "customers_count"
  ],
  "entities": [
    "distinct_utility_count"
  ],
  "records": [
    "source_record_count"
  ],
  "revenue": [
    "revenue_thousand_dollars"
  ],
  "sales_mwh": [
    "sales_mwh"
  ]
}

Response summary fields:

Accepted fact policy:

Metric metadata:

Metric Category Unit Aggregation Additive Across Groups Authoritative Total Definition
sales_mwh sales_mwh MWh sum true summary.totals.sales_mwh Sum of EIA-861 annual billed retail electricity sales (MWh) within the current result scope.
revenue_thousand_dollars revenue thousand USD sum true summary.totals.revenue_thousand_dollars Sum of EIA-861 annual retail revenue (thousand dollars) within the current result scope.
customers_count customers count sum true summary.totals.customers_count Sum of EIA-861 annual ultimate-customer counts within the current result scope.
distinct_utility_count entities count count_distinct false summary.totals.distinct_utility_count Count of distinct EIA utility IDs within the current result scope.
source_record_count records count count source records true summary.totals.source_record_count Count of normalized source rows (measure-cell atoms) contributing to the current result scope.

Rollup rules:

Detail record fields returned when include_records is true:

Row-level citation fields:

Aggregate citation fields:

Codebooks

Field Coverage Codes Examples Note
sector complete_for_served_eia861_sectors 5 residential = Residential, commercial = Commercial, industrial = Industrial, transportation = Transportation, total = In-row TOTAL block (duplicates the four sectors; explicit opt-in) Default scope is the four customer sectors; the in-row total block duplicates them and is excluded unless sector names it explicitly (an unpinned sum would double-count). Filter values are case-normalized server-side.
part complete_for_eia861_filing_parts 4 A = Bundled service (energy + delivery), B = Energy-only service (deregulated energy seller), C = Delivery-only service (wires company), D = Bundled, behind-the-meter third-party owners The file's own aggregation law (PD-026): state totals sum Parts A,B,C,D for revenue but only A,B,D for sales and customers — Part C (Delivery) re-counts energy that Part B (Energy) rows already carry. A result mixing service types carries a service_type_mix scope note with that exact remedy.
data_type complete_for_eia861_data_type_codes 2 O = Observed, I = Imputed O = Observed, I = Imputed. In the 2024 census every imputed row is one of the state-level Adjustment sentinel rows (PD-023/PD-025).
ownership complete_for_eia861_ownership_labels 10 Behind the Meter = Behind the Meter, Community Choice Aggregator = Community Choice Aggregator, Cooperative = Cooperative, Federal = Federal, Investor Owned = Investor Owned Sentinel rows (Adjustment/Withheld) carry a blank ownership, served as null.
ba_code partial_for_eia861 81 AEC = PowerSouth Energy Cooperative, AECI = Associated Electric Cooperative, Inc., AESO = Alberta Electric System Operator, AVA = Avista Corporation, AVRN = Avangrid Renewables, LLC EIA-861 reports this BA code on the utility×state row. exascale.build preserves it as source-reported data; it is not an independently validated physical BA-footprint assignment or corrected grid-operator attribution. A balancing authority is not a state. ERCO (ERCOT) lies wholly within Texas and covers ~90% of its load, but state=TX is the larger jurisdiction — it also includes non-ERCOT El Paso (WECC), the Panhandle (SPP), and East Texas (MISO), a material (~20%+) difference. Use balancing_authority_code for a grid and state for a jurisdiction; they are not interchangeable. When a phrase like 'the Texas grid' is ambiguous between the two, report both readings rather than guessing one (PD-009).

The complete machine-readable codebooks are included in capability-schema.json.

Checked Examples

Agent question Request params Checked output
What were 2024 retail sales, revenue, and customers by state and customer sector? {"data_year": 2024, "group_by": ["state", "sector"]} retail-sales-by-state-and-sector.json
Which utilities sold retail power in Maine, and how much? {"group_by": ["eia_utility_id", "utility_name"], "state": "ME"} utility-sales-in-maine.json
How do Maine's retail sales split by filing part and service type? {"group_by": ["part", "service_type"], "state": "ME"} service-type-structure.json
What state-level adjustment corrections does the Maine census carry, by sector? {"group_by": ["sector"], "is_adjustment": true, "state": "ME"} adjustment-corrections.json
Return one Maine retail-sales atom with a cell-level citation. {"include_records": true, "limit": 1, "state": "ME"} retail-detail-with-citation.json
Verify the raw workbook row behind a returned citation citations[ref].verify (aggregate) or records[0].citation (detail) source-row-evidence.json
Dogfood the tool sequence as an agent list -> describe -> query -> evidence agent-dogfood-transcript.json

The checked schema output is capability-schema.json.

Agent Workflow

  1. Call list_capabilities_v1 and select power.retail_sales.
  2. Call describe_power_retail_sales_v1 to inspect valid filters, groupings, metrics, and citation fields.
  3. Call query_power_retail_sales_v1 with bounded JSON params.
  4. If the answer needs proof, pass a returned row-level citation object to get_source_evidence_v1.
  5. Answer with the resolved as_of and relevant citations. Present returned metrics as authoritative for their declared source, snapshot, grain, and aggregation.
Generated from the tested API contract. Compare with the live capability map ↗