Agent Skill
2/7/2026

gridstatus-api

This skill should be used when the user asks to "get electricity data", "query grid data", "get LMP prices", "fetch load data", "get fuel mix", "query ERCOT data", "query CAISO data", "query PJM data", "get electricity prices", "analyze grid operations", "get ISO data", or mentions electricity market data (load, generation, pricing, LMP, fuel mix, ancillary services, etc.).

M
misterclean
2GitHub Stars
2Views
npx skills add MisterClean/claude-plugins

SKILL.md

Namegridstatus-api
DescriptionThis skill should be used when the user asks to "get electricity data", "query grid data", "get LMP prices", "fetch load data", "get fuel mix", "query ERCOT data", "query CAISO data", "query PJM data", "get electricity prices", "analyze grid operations", "get ISO data", or mentions electricity market data (load, generation, pricing, LMP, fuel mix, ancillary services, etc.).

name: gridstatus-api description: This skill should be used when the user asks to "get electricity data", "query grid data", "get LMP prices", "fetch load data", "get fuel mix", "query ERCOT data", "query CAISO data", "query PJM data", "get electricity prices", "analyze grid operations", "get ISO data", or mentions electricity market data (load, generation, pricing, LMP, fuel mix, ancillary services, etc.). version: 1.3.0

GridStatus API Skill

Query electricity grid data from US Independent System Operators (ISOs) using the GridStatus.io API. Access real-time and historical data for load, pricing (LMP), generation, fuel mix, and more.

Quick Start

IMPORTANT: Always use the Python SDK. The direct curl API has issues with date filtering on the free tier and returns stale sample data. The Python SDK correctly handles all parameters.

Setup

  1. Install SDK (use uv for isolation):
cd /tmp && uv venv -q && source .venv/bin/activate && uv pip install gridstatusio pandas -q
  1. API Key: Check for GRIDSTATUS_API_KEY in the user's .env file. If not present, instruct the user to:

  2. Query data:

import os
os.environ['GRIDSTATUS_API_KEY'] = 'key_from_dotenv'

from gridstatusio import GridStatusClient
client = GridStatusClient()

df = client.get_dataset(
    dataset="isone_fuel_mix",
    start="2026-01-25",
    end="2026-01-26",
    limit=100
)
print(df.tail())

Free tier limit: 500,000 rows per month. Always use limit parameter.

Supported ISOs

ISORegionKey Datasets
ERCOTTexasercot_load, ercot_spp_*, ercot_fuel_mix
CAISOCaliforniacaiso_load, caiso_lmp_*, caiso_fuel_mix
PJMMid-Atlantic/Midwestpjm_load, pjm_lmp_*, pjm_standardized_*
MISOMidwestmiso_load, miso_lmp_*
NYISONew Yorknyiso_load, nyiso_lmp_*
ISO-NENew Englandisone_load, isone_lmp_*, isone_fuel_mix
SPPSouthwest/Centralspp_load, spp_lmp_*

See references/datasets-by-iso.md for complete dataset catalog.

Standard Query Template

Use this template for all queries. Run in a Python heredoc:

cd /tmp && source .venv/bin/activate && python3 << 'EOF'
import os
os.environ['GRIDSTATUS_API_KEY'] = 'YOUR_KEY_HERE'

from gridstatusio import GridStatusClient
client = GridStatusClient()

df = client.get_dataset(
    dataset="DATASET_NAME",
    start="YYYY-MM-DD",
    end="YYYY-MM-DD",
    limit=100
)
print(df.to_string())
EOF

Common Query Patterns

