API reference

Quickstart

Vatio gives you clean, normalized US grid data — prices, demand and the full fuel mix — for dashboards, price-aware automation, storage/BESS analytics, forecasting and research, without wrangling seven different operator feeds. It's REST over HTTPS; every response is JSON (CSV on history endpoints). One uniform shape covers all seven US grids — swap the {iso} path segment. The base URL is http://localhost:8000. Grab your API key from the dashboard, then send it on every request as the X-API-Key header.

Try it right now — no key needed
bash
# a live snapshot, no account required (15-min delayed)
$ curl http://localhost:8000/v1/sample
With your key — pick your language
# create a free key in the dashboard, then pull any grid
$ curl http://localhost:8000/v1/caiso/lmp/realtime?hub=SP15 \
    -H "X-API-Key: vt_live_…"
import requests

r = requests.get(
    "http://localhost:8000/v1/caiso/lmp/realtime",
    params={"hub": "SP15"},
    headers={"X-API-Key": "vt_live_…"},
)
print(r.json())
const r = await fetch("http://localhost:8000/v1/caiso/lmp/realtime?hub=SP15", {
  headers: { "X-API-Key": "vt_live_…" },
});
console.log(await r.json());
# any history endpoint straight into a DataFrame via ?format=csv
import io, requests, pandas as pd

url = "http://localhost:8000/v1/ercot/load/history?format=csv"
r = requests.get(url, headers={"X-API-Key": "vt_live_…"})
df = pd.read_csv(io.StringIO(r.text))

The machine-readable schema is at /openapi.json.

Authentication

Every request is authenticated with your secret API key, sent as the X-API-Key header:

http
X-API-Key: vt_live_…

Create, reveal and revoke keys in your dashboard — each key is shown once, so store it securely. Keep it secret: anyone with your key can spend your quota.

Plans & limits

Your plan controls four things: throughput (requests per second — the main lever), how fresh the data is (free is 15-minutes delayed; paid is live), how far back history goes, and a generous monthly fair-use cap. See pricing.

PlanPriceRateDataHistoryCalls / mo
free$05 / s15-min delayed30 days10,000
pro$2930 / sLive2 yearsFair use

Track your month-to-date usage any time in your dashboard.

Errors & rate limits

Standard HTTP status codes; the body is always {"detail": "…"}. Exceed your per-second rate and you'll get 429 — back off and retry.

CodeMeaning
400Bad request — e.g. an unknown hub.
401Missing or invalid API key / session token.
402Pro feature (nodal LMP, DART, spreads) requested with a Free key.
404No data available yet for that query.
422Invalid parameters (e.g. password under 8 chars).
429Rate limit exceeded for your plan.
503Billing not configured (Stripe keys absent).

Every authenticated data response carries your limits in headers: X-RateLimit-Limit-Second (your per-second rate), X-RateLimit-Limit (monthly cap) and X-RateLimit-Remaining — poll them instead of guessing.

Grids & coverage

Every data endpoint is the same shape across grids — just swap the {iso} path segment. Authenticate with your API key (X-API-Key). Timestamps are UTC; prices are $/MWh, power is MW. Free callers see data ≥ 15 min old.

{iso}OperatorPrices (LMP)Nodal + DARTDemandFuel mix
caisoCalifornia ISO✅ 5-min✅ RT + DA✅ 5-minhourly
nyisoNew York ISO✅ 5-minsoonhourlyhourly
ercotERCOT (Texas)rolling outsoonhourlyhourly
pjmPJMrolling outsoonhourlyhourly
misoMidcontinent ISOrolling outsoonhourlyhourly
isoneISO New Englandrolling outsoonhourlyhourly
sppSouthwest Power Poolrolling outsoonhourlyhourly

Data sources & cadence

Prices (LMP) come from each operator's own real-time feed and are live for CAISO and NYISO today (5-minute intervals). The other grids return 404 on price endpoints until their feed lands — create a key now and they switch on with no migration. Demand and the full fuel mix come from the U.S. EIA-930 feed, updated hourly for every grid (CAISO demand is 5-minute, from its native feed). EIA publishes with a few hours' lag, so treat demand and fuel mix as an hourly series, not a sub-minute tick. Hubs per grid are listed by /v1/public/isos.

Prices (LMP)

get/v1/{iso}/lmp/realtimeAPI key

Latest real-time price (RTD LMP) for a hub.

Query
ParamTypeNotes
hubstringDefaults to the ISO's primary hub. CAISO: NP15, SP15, ZP26.
Request
bash
$ curl http://localhost:8000/v1/caiso/lmp/realtime?hub=SP15 \
    -H "X-API-Key: vt_live_…"
Response 200
{
  "iso": "caiso",
  "hub": "SP15",
  "market": "RTD",
  "interval_start": "2026-06-27T18:05:00Z",
  "price": -15.63,
  "unit": "$/MWh"
}
get/v1/{iso}/lmp/historyAPI key

Historical price series for a hub, oldest-first. Window is clamped to your plan's history depth.

Query
ParamTypeNotes
hubstringDefaults to the ISO's primary hub.
startISO-8601Default: 24h before end.
endISO-8601Default: now (minus plan delay).
limitint1–5000, default 500.
formatstringjson (default) or csv.
Response 200
{
  "iso": "caiso",
  "hub": "SP15",
  "market": "RTD",
  "unit": "$/MWh",
  "delayed_minutes": 0,
  "count": 2,
  "data": [
    {
      "interval_start": "2026-06-27T18:20:00Z",
      "price": -16.71
    },
    {
      "interval_start": "2026-06-27T18:25:00Z",
      "price": -17.04
    }
  ]
}

Demand

get/v1/{iso}/load/realtimeAPI key

Latest system demand (actual + forecast), in MW. interchange_mw is net interchange with neighboring grids — EIA sign: positive = net exports, negative = net imports (net imports are why generation ≠ demand). Hourly via EIA-930.

Response 200
{
  "iso": "ercot",
  "interval_start": "2026-06-27T18:00:00Z",
  "actual_mw": 67160.0,
  "forecast_mw": 66890.0,
  "interchange_mw": -1240.0,
  "unit": "MW"
}
get/v1/{iso}/load/historyAPI key

Historical demand series. Same start / end / limit / format params as /lmp/history.

Response 200
{
  "iso": "ercot",
  "unit": "MW",
  "delayed_minutes": 0,
  "count": 168,
  "data": [
    {
      "interval_start": "2026-06-27T17:00:00Z",
      "actual_mw": 66740.0,
      "forecast_mw": 66510.0
    }
  ]
}

Generation (fuel mix)

Generation by fuel type, in MW — the full mix (gas, nuclear, coal, hydro, wind, solar, battery, oil, other), hourly for every grid. Every response also carries derived metrics built for storage and forecasting work: renewable_mw / renewable_pct (solar + wind), net_load_mw (demand − solar − wind — the net-load curve), and carbon_intensity in gCO₂/kWh.

get/v1/{iso}/generation/realtimeAPI key

Latest generation mix for a grid.

Response 200
{
  "iso": "ercot",
  "interval_start": "2026-06-27T16:00:00Z",
  "mix": {
    "nuclear": 4900,
    "coal": 8200,
    "gas": 38000,
    "wind": 9100,
    "solar": 14500,
    "battery": 1200,
    "other": 600
  },
  "total_mw": 76500,
  "renewable_mw": 23600,
  "renewable_pct": 30.8,
  "net_load_mw": 43560,
  "carbon_intensity": 320.8,
  "unit": "MW"
}

Net load = demand − (solar + wind), the series most forecasters and battery operators model against. Carbon intensity is direct fossil-combustion CO₂ (coal, gas, oil) per MWh of total generation, in gCO₂/kWh — non-fossil sources count as zero. Both appear on the history endpoint too, and as columns in the CSV.

get/v1/{iso}/generation/historyAPI key

Historical fuel-mix series. Accepts start / end / limit / format=csv (one column per fuel).

Response 200
{
  "iso": "ercot",
  "fuels": [
    "nuclear",
    "coal",
    "gas",
    "wind",
    "solar",
    "battery",
    "other"
  ],
  "unit": "MW",
  "delayed_minutes": 0,
  "count": 24,
  "data": [
    {
      "interval_start": "2026-06-27T15:00:00Z",
      "mix": {
        "gas": 37500,
        "wind": 9400,
        "solar": 15200
      },
      "renewable_mw": 24600,
      "net_load_mw": 42100,
      "carbon_intensity": 259.7
    }
  ]
}

Renewables (solar + wind)

A convenience view of the two variable renewables, derived from the fuel mix.

get/v1/{iso}/renewables/realtimeAPI key
Response 200
{
  "iso": "caiso",
  "interval_start": "2026-06-27T18:05:00Z",
  "solar_mw": 19672.0,
  "wind_mw": 3261.0,
  "unit": "MW"
}
get/v1/{iso}/renewables/historyAPI key

Historical solar + wind series. Same params as /lmp/history (incl. format=csv).

Nodal & trader data Pro

