Skip to main content

ERCOT market data in one line of Python — DAM/RTM prices, LMPs, load, generation, and more.

Project description

ercot

ERCOT market data in one line of Python.

A thin SDK for the ERCOT Public API that gives you Day-Ahead and Real-Time settlement point prices, LMPs, load data, generation mix, and more — all as pandas DataFrames with proper Central Prevailing Time DST handling and one-call Excel/CSV export.

import ercot as er

er.configure("you@email.com", "your-password", "your-subscription-key")

df = er.dam("LZ_HOUSTON", "2025-07-01", "2025-07-31")
er.save_xlsx(df, "houston_dam_july.xlsx")

Installation

pip install ercot

Getting Your ERCOT API Credentials

You need three things: a username (email), a password, and a subscription key. All free. Here's exactly how to get them.

Step 1: Register an Account

  1. Go to https://apiexplorer.ercot.com/
  2. Click Sign Up in the top-right corner
  3. Fill in your email address and create a password
  4. Complete the email verification (check your inbox for the confirmation link)
  5. Once verified, sign in to the API Explorer

Step 2: Subscribe to the Public API

  1. After signing in, click Products in the top navigation
  2. Click Public API to open the product page
  3. Enter a name for your subscription (e.g., "my-ercot-app") in the Subscription name field
  4. Click Subscribe
  5. Wait for your subscription to be approved (usually instant, but can take up to a few hours)

Step 3: Get Your Subscription Key

  1. After approval, click your username in the top-right corner → Profile
  2. You'll see your subscription(s) listed
  3. Click Show next to the Primary key field
  4. Copy this key — this is your subscription key (also called Ocp-Apim-Subscription-Key)

Step 4: Configure ercot

import ercot as er

# This saves your credentials to ~/.ercot/credentials.json
# so you only need to do it once.
er.configure(
    "you@email.com",          # the email you registered with
    "your-password",           # the password you created
    "your-subscription-key",   # the Primary key from Step 3
)

That's it. All subsequent calls will use the saved credentials automatically.

Alternative: Environment Variables

If you prefer not to save credentials to disk (e.g., in CI/CD or Docker):

export ERCOT_API_USERNAME="you@email.com"
export ERCOT_API_PASSWORD="your-password"
export ERCOT_API_SUBSCRIPTION_KEY="your-subscription-key"

Alternative: Pass Directly

c = er.client(
    username="you@email.com",
    password="your-password",
    subscription_key="your-key",
)
df = c.dam_spp("2025-07-01")

Quick Start

import ercot as er

# Day-Ahead prices — wide format (date + HE1..HE24 columns)
df = er.dam("LZ_HOUSTON", "2025-07-01", "2025-07-31")

# Real-Time prices — long format (one row per 15-min interval)
df = er.rtm("HB_NORTH", "2025-07-01", "2025-07-07", format="long")

# All load zones at once
df = er.dam("zones", "2025-01-01", "2025-01-31")

# Save to Excel (styled headers, alternating rows)
er.save_xlsx(df, "prices.xlsx")

# Save to CSV
er.save_csv(df, "prices.csv")

Output Formats

Wide Format (default)

One row per date per settlement point. Interval values are columns.

DAM (24 hourly intervals):

date settlement_point HE1 HE2 HE3 ... HE24
2025-07-01 LZ_HOUSTON 28.54 25.12 23.87 ... 38.91
2025-07-01 LZ_NORTH 27.10 24.03 22.95 ... 37.44

RTM (96 fifteen-minute intervals):

date settlement_point IE1 IE2 ... IE96
2025-07-01 LZ_HOUSTON 24.12 25.67 ... 35.44

Long Format

One row per interval with a CPT-aware interval_ending datetime.

DAM:

date settlement_point hour interval_ending price
2025-07-01 LZ_HOUSTON 1 2025-07-01 01:00:00-05:00 28.54
2025-07-01 LZ_HOUSTON 2 2025-07-01 02:00:00-05:00 25.12

RTM:

date settlement_point interval interval_ending price
2025-07-01 LZ_HOUSTON 1 2025-07-01 00:15:00-05:00 24.12
2025-07-01 LZ_HOUSTON 2 2025-07-01 00:30:00-05:00 25.67

DST Handling

ERCOT operates in Central Prevailing Time (CPT). ercot handles DST transitions correctly:

  • Spring forward (March): Hour Ending 03:00 is skipped. DAM has 23 intervals; RTM has 92.
  • Fall back (November): Hour Ending 02:00 repeats. ERCOT flags the second occurrence. DAM has 25 intervals; RTM has 100.

In long format, the interval_ending column is a timezone-aware timestamp (America/Chicago) with the correct UTC offset for each row — CDT intervals show -05:00, CST intervals show -06:00.


