Gramm Forecast API

Production API documentation for supported U.S. power markets. RESTful JSON API with forecast horizons from 1 day to 15 days across 7 ISO regions.

What to check before integration

Review the API surface below, then pair it with the public benchmark on /accuracy and the review materials on /enterprise. Gramm supports day-ahead forecasts and extended horizons where the grid, plan, and validation status allow them.

Base URL

https://api.gramm.ai/v1

All endpoints are versioned under /v1. Responses are JSON by default.

Authentication

All queries except TAC_AREAS require a Bearer token:

Authorization: Bearer grmm_your_api_key

Create an account to get an API key. Keys are prefixed with grmm_ and shown once on creation.

Supported Regions

Use any of these codes as the region parameter. List all via GET /v1/regions.

CAISO
California ISO
California
active
ERCOT
Electric Reliability Council of Texas
Texas
active
PJM
PJM Interconnection
Mid-Atlantic / Midwest
active
MISO
Midcontinent ISO
Central US
active
NYISO
New York ISO
New York
active
ISONE
ISO New England
New England
active
SPP
Southwest Power Pool
Central US
active

Endpoints

GET/v1/demand/forecast

System load demand forecast. Returns MW values at the requested resolution (1h or 15min) for the requested horizon.

regionYes

CAISO, PJM, ERCOT, MISO, NYISO, ISONE, SPP. Aliases accepted: CISO, ERCO, ISNE, NYIS, SWPP.

horizonNo

1d (default), 2d, 7d, 15d. Availability varies by plan and grid.

resolutionNo

1h (default), 15min. Sub-hourly resolution requires a paid plan where available.

Example

curl "https://api.gramm.ai/v1/demand/forecast?region=CAISO&horizon=2d" \
  -H "Authorization: Bearer grmm_your_api_key"

Response (Developer plan and above)

{
  "status": "success",
  "data": [
    { "timestamp": "2026-04-09T08:00:00+00:00", "value_mw": 24523.4, "p10": 23892.1, "p90": 25104.7 },
    { "timestamp": "2026-04-09T09:00:00+00:00", "value_mw": 25891.7, "p10": 25201.4, "p90": 26573.9 }
  ],
  "meta": {
    "region": "CAISO",
    "horizon": "2d",
    "resolution": "1h",
    "count": 48,
    "issued_at": "2026-04-09T06:00:00Z",
    "model": "gramm-v22",
    "generated_at": "2026-04-09T12:34:56Z"
  }
}

Free responses omit the p10/p90 keys. Prediction intervals are populated on rows where the model has produced them; intervals are absent on rows that do not yet carry quantile estimates.

GET/v1/demand/history

Historical actual load from EIA data. Defaults to last 24 hours. Maximum query range: 31 days.

regionYes

CAISO, PJM, ERCOT, MISO, NYISO, ISONE, SPP. Aliases accepted.

startNo

ISO 8601 datetime (default: 24h ago).

endNo

ISO 8601 datetime (default: now).

curl "https://api.gramm.ai/v1/demand/history?region=PJM&\
  start=2026-04-07T00:00:00Z&end=2026-04-08T00:00:00Z" \
  -H "Authorization: Bearer grmm_your_api_key"
GET/v1/demand/latest

Latest actual load value and most recent forecast for a region. Useful for dashboards and real-time monitoring.

{
  "status": "success",
  "data": {
    "region": "ERCOT",
    "actual": { "timestamp": "2026-04-09T12:00:00Z", "value_mw": 45231.5 },
    "forecast": { "timestamp": "2026-04-09T13:00:00Z", "value_mw": 46102.3, "issued_at": "2026-04-09T06:00:00Z" }
  }
}
GET/v1/demand/accuracy

Live forecast accuracy metrics. Computes MAPE, RMSE, MAE, and bias from actual forecast vs actuals data.

{
  "status": "success",
  "data": {
    "region": "CAISO",
    "metrics": {
      "mape_pct": 2.62,
      "mae_mw": 245.8,
      "rmse_mw": 312.5,
      "bias_mw": -15.2,
      "sample_hours": 720
    },
    "model": {
      "name": "gramm-v22",
      "version": "v22",
      "last_run": "2026-04-09T06:00:00Z",
      "forecast_count": 336
    }
  }
}
GET/v1/regions

