Project operational timeseries
Query half-hourly energy, curtailment and revenue timeseries for projects, by project id or DUID.
Authorization header. See Getting started for authentication details.Body parameters
| Name | Type | Description |
|---|---|---|
| series* | string[] | One or more project series, each as "name" or "name:rollup". See the series table below |
| from* | integer | Start of the range in epoch milliseconds, inclusive |
| to* | integer | End of the range in epoch milliseconds, exclusive. Must be greater than from |
| interval* | enum | Bucket size. One of "hh", "d", "w", "m" or "y" |
| entity_ids | string[] | RenewMap project ids, maximum 500. Required unless duids is supplied |
| duids | string[] | Market DUIDs, maximum 500. Required unless entity_ids is supplied |
| time_of_day_intervals | integer[] | Half-hour slots of the day, 1 to 48. Returns a value per bucket per slot |
Example request
curl --request POST \
--url 'https://api.renewmap.com.au/api/v1/projects/timeseries/points' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'content-type: application/json' \
--data '{
"series": ["generation_mwh", "generation_revenue:avg"],
"from": 1735689600000,
"to": 1738368000000,
"interval": "d",
"duids": ["COOPGWF1"]
}'Example response
{
"from": 1735689600000,
"to": 1738368000000,
"interval": "d",
"data": [
{
"entity_id": "e7347ca7-85b3-4da7-90fa-d3da74fc73a8",
"series": "generation_mwh",
"rollup": "sum",
"key": "COOPGWF1",
"value": 2412.6,
"timestamp": "2025-01-01T00:00:00.000Z"
},
{
"entity_id": "e7347ca7-85b3-4da7-90fa-d3da74fc73a8",
"series": "generation_revenue",
"rollup": "avg",
"key": "COOPGWF1",
"value": 1043.11,
"timestamp": "2025-01-01T00:00:00.000Z"
}
]
}
Experimental: The operational insights endpoints are in early access.
Returns the half-hourly generation, curtailment and revenue timeseries that power the charts in a project’s Operational tab, bucketed to the interval you ask for. For transmission lines, see Transmission operational timeseries.
Points are ordered by entity, series and time.
Access
This endpoint requires the Operational Insights add-on on your organisation’s licence, in addition to an API key. Requests without a key return 401, and requests from an organisation without the add-on return 403. Contact [email protected] to enable it.
Authentication is the same as the rest of the API. See Getting started.
Identifying projects
Supply either entity_ids or duids. If neither is present the request fails with 400. Any field outside the table above is rejected, so line_* series and transmission-only fields are not accepted here.
entity_ids are the id values returned by Get a list of projects. Project ids resolve through the DUIDs registered against the project, so a project with no DUID has no operational data.
Series
Project series are keyed by DUID; a project with more than one DUID returns a point per DUID.
| Name | Unit | Rollups | Default | Description |
|---|---|---|---|---|
generation_mwh |
MWh | avg, sum |
sum |
Energy generated, floored at zero. See Generation & Load |
load_mwh |
MWh | avg, sum |
sum |
Energy consumed, which for a battery is charging |
curtailment_constraint_mwh |
MWh | avg, sum |
sum |
Energy curtailed because a network constraint was binding. See Curtailment |
curtailment_economic_mwh |
MWh | avg, sum |
sum |
Energy curtailed in response to price rather than to the network |
generation_revenue |
AUD | avg, sum |
sum |
Generated energy valued at spot. See Revenue & Missed Revenue |
load_revenue |
AUD | avg, sum |
sum |
Consumed energy valued at spot. Signed, and adds to generation_revenue to give net revenue |
missed_revenue_constraint |
AUD | avg, sum |
sum |
Constraint-curtailed energy valued at spot, with the price floored at zero |
Requesting a name outside this list returns 400 with the list of accepted series in the message.
Curtailment and revenue are split rather than totalled. Add both curtailment_*_mwh series for total curtailment, and generation_revenue plus load_revenue for net revenue.
Rollups
Each series entry is a name, optionally followed by a colon and a rollup: "generation_mwh" or "generation_mwh:avg". The rollup sets how the half-hourly readings in a bucket become one value.
| Rollup | Meaning |
|---|---|
avg |
Mean of the readings in the bucket |
sum |
Total of the readings in the bucket |
- A bare name uses that series’ default, shown per series above
- An unsupported rollup returns
400naming the ones that series accepts - A series can repeat with different rollups.
["generation_mwh:avg", "generation_mwh:sum"]returns two points per bucket, separated by therollupfield - Rollups combine within a bucket, never across projects, so a
sumover five projects returns five sums - At
interval: "hh"both rollups return the same value, since the bucket holds one reading - non-default rollups may have unintuitive definitions. e.g. generation_mwh:avg will return the average mwh per half hour, and would need to be multiplied by 2 to get average mw
Response
| Field | Description |
|---|---|
from, to |
The requested range, echoed back |
interval |
The interval the response was built at, which may be coarser than the one you requested |
time_of_day_intervals |
The requested slots, echoed back. Omitted when the request did not include them |
data[].entity_id |
The project id the value belongs to |
data[].series |
The series name, without the rollup |
data[].rollup |
The rollup the value was built with, named or defaulted |
data[].key |
The DUID the value was recorded against |
data[].value |
The value, in the unit of the series |
data[].timestamp |
Start of the bucket |
data[].half_hour |
The half-hour slot, 1 to 48. Present only when time_of_day_intervals was requested |
Projects and periods with no data are absent from data rather than returned as null, so an empty data array is a normal response for a project that reports no telemetry.
Adding time_of_day_intervals returns a point per bucket per requested half-hour slot, each carrying both a timestamp and a half_hour. Slots with no reading for a bucket are omitted, so a bucket can carry fewer points than the number of slots you requested.
How values are aggregated
A daily generation_revenue under sum is the day’s total; under avg it is the average per half hour. MWh and dollars are normally read as totals, which is why every series defaults to sum. See Revenue & Missed Revenue.
Averages are recombined from stored sums and counts rather than averaged again, so a bucket with missing readings is not weighted incorrectly. A sum totals only the readings that exist. Check interval on the response before reading a sum, since a coarsened bucket covers a longer period than requested.
Timestamps
All timestamps and half-hour slots are in market time: Australian Eastern Standard Time (UTC+10), with no daylight saving adjustment all year. Slot 1 is 00:00 to 00:30 and slot 48 is 23:30 to 00:00. See Data sources & coverage.
Limits
- Maximum 500
entity_idsorduidsper request - A response is capped at roughly 5,000 buckets. When the range and interval you asked for would exceed that, the endpoint steps the interval up (
hhtod, thenw,m,y) until the request fits, and returns the interval it actually used in theintervalfield. A year ofhhdata comes back asd. Readintervalfrom the response rather than assuming your request was honoured, and page through shorter ranges to keep half-hourly resolution over a long period - Requests are rate limited per organisation. Exceeding the limit returns
429. See Getting started
Errors
| Status | Meaning |
|---|---|
400 |
The body is not valid JSON, a field failed validation, an unrecognised field or series rollup was supplied, or neither entity_ids nor duids was given |
401 |
Missing or invalid API key |
403 |
The organisation does not hold the Operational Insights add-on |
429 |
Rate limit exceeded |
Error responses carry a JSON body with a message field. Validation failures are joined into a single message, so one response can describe several problems.