Settlement Point Shortcuts

Shortcut Expands To
'LZ_HOUSTON' Single load zone
['LZ_HOUSTON', 'HB_NORTH'] Specific list
'zones' All 8 load zones: LZ_HOUSTON, LZ_NORTH, LZ_SOUTH, LZ_WEST, LZ_AEN, LZ_CPS, LZ_LCRA, LZ_RAYBN
'hubs' All 6 trading hubs: HB_BUSAVG, HB_HOUSTON, HB_NORTH, HB_SOUTH, HB_WEST, HB_PAN
'all' All zones + hubs combined

Full API Reference

Prices

Function Description
er.dam(points, start, end, format=) DAM Settlement Point Prices (hourly)
er.rtm(points, start, end, format=) RTM Settlement Point Prices (15-min)
er.dam_lmp(start, end, points) DAM Hourly LMPs
er.rtm_lmp(start, end, points) RTM LMPs by Settlement Point (5-min)

Load

Function Description
er.system_load(start, end) Actual system load by weather zone
er.load_forecast(start, end) 7-day load forecast by model/weather zone

Generation

Function Description
er.wind_production(start, end) Wind power — actual and forecast
er.solar_production(start, end) Solar power — actual and forecast
er.fuel_mix(start, end) Generation by fuel type

Grid / Constraints

Function Description
er.dam_shadow_prices(start, end) DAM shadow prices and binding constraints
er.sced_shadow_prices(start, end) SCED shadow prices and binding constraints

Reference

Function Description
er.settlement_points_list() All settlement points and bus mapping
er.list_endpoints() List all available endpoints

Export

Function Description
er.save_xlsx(df, "file.xlsx") Formatted Excel (styled headers, alternating rows)
er.save_csv(df, "file.csv") Standard CSV export

Advanced

# Get the full client for custom queries
c = er.client()
df = c.request("fuel_mix", {"deliveryDateFrom": "2025-07-01"})

# Hit an endpoint not in the registry
df = c.raw("/np6-xxx-cd/some_endpoint", {"param": "value"})

Excel Export Features

er.save_xlsx() produces publication-quality spreadsheets:

  • Header row: Dark teal background, white bold text, centered, with borders
  • Data rows: Alternating white / light gray for readability
  • Price columns: Automatically detected (HE*, IE*, price) and formatted as $#,##0.00
  • Column widths: Auto-fitted to content
  • Frozen panes: Header row stays visible when scrolling
  • Auto-filter: Filter dropdowns on every column
  • Optional high-price highlighting: Red background for prices above a threshold
# Basic
er.save_xlsx(df, "prices.xlsx")

# Multi-sheet workbook
er.save_xlsx({
    "DAM Houston": dam_df,
    "RTM Houston": rtm_df,
    "Load": load_df,
}, "ercot_report.xlsx")

# Highlight extreme prices
er.save_xlsx(df, "prices.xlsx", highlight_high_prices=True, high_price_threshold=200)

Architecture

ercot/
├── __init__.py      # Public API — er.dam(), er.rtm(), er.save_xlsx(), etc.
├── models.py        # Constants, enums, endpoint registry, timezone
├── auth.py          # OAuth2 ROPC token management, credential storage
├── client.py        # ErcotClient — one method per endpoint, pagination
├── formatting.py    # Wide/long conversion, DST-aware datetimes
└── export.py        # CSV and formatted XLSX output

Data flow: ERCOT API → ErcotClient → DataFrame → (optional) formatting → (optional) export

No local database, no caching, no stale data. Every call hits the live API.


License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ercot-0.1.0.tar.gz (23.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ercot-0.1.0-py3-none-any.whl (19.7 kB view details)

Uploaded Python 3

File details

Details for the file ercot-0.1.0.tar.gz.

File metadata

  • Download URL: ercot-0.1.0.tar.gz
  • Upload date:
  • Size: 23.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for ercot-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3a64244cf49e74204a4a0027377c19a31f06d2c4bd08aea3719c5495e014a828
MD5 7ada18645a16dcb9e932c38ff2233ab9
BLAKE2b-256 378c476acd3a9e1df4709cc76ca4de24e55147194350d2a0ae0a8fcaefcc3e78

See more details on using hashes here.

File details

Details for the file ercot-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: ercot-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 19.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for ercot-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0594ae9e9a92cb5e64fd7b445934fcef069622756c0c809bb4a18ce5362cfef2
MD5 74b37921d7372e5b05d3baac2d0801fe
BLAKE2b-256 2738b6ecb712352835ace6877cd7142d6ac038d69cb23a74a7ece6284a6c05dc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page