API Reference
Every product in the catalog is reachable as a REST endpoint. Paths, query conventions and the response envelope follow the reference Public API so client code written against one works against the other.
Endpoints
Data endpoints are addressed by Report ID and endpoint name:
GET /api/public-reports/{reportId}/{endpoint}
# example
GET /api/public-reports/np6-788-cd/lmp_node_zone_hubThe base path stands in for https://api.grid-operator.example/api/public-reports on the real service. No subscription key or bearer token is required here.
Response envelope
Responses separate the schema from the rows. Columns are described once in fields, and each record is a positional array in data.
{
"_meta": {
"totalRecords": 8640,
"pageSize": 100,
"totalPages": 87,
"currentPage": 1,
"query": { "deliveryDateFrom": "2026-08-01" }
},
"report": {
"name": "LMPs by Resource Nodes, Load Zones and Trading Hubs",
"reportId": "np6-788-cd",
"displayId": "NP6-788-CD",
"endpoint": "lmp_node_zone_hub"
},
"fields": [
{ "name": "SCEDTimestamp", "label": "SCED Timestamp", "dataType": "TIMESTAMP" },
{ "name": "settlementPoint", "label": "Settlement Point", "dataType": "STRING" },
{ "name": "LMP", "label": "LMP", "dataType": "FLOAT", "unit": "$/MWh" }
],
"data": [
["2026-08-01T00:00:00", "HB_NORTH", 28.44],
["2026-08-01T00:00:00", "HB_HOUSTON", 31.02]
]
}To rebuild named records, zip each row against the field list:
const rows = body.data.map((row) =>
Object.fromEntries(row.map((v, i) => [body.fields[i].name, v])),
);Filtering
Any field marked filterable in a report's schema can be used as a query parameter. String and boolean fields match exactly; numeric, date and timestamp fields take From and To suffixes for ranges.
# exact match
?settlementPoint=HB_NORTH
# numeric range
?LMPFrom=100&LMPTo=5000
# date range
?deliveryDateFrom=2026-08-01&deliveryDateTo=2026-08-07
# combined
?settlementPoint=HB_WEST&LMPFrom=0&deliveryDateFrom=2026-08-01
# sort (portal extension)
?sort=LMP&dir=descFilters combine with AND. A date filter applied to a timestamp field matches on prefix, so SCEDTimestamp=2026-08-01 returns every interval that day.
Pagination
?page=1&size=1000 # size caps at 5000, defaults to 100Read _meta.totalPages from the first response and walk forward until you reach it:
let page = 1, all = [], total;
do {
const res = await fetch(`${url}&page=${page}&size=1000`);
const body = await res.json();
all.push(...body.data);
total = body._meta.totalPages;
} while (page++ < total);Requests are also bounded by date span: reports posted every five or fifteen minutes serve at most 7 days per request, hourly and daily reports up to 31 and 62 days respectively. A wider range is clamped to the most recent window rather than rejected.
Archive listings
The archive endpoint lists individual postings of a report, newest first, each linking to the data it contained.
GET /api/public-reports/archive/{reportId}
?postDatetimeFrom=2026-08-01&postDatetimeTo=2026-08-07&page=1&size=50
{
"_meta": { "totalRecords": 2016, "totalPages": 41, "currentPage": 1 },
"archives": [
{
"docId": 1043227,
"postDatetime": "2026-08-07T23:55:00",
"friendlyName": "cdr.np6_788_cd.20260807235500.csv",
"bytes": 184213,
"_links": { "endpoint": { "href": "/api/public-reports/..." } }
}
]
}CSV export
Add format=csv to any data request to receive the current page as a CSV download instead of JSON. Filters and page size apply unchanged.
GET /api/public-reports/np6-345-cd/act_sys_load_by_wzn
?deliveryDateFrom=2026-08-01&deliveryDateTo=2026-08-07&size=1000&format=csvEndpoint catalog
All 27 endpoints exposed by this portal.