Get the FREE Ultimate OpenClaw Setup Guide →

gridstatus-api

npx machina-cli add skill MisterClean/claude-plugins/gridstatus-api --openclaw
Files (1)
SKILL.md
7.6 KB

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

Source

git clone https://github.com/MisterClean/claude-plugins/blob/main/skills/gridstatus-api/SKILL.mdView on GitHub

Overview

GridStatus API lets you fetch real-time and historical electricity grid data from US ISOs (ERCOT, CAISO, PJM, and more) via GridStatus.io. It covers load, LMP pricing, generation, fuel mix, and other market metrics for grid analysis and market insights.

How This Skill Works

Use the Python SDK to authenticate with GRIDSTATUS_API_KEY, create a GridStatusClient, and call get_dataset with a dataset name, start, end, and limit. The docs emphasize using the Python SDK (not curl) for correct parameter handling and date filtering, including awareness of the free tier limits.

When to Use It

  • You need current or historical ISO-wide load data.
  • You want ISO pricing (LMP) data across regions.
  • You need fuel mix or generation composition for an ISO.
  • You’re comparing data across multiple ISOs (ERCOT, CAISO, PJM, etc.).
  • You’re setting up API access and querying data via the Python SDK (avoid curl due to reliability).

Quick Start

  1. Step 1: Install SDK (use uv for isolation): cd /tmp && uv venv -q && source .venv/bin/activate && uv pip install gridstatusio pandas -q
  2. Step 2: API Key: Check GRIDSTATUS_API_KEY in the user\'s .env file. If not present, instruct the user to: - Create account at https://www.gridstatus.io - Get API key from Settings page - Add to .env: GRIDSTATUS_API_KEY=your_key_here
  3. Step 3: Query data: 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())

Best Practices

  • Always use the Python SDK for parameter handling and date filtering.
  • Store your GRIDSTATUS_API_KEY securely (e.g., .env) and load it in your environment.
  • Respect the free tier: limit is 500,000 rows per month; always specify a limit.
  • Choose the dataset name appropriate to your ISO and metric (e.g., ercot_load, isone_fuel_mix).
  • Be mindful of timezones (use start/end and timezone parameters to align your data).

Example Use Cases

  • df = client.get_dataset(dataset='isone_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}%)")
  • 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")
  • 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")
  • 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")
  • df = client.get_dataset(dataset='caiso_fuel_mix', start='2026-01-25', end='2026-01-26', limit=100)

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers