Skip to content

Enverus Forecasts

ProgridPy integrates with the Enverus NRF (National Renewable Forecast) API to fetch wind and solar forecasts and extreme weather flags. The EnverusClient provides a simple interface for acquiring day-ahead style forecast data for any supported ISO.

Setup

Authentication

The Enverus API requires only a user ID. No separate API key or token is needed.

from progridpy.utils.enverus_api.client import EnverusClient

# Option 1: Pass directly
client = EnverusClient(userid="your-userid")

# Option 2: Set environment variable (recommended)
# export ENVERUS_USERID=your-userid
client = EnverusClient()  # Reads from ENVERUS_USERID env var

Missing credentials

If neither argument nor environment variable is set, the constructor raises EnverusAuthError.

Constructor Parameters

EnverusClient(userid: str | None = None, timeout: float = 120.0)
Parameter Type Default Description
userid str \| None None Enverus user ID. Falls back to ENVERUS_USERID env var.
timeout float 120.0 HTTP request timeout in seconds.

Fetching Forecast Data

fetch_df()

The primary method for retrieving forecast data:

def fetch_df(
    self,
    iso: str,
    feature: EnverusDataType,
    start_date: str | None = None,
    end_date: str | None = None,
    model: WeatherModel | None = None,
    gen_hr: int | None = None,
) -> pd.DataFrame:
Parameter Type Default Description
iso str -- ISO identifier: "miso", "ercot", "spp", "pjm", "nyiso", "isone", "caiso"
feature EnverusDataType -- Data type to fetch
start_date str \| None Today Operating Day start in YYYYMMDD format (inclusive)
end_date str \| None start_date Operating Day end in YYYYMMDD format (inclusive)
model WeatherModel \| None Feature default Weather model: ECMWF or HRRR
gen_hr int \| None Model default Model generation hour (UTC)

Returns a DataFrame with columns: [interval_start_local, node, <feature_value>]

Basic Example

from progridpy.utils.enverus_api.client import EnverusClient
from progridpy.utils.enverus_api.registry import EnverusDataType

client = EnverusClient()

# Fetch MISO wind forecast for January 13, 2026
df = client.fetch_df("miso", EnverusDataType.WIND_FORECAST, "20260113")
print(df.head())
# Columns: interval_start_local, node, wind_forecast

Date Range Example

# Fetch 3 days of ERCOT solar forecast
df = client.fetch_df(
    "ercot",
    EnverusDataType.SOLAR_FORECAST,
    start_date="20260113",
    end_date="20260115",
)

Specifying Weather Model

from progridpy.utils.enverus_api.registry import WeatherModel

# Use HRRR model instead of the default ECMWF
df = client.fetch_df(
    "miso",
    EnverusDataType.WIND_FORECAST,
    start_date="20260113",
    model=WeatherModel.HRRR,
)

Supported Data Types

from progridpy.utils.enverus_api.registry import EnverusDataType
Data Type Value Supported Models Default Model
WIND_FORECAST "wind_forecast" ECMWF, HRRR ECMWF
SOLAR_FORECAST "solar_forecast" ECMWF, HRRR ECMWF
EXTREME_WIND_SPEED "extreme_wind_speed" HRRR only HRRR
SOLAR_SMOKE "solar_smoke" HRRR only HRRR
SOLAR_SNOW "solar_snow" HRRR only HRRR
TURBINE_ICING "turbine_icing" HRRR only HRRR

Weather Models

from progridpy.utils.enverus_api.registry import WeatherModel

WeatherModel.ECMWF  # European Centre for Medium-Range Weather Forecasts
WeatherModel.HRRR   # High-Resolution Rapid Refresh
Model gen_hr Default Notes
HRRR 12 (UTC) Recommended for trading across all timezones. Produces ~48 hours of forecasts.
ECMWF 0 (UTC) The only available generation hour.

Start Date vs. Forecast Date Semantics

The start_date and end_date parameters represent the Operating Day (OD) -- the day you want forecast data for. Internally, fetch_df() fetches the model run from OD-1 (the previous day) and extracts only the OD hours.

This is designed for day-ahead trading workflows:

OD-1 (Model Run Day)          OD (Operating Day)
 |                              |
 v                              v
 HRRR 12:00 UTC run -----> Full 24-hour forecast for OD

For example, calling fetch_df("miso", EnverusDataType.WIND_FORECAST, "20260113"):

  1. Fetches the HRRR model run from January 12 (OD-1) at 12:00 UTC
  2. Filters the response to only include hours from January 13 00:00 to 23:59 local time
  3. Returns the 24-hour forecast DataFrame for the Operating Day

HRRR coverage

The HRRR 12:00 UTC model run produces approximately 48 hours of forecasts. The OD-1 run provides full 24-hour coverage for the Operating Day (00:00 to 23:59).

Supported ISOs

The Enverus NRF API supports the following ISOs:

ISO Identifier
MISO "miso"
ERCOT "ercot"
SPP "spp"
PJM "pjm"
NYISO "nyiso"
ISO-NE "isone"
CAISO "caiso"

Error Handling

The client raises specific exceptions:

Exception Cause
EnverusAuthError Missing user ID (no userid argument and no ENVERUS_USERID env var)
EnverusAPIError HTTP error from the API (non-200 status code)
ValueError Unsupported weather model for the requested feature
from progridpy.utils.enverus_api.exceptions import EnverusAPIError, EnverusAuthError

try:
    df = client.fetch_df("miso", EnverusDataType.WIND_FORECAST, "20260113")
except EnverusAPIError as e:
    print(f"API returned status {e.status_code}")

MISO Raw Data Integration

MISO's raw data type enum includes Enverus-sourced types that are downloaded via the Enverus API rather than the MISO website:

from progridpy.iso import MISORawDataType

MISORawDataType.WIND_FORECAST_HRRR_ENVERUS
MISORawDataType.WIND_FORECAST_ECMWF_ENVERUS
MISORawDataType.SOLAR_FORECAST_HRRR_ENVERUS
MISORawDataType.SOLAR_FORECAST_ECMWF_ENVERUS
MISORawDataType.EXTREME_WIND_SPEED_ENVERUS
MISORawDataType.SOLAR_SMOKE_ENVERUS
MISORawDataType.SOLAR_SNOW_ENVERUS
MISORawDataType.TURBINE_ICING_ENVERUS

These are downloaded through the standard download_raw_data() interface when selected:

from progridpy.iso import MISO, MISORawDataType

miso = MISO()
miso.download_raw_data(
    start_date="2026-01-01",
    end_date="2026-01-07",
    data_types=[MISORawDataType.WIND_FORECAST_HRRR_ENVERUS],
)