Reference
Units, GST, curl examples, errors, rate limits, and the OpenAPI contract.
Units and GST
Everything stored is GST-exclusive, because that is how the wholesale market publishes it.
| Field | Meaning |
|---|---|
priceDollarsPerMwh | Raw, as the market publishes it. GST-exclusive |
priceCentsPerKwh | The same number ÷ 10. GST-exclusive |
priceCentsPerKwhInclGst | × 1.15. GST-inclusive — the one to compare with a power bill |
Negative prices are real, especially overnight in the South Island. They pass through as negatives; GST on a credit is still a credit.
Timestamps are ISO-8601 in UTC (Z), e.g. 2026-08-21T05:45:00Z. Jackson serialises Instant that way; spring.jackson.time-zone does not change it. tradingDate and tradingPeriod are New Zealand trading-calendar fields, so you never have to recompute a half-hour across the two daylight-saving days (46 or 50 periods instead of 48).
curl
Replace HAY2201 and the ICP with your values from GET /me.
export ECOS_KEY='ecos_live_your_key_here'
curl -sS -H "Authorization: Bearer $ECOS_KEY" \
"https://api.ecosmart.co.nz/rest/v1/me"
curl -sS -H "Authorization: Bearer $ECOS_KEY" \
"https://api.ecosmart.co.nz/rest/v1/gxps/HAY2201/spot"
curl -sS -H "Authorization: Bearer $ECOS_KEY" \
"https://api.ecosmart.co.nz/rest/v1/gxps/HAY2201/forecast?hours=24"
curl -sS -H "Authorization: Bearer $ECOS_KEY" \
"https://api.ecosmart.co.nz/rest/v1/windows?icp=0000123456ABCDE&n=6"
Errors and rate limits
| Status | code | When |
|---|---|---|
| 401 | UNAUTHORIZED | Missing, unknown, or revoked key. All three look the same |
| 403 | ICP_NOT_IN_SCOPE | /icps/{icp} or /windows for an ICP this key does not carry |
| 404 | UNKNOWN_POC | No such grid exit point |
| 400 | INVALID_RANGE | from after to, or a final-prices range over 62 days |
| 429 | RATE_LIMITED | This key’s per-minute budget is spent |
Bodies are JSON with a code you can branch on and a message for a human.
The limit is a token bucket per key, not per IP: 12 requests, refilling continuously (one every five seconds at the default, with a burst of 12). A dashboard that polls every five minutes never comes close. There is no IP blacklist on this API; a stolen or runaway key is stopped by revoking it (or by this budget). Every response carries X-RateLimit-Limit and X-RateLimit-Remaining. A 429 adds Retry-After in whole seconds — wait that long; do not retry immediately.
OpenAPI
The machine-readable contract is openapi.yaml. Import it into Postman, Insomnia, or similar. Home Assistant does not import OpenAPI — use the REST sensors.