---
name: ercot-public-data-api-ingestion
description: "How to get ERCOT Public Data API data into a pandas DataFrame and Parquet: access, the request, the format, limits, quirks and terms."
---

# Load the ERCOT public-report catalog into pandas and Parquet

Source entry: https://signal-lab-jet.vercel.app/datasets/ercot-public-data-api
Provider: https://developer.ercot.com/applications/pubapi/user-guide/using-api/
Checked against the provider's documentation: 2026-11-01

## Access
- Create the free account manually, subscribe to the Public API product, and set ERCOT_USERNAME, ERCOT_PASSWORD and ERCOT_SUBSCRIPTION_KEY.
- Request a fresh ID token before API calls; tokens are valid for one hour.
- Current geographic controls restrict access from outside the United States.

## Request
```bash
curl 'https://api.ercot.com/api/public-reports' -H "Ocp-Apim-Subscription-Key: $ERCOT_SUBSCRIPTION_KEY" -H "Authorization: Bearer $ERCOT_ID_TOKEN"
```

## Format
JSON HAL response whose embedded products contain EMIL ID, name, description, status, report type, audience, generation frequency, first run, file types, archive duration, download limit and artifact endpoint links.

## Load into pandas and Parquet
Needs Python 3 with requests, pandas and pyarrow.
```python
"""ERCOT public-report catalog -> pandas -> Parquet. Needs a free account."""
import os
import requests
import pandas as pd

AUTH_URL = "https://ercotb2c.b2clogin.com/ercotb2c.onmicrosoft.com/B2C_1_PUBAPI-ROPC-FLOW/oauth2/v2.0/token"
params = {
    "username": os.environ["ERCOT_USERNAME"],
    "password": os.environ["ERCOT_PASSWORD"],
    "grant_type": "password",
    "scope": "openid fec253ea-0d06-4272-a5e6-b478baeecd70 offline_access",
    "client_id": "fec253ea-0d06-4272-a5e6-b478baeecd70",
    "response_type": "id_token",
}
auth = requests.post(AUTH_URL, data=params, timeout=30)
auth.raise_for_status()
id_token = auth.json()["id_token"]
headers = {
    "Authorization": f"Bearer {id_token}",
    "Ocp-Apim-Subscription-Key": os.environ["ERCOT_SUBSCRIPTION_KEY"],
}
r = requests.get("https://api.ercot.com/api/public-reports", headers=headers, timeout=60)
r.raise_for_status()
products = r.json().get("_embedded", {}).get("products", [])
df = pd.json_normalize(products, sep="_")
df.to_parquet("ercot_public_report_catalog.parquet", index=False)
print(len(df), "ERCOT public-report products", len(df.columns), "fields")
```
Not run: it needs a free account, subscription key and ID token.

## Limits
- Rate limit: 30 requests per minute, approximately one every two seconds.
- Historic-file downloads are limited to 1,000 files at one time.
- API data begins at each product's activation date; older files are retained for at least seven years.
- Current geographic controls restrict regions outside the United States.

## Quirks
- ID tokens expire after one hour and cannot be refreshed; request another token.
- Product frequencies, activation dates, schemas and artifact endpoints differ, so discover metadata before selecting reports.
- Data Access Portal terms limit the same report to three downloads in 12 months; store and reuse downloaded reports.

## Terms and attribution
- Accounts must be registered manually; accounts created by bots or automated methods are prohibited.
- Use only the documented access methods and do not evade ERCOT's limits.
- API information is supplied as is without warranties of accuracy, timeliness or completeness.
- Terms page: https://www.ercot.com/help/terms/data-portal

## Sources
- https://developer.ercot.com/applications/pubapi/user-guide/registration-and-authentication/: "To access ERCOT APIs, you must register as a user on the ERCOT"
- https://developer.ercot.com/applications/pubapi/user-guide/registration-and-authentication/: "ID tokens are valid for one hour. There is no way to refresh an ID token."
- https://developer.ercot.com/applications/pubapi/known-limits/: "30 requests per minute"
- https://developer.ercot.com/applications/pubapi/known-limits/: "and is retained for at least 7 years."
- https://www.ercot.com/help/terms/data-portal: "Accounts registered by "bots" or other automated methods are not permitted."

## Help improve this skill
Missing a source, or see something to improve? Call the MCP tool suggest_source or feedback (or POST /api/suggest or /api/feedback). Reviewed ideas: https://signal-lab-jet.vercel.app/agent-suggestions

Information for educational purposes only. Free tiers, limits and licenses belong to the providers and may change; check the provider's own terms before using the data.