Node-level LMP with its full component breakdown (energy, congestion, loss, and CAISO's GHG adder), day-ahead prices, the DART spread, and cross-location spreads — the data batteries (BESS) and traders actually act on. Nodal coverage today: CAISO (trading hubs + default load-aggregation points). Node discovery is open on any plan; nodal prices, DART and spreads require Pro (else 402).

get/v1/{iso}/nodesAPI key

Find the pricing node your asset sits on.

Query
ParamTypeNotes
searchstringCase-insensitive match on node id or name.
limitint1–1000, default 100.
Response 200
[
  {
    "iso": "caiso",
    "node_id": "TH_SP15_GEN-APND",
    "name": "SP15 Trading Hub",
    "zone": "SP15",
    "node_type": "HUB"
  }
]
get/v1/{iso}/lmp/nodalPro

Latest nodal LMP with components. price = energy + congestion + loss + ghg.

Query
ParamTypeNotes
nodestringRequired. A PNode id from /nodes.
marketstringRTM (5-min, default) or DAM (hourly day-ahead).
Response 200
{
  "iso": "caiso",
  "node_id": "TH_SP15_GEN-APND",
  "market": "RTM",
  "interval_start": "2026-07-01T12:10:00Z",
  "price": 13.4,
  "energy": 12.06,
  "congestion": 1.66,
  "loss": -0.32,
  "ghg": 0.0,
  "unit": "$/MWh"
}
get/v1/{iso}/lmp/nodal/historyPro

Nodal series with components, oldest-first. Same node/market params, plus start/end/limit/format like /lmp/history.

get/v1/{iso}/lmp/dartPro

The DART spread — each real-time interval matched to its hour's day-ahead price. spread = real_time − day_ahead.

Query
ParamTypeNotes
nodestringRequired. A PNode id.
start/end/limit/formatAs /lmp/history.
Response 200
{
  "iso": "caiso",
  "node_id": "TH_SP15_GEN-APND",
  "unit": "$/MWh",
  "count": 1,
  "data": [
    {
      "interval_start": "2026-07-01T12:00:00Z",
      "day_ahead": 20.12,
      "real_time": 13.69,
      "spread": -6.43
    }
  ]
}
get/v1/spreadsPro

Latest price spread between two nodes — same or cross-ISO. spread = price_a − price_b.

Query
ParamTypeNotes
iso_a, astringISO + node id of location A.
iso_b, bstringISO + node id of location B.
marketstringRTM (default) or DAM.
Response 200
{
  "market": "RTM",
  "interval_start": "2026-07-01T12:10:00Z",
  "a": "caiso:TH_NP15_GEN-APND",
  "b": "caiso:TH_SP15_GEN-APND",
  "price_a": 14.87,
  "price_b": 13.4,
  "spread": 1.47,
  "unit": "$/MWh"
}
get/v1/{iso}/signalsAPI key

Derived grid signals for every ISO (open to any plan): net-load ramp, renewable share, and carbon intensity — the drivers behind price moves.

Response 200
{
  "iso": "caiso",
  "interval_start": "2026-07-01T06:00:00Z",
  "demand_mw": 27134.0,
  "net_load_mw": 22530.0,
  "net_load_ramp_mw_per_hr": -2007.0,
  "renewable_mw": 4604.0,
  "renewable_pct": 25.3,
  "carbon_intensity": 20.7
}

Output formats

All responses are JSON by default. Every */history endpoint also accepts ?format=csv for a download that drops straight into pandas or a spreadsheet:

bash
$ curl http://localhost:8000/v1/ercot/generation/history?format=csv \
    -H "X-API-Key: vt_live_…" -o ercot_generation.csv

CSV columns mirror the JSON fields (for fuel mix, one column per fuel).

Paginating long windows

History endpoints return up to 5000 rows per call (limit, default 500). For a longer window, page by time: request a range, then pass the last interval_start you got back as the next call's start, repeating until you receive fewer than limit rows. For bulk pulls, ?format=csv is the fastest path into pandas or a spreadsheet.

Preview endpoints (no key)

These power the public live dashboard and landing demo. They're 15-minute delayed and need no key — handy for a quick look before you sign up.

get/v1/public/isosno auth

Catalog of grids for the dashboard picker — slug, code, hubs, and whether prices are live.

get/v1/public/dashboard?iso=caiso&hours=24no auth

Snapshot plus series for prices, demand and the fuel mix for one grid, in a single call. iso = any slug, hours = 1–168.

get/v1/public/compare?metric=demandno auth

One metric (demand or price) across every grid, for the compare chart.

get/v1/sampleno auth

CAISO landing snapshot: hub prices plus demand, solar and wind.

Get your free key →

Vatio · real-time US grid data · API reference · status · support
Data: U.S. Energy Information Administration (EIA) & CAISO OASIS · not affiliated with or endorsed by either.
Live gridTermsPrivacyOpenAPI