List all supported regions with ISO name, timezone, available horizons, and status. No authentication required.

GET/v1/health

API health check. Returns status, model version, active grid count, and last forecast run time. No authentication required.

Rate Limits & Data Access

Exceeding your plan's rate limits returns HTTP 429 with a Retry-After header. Historical data access and per-region daily caps also vary by plan.

Free

Req / Hour
100
Req / Day
1,000
API Keys
2
History
24 hours
Per-Region / Day
50

Developer

Req / Hour
10,000
Req / Day
50,000
API Keys
5
History
30 days
Per-Region / Day
5,000

Team

Req / Hour
50,000 pooled
Req / Day
500,000 pooled
API Keys
Unlimited team
History
30 days
Per-Region / Day
5,000

Enterprise

Req / Hour
Custom
Req / Day
Custom
API Keys
Custom
History
1 year
Per-Region / Day
50,000

Error Responses

Errors use machine-readable string codes. XML format for OASIS queries, JSON for resultformat=7. Every error includes a request_id for support debugging.

XML Error Response

<?xml version="1.0" encoding="UTF-8"?>
<OASISReport>
  <MessagePayload>
    <RTO>
      <ERROR>
        <ERR_CODE>rate_limited</ERR_CODE>
        <ERR_DESC>Rate limit exceeded for Free plan. Retry after 1823 seconds.</ERR_DESC>
        <REQUEST_ID>req_m3k8f2_a9c4xp</REQUEST_ID>
        <DOCUMENTATION_URL>https://gramm.ai/api-docs#rate-limits</DOCUMENTATION_URL>
      </ERROR>
    </RTO>
  </MessagePayload>
</OASISReport>

JSON Error Response (resultformat=7)

{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded for Free plan. Retry after 1823 seconds.",
    "documentation_url": "https://gramm.ai/api-docs#rate-limits",
    "request_id": "req_m3k8f2_a9c4xp",
    "details": {
      "plan": "free",
      "limit_hourly": 100,
      "remaining_hourly": 0,
      "limit_daily": 1000,
      "remaining_daily": 450,
      "retry_after_seconds": 1823
    }
  }
}
401unauthorized

Missing or invalid API key

401invalid_key

API key revoked or not found

429rate_limited

Rate limit exceeded (includes Retry-After header)

400invalid_query

Unsupported queryname

400missing_parameter

Required parameter not provided

404no_data

No forecast data available for this grid

Quick Start

Python

import requests

BASE_URL = "https://api.gramm.ai/v1"
headers = {"Authorization": "Bearer grmm_your_api_key"}

# Get 48-hour forecast for ERCOT
resp = requests.get(f"{BASE_URL}/demand/forecast",
    params={"region": "ERCOT", "horizon": "2d"},
    headers=headers)
data = resp.json()

for point in data["data"]:
    print(f"{point['timestamp']}: {point['value_mw']:.0f} MW")

cURL

# Forecast
curl "https://api.gramm.ai/v1/demand/forecast?region=CAISO&horizon=7d" \
  -H "Authorization: Bearer grmm_your_api_key"

# Historical actuals (no auth needed for regions)
curl "https://api.gramm.ai/v1/regions"

OASIS Compatibility (Legacy)

For teams migrating from CAISO OASIS, a compatibility endpoint is available at /v1/oasis. It accepts the same parameters as CAISO OASIS (queryname, tac_area_name, market_run_id, startdatetime, enddatetime, resultformat) and returns OASIS-compatible CSV/XML. We recommend migrating to the v1 REST endpoints above for new integrations.

# OASIS compatibility endpoint
curl "https://api.gramm.ai/v1/oasis?queryname=SLD_FCST&\
  market_run_id=DAM&tac_area_name=CISO&resultformat=6" \
  -H "Authorization: Bearer grmm_your_api_key"

Try the API

Build a request interactively. Select parameters below to generate the URL and code snippets.

API Builder

Select an endpoint and parameters to generate request URLs and code snippets.

GEThttps://api.gramm.ai/v1/demand/forecast?region=CAISO&horizon=2d
curl "https://api.gramm.ai/v1/demand/forecast?region=CAISO&horizon=2d" \
  -H "Authorization: Bearer grmm_your_api_key"

Support

Contact: hello@gramm.ai