Endpoints
Every keyed price-API route — live spot, forecast, settled prices, your ICP, and tomorrow's cheap and expensive windows.
Base URL https://api.ecosmart.co.nz/rest/v1. Every request needs Authorization: Bearer ecos_live_…. See Overview for minting a key.
{poc} is the GXP code from /me. {icp} is your 15-character connection point.
| Method | Path | What it is |
|---|---|---|
| GET | /me | This key, and the ICPs / GXPs on it |
| GET | /gxps/{poc}/spot | Current 5-minute dispatch price |
| GET | /gxps/{poc}/spot/history?hours=24 | 5-minute history (1–72 hours; we keep a rolling 72 h) |
| GET | /gxps/{poc}/forecast?hours=48 | Forward prices from WITS (short schedule beats long) |
| GET | /gxps/{poc}/final-prices?from=2026-07-01&to=2026-07-31 | Settled half-hourly prices (max 62 days per call) |
| GET | /icps/{icp} | One of your ICPs (GXP, network, price category as recorded on the key) |
| GET | /windows?icp={icp}&n=6 | Tomorrow’s cheapest and most expensive N half-hours, plus your network time-of-use clock ranges |
Live price
GET /gxps/{poc}/spot — republished by the market every five minutes.
{
"poc": "HAY2201",
"priceDollarsPerMwh": 208.40,
"priceCentsPerKwh": 20.840,
"priceCentsPerKwhInclGst": 23.9660,
"observedAt": "2026-08-21T03:00:00Z",
"ageSeconds": 286,
"isStale": false,
"gstRatePercent": 15.0
}
isStale is the field that matters. If the figure is more than 15 minutes old, we still return it — with isStale: true and the timestamp — rather than blanking it. Show the age, or do not show the price. A known GXP with no live dispatch data answers 200 with null prices and isStale: true. A code that is not a grid exit point at all is 404 UNKNOWN_POC.
GET /gxps/{poc}/spot/history?hours=24 is the same series back through a rolling 72-hour window. hours is clamped to 1–72; the response echoes the clamped value.
Forecast
GET /gxps/{poc}/forecast
{
"poc": "HAY2201",
"horizonHours": 48,
"coveredHours": 41.5,
"from": "2026-08-21T03:00:00Z",
"to": "2026-08-23T03:00:00Z",
"publishedAt": "2026-08-21T02:32:00Z",
"unavailableReason": null,
"count": 83,
"gstRatePercent": 15.0,
"points": [
{
"startsAt": "2026-08-21T03:00:00Z",
"tradingDate": "2026-08-21",
"tradingPeriod": 31,
"schedule": "S",
"priceDollarsPerMwh": 141.20,
"priceCentsPerKwh": 14.120,
"priceCentsPerKwhInclGst": 16.2380
}
]
}
Read coveredHours, not horizonHours. Two WITS schedules are merged:
| Schedule | Republished | Reaches | Wins an overlap? |
|---|---|---|---|
S short (PRSS) | about every 30 min | about 8 trading periods ≈ 4 hours | Yes — later, better-informed |
L long (PRSL) | about every 2 hours | 72 trading periods = 36 hours | No |
A 48-hour request is normally short data for the first ~4 hours and long data after that. When the long schedule is missing, the answer simply stops early. points[0] is the half-hour in progress, not the next one. Empty is a valid 200 with unavailableReason set. hours is clamped to 1–168.
Tomorrow’s windows
GET /windows?icp={icp}&n=6
Ranks tomorrow’s New Zealand trading date (midnight to midnight Pacific/Auckland) and returns the N cheapest and N most expensive half-hours from the same WITS forecast. They are usually scattered, not a consecutive block. n defaults to 6 and clamps to 1–24.
networkTou is clock ranges you can type into a battery’s time-of-use scheduler (peak / off-peak / shoulder / night / export credit). They come from the 2026 distributor schedules bundled in the price service, using the network and price category stored on your key at mint — not a live registry lookup. If that pair is missing or unknown, cheap and expensive half-hours are still returned and networkTou is empty with a reason. Public holidays are not modelled: Saturday and Sunday count as weekend.
This payload is indicative: a forecast of wholesale energy, not a promise and not a retail price. Someone else’s ICP, or an ICP this key does not carry, is 403 either way.
Settled prices
GET /gxps/{poc}/final-prices?from=2026-07-01&to=2026-07-31
The numbers that settle money. EMI publishes a day at D+1, so today and often yesterday are legitimately absent. Periods we hold nothing for are omitted, not returned as null.
priceType:
FINAL— settled. Bill from this.INTERIM— published but can still change.DISPATCH— indicative only; do not bill from it (you will not normally see this rung).
Maximum 62 days per call.
Your ICP
GET /icps/{icp}
Answered from what was recorded on the key when it was minted. This service does not query the electricity registry.