Current Fuel Mix (What's generating now?)

df = client.get_dataset(
    dataset="isone_fuel_mix",  # or ercot_fuel_mix, caiso_fuel_mix
    start="2026-01-25",
    end="2026-01-26",
    limit=500
)
latest = df.iloc[-1]
total = latest[['coal','hydro','natural_gas','nuclear','oil','solar','wind','wood','refuse','other']].sum()
print(f"Oil: {latest['oil']:.0f} MW ({latest['oil']/total*100:.1f}%)")

System Load

df = client.get_dataset(
    dataset="pjm_load",
    start="2026-01-25",
    end="2026-01-26",
    timezone="US/Eastern",
    limit=100
)
print(f"Current load: {df.iloc[-1]['load']:,.0f} MW")

Electricity Prices (LMP)

df = client.get_dataset(
    dataset="ercot_spp_real_time_15_min",
    start="2026-01-25",
    end="2026-01-26",
    filter_column="location",
    filter_value="HB_HOUSTON",
    limit=100
)
print(f"Houston price: ${df.iloc[-1]['spp']:.2f}/MWh")

Zone-Specific Load (Standardized Datasets)

df = client.get_dataset(
    dataset="pjm_standardized_hourly",
    start="2026-01-25",
    end="2026-01-26",
    timezone="market"
)
# Zone data in columns: df['load.comed'], df['load.aep'], etc.
print(f"ComEd load: {df.iloc[-1]['load.comed']:,.0f} MW")

Dataset Discovery

Check Dataset Metadata (date range, columns)

# Get dataset info including available date range
import requests
import os

api_key = os.environ.get('GRIDSTATUS_API_KEY')
r = requests.get(f"https://api.gridstatus.io/v1/datasets/pjm_load",
                 headers={"x-api-key": api_key})
meta = r.json()
print(f"Available: {meta['earliest_available_time_utc']} to {meta['latest_available_time_utc']}")
print(f"Columns: {[c['name'] for c in meta['all_columns']]}")

List Datasets

client.list_datasets(filter_term="ercot")  # Search by keyword
datasets = client.list_datasets(filter_term="fuel_mix", return_list=True)

Dataset naming convention: {iso}_{data_type}_{frequency}

  • ercot_load - ERCOT system load
  • caiso_lmp_real_time_5_min - CAISO 5-minute real-time LMPs
  • pjm_lmp_day_ahead_hourly - PJM day-ahead hourly LMPs

Energy Calculations

Load (MW) measures instantaneous power. Energy (MWh) = power x time.

Data FrequencyEnergy FormulaExample
5-minuteenergy_MWh = load_MW * (5/60)100,000 MW x 0.0833 = 8,333 MWh
15-minuteenergy_MWh = load_MW * (15/60)100,000 MW x 0.25 = 25,000 MWh
Hourlyenergy_MWh = load_MW * 1100,000 MW x 1 = 100,000 MWh
# Total energy for a period (5-min data)
total_mwh = (df['load'] * (5/60)).sum()
total_gwh = total_mwh / 1000

Query Parameters Reference

ParameterTypeDescription
datasetstrRequired. Dataset ID (e.g., ercot_load)
startstrStart date (YYYY-MM-DD or ISO format)
endstrEnd date
limitintMax rows to return
timezonestr"market" for ISO local time, or "US/Central" etc.
filter_columnstrColumn to filter on
filter_valuestr/listValue(s) to match
filter_operatorstr=, !=, >, <, >=, <=, in
resamplestrAggregate frequency ("1 hour", "1 day")
resample_functionstrmean, sum, min, max

See references/api-reference.md for complete documentation.

Troubleshooting

IssueCauseFix
Old/stale data returnedUsing curl directlyUse Python SDK instead - curl has date filtering issues on free tier
401 UnauthorizedInvalid/missing API keyCheck GRIDSTATUS_API_KEY is set correctly
Empty DataFrameDate range outside coverageCheck dataset metadata for available date range
ModuleNotFoundErrorSDK not installedRun: cd /tmp && uv venv -q && source .venv/bin/activate && uv pip install gridstatusio pandas -q
"Unknown column" errorWrong filter columnZone data is in columns after fetch, not filterable. Use df['load.comed']
429 Rate LimitedToo many requestsSDK auto-retries with backoff

Why Not curl?

The direct HTTP API has a critical issue on the free tier: date parameters are ignored and it returns sample data from years ago. The Python SDK correctly handles date filtering and returns current data.

If you must use curl (e.g., for dataset metadata), it works for non-query endpoints:

# This works - metadata endpoint
curl -s -H "x-api-key: $GRIDSTATUS_API_KEY" \
  "https://api.gridstatus.io/v1/datasets/pjm_load"

# This returns stale data - query endpoint has issues
curl -s -H "x-api-key: $GRIDSTATUS_API_KEY" \
  "https://api.gridstatus.io/v1/datasets/pjm_load/query?start=2026-01-25"  # BROKEN

Additional Resources

Reference Files

  • references/datasets-by-iso.md - Complete dataset catalog by ISO
  • references/api-reference.md - Full API parameter documentation
  • references/common-queries.md - Ready-to-use query patterns

Example Files

  • examples/python-query.py - Python SDK examples
Skills Info
Original Name:gridstatus-apiAuthor:misterclean