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.1.tar.gz (23.3 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.1-py3-none-any.whl (20.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: ercot-0.1.1.tar.gz
  • Upload date:
  • Size: 23.3 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.1.tar.gz
Algorithm Hash digest
SHA256 5edf3f4cbf46d51befe7ef0a30d82202cce39c2e6684f7bbcdfd706f4f659165
MD5 9777933642186dad49ec4a43e7258947
BLAKE2b-256 5caafc66e14fce98b8b4792d2f5f1ad3349f7b795b8bfe76dc0c5ebbc0c2cbcd

See more details on using hashes here.

File details

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

File metadata

  • Download URL: ercot-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 20.0 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 00795bd83bf2931b48a5338bf6894b73eacaea1e57821393201aef191ad1f746
MD5 df488cc6f7ef09b3d1390cf273617885
BLAKE2b-256 5b02b1e4330eac8666835cd4e498976f119445693b9cecdcf2eb0df9df261a2f

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