Query Timeseries
Query timeseries data generated primarily by field devices, such as sensors and meters, but also custom data generated by applications and other sources, such as weather data or forecasts output.
See Data Exchange for information about how to write timeseries data.
Series
Every query selects one or more series. A series identifies the values of one property of one device:
devices/{deviceId}/{property}For example, devices/my-device-uuid/temperature is the temperature measured by the device my-device-uuid.
Aggregated series
When the device type of a device declares aggregations for a property, the platform also computes aggregated series for it. An aggregation is declared as operation:period, for example avg:quarter or delta:daily:
{
"name": "Energy meter",
"properties": {
"activeEnergy": {
"displayName": "Active energy",
"uom": "kWh",
"type": "number",
"aggregations": ["delta:quarter", "delta:hourly", "delta:daily"]
}
}
}| Operations | Periods |
|---|---|
avg, sum, delta, first, last | quarter (15 minutes), hourly, daily, weekly, monthly |
Aggregated series are named {property}_{operation}_{period} and can be queried like any other series, with either notation:
devices/my-device-uuid/temperature_avg_quarter
devices/my-device-uuid/temperature/avg/quarterQuerying data
The default HTTP endpoint for querying timeseries data is
Where JSON_QUERY is in the following form:
[{
"query": {
"series": [
"devices/my-device-uuid/temperature",
"devices/my-device-uuid/humidity"
],
"timeFrom": "2023-01-01T12:00:00.000Z",
"timeTo": "2023-01-01T14:00:00.000Z"
}
}]This payload will query the API for two timeseries, representing the measurements of temperature and humidity generated by the same device, in a two hour period. timeFrom and timeTo are optional: when omitted, the query covers the last hour.
The response contains one item for each query; each item is a list of columns, one per series, with [time, value] pairs:
{
"status": true,
"data": [
[
{
"name": "devices/my-device-uuid/temperature",
"data": [
[
"2023-01-02T12:00:00.000Z",
12.14
],
[
"2023-01-02T12:01:00.000Z",
12.98
],
...
]
},
{
"name": "devices/my-device-uuid/humidity",
"data": [
[
"2023-01-02T12:00:00.000Z",
31.4
],
[
"2023-01-02T12:01:00.000Z",
32.5
],
...
]
}
]
]
}With this api we can also combine results from multiple devices:
[{
"query": {
"series": [
"devices/my-device-uuid-1/temperature",
"devices/my-device-uuid-2/temperature",
"devices/my-device-uuid-3/humidity"
],
"timeFrom": "2023-01-01T12:00:00.000Z",
"timeTo": "2023-01-01T14:00:00.000Z"
}
}]Multiple queries
We can also run multiple queries across different time intervals:
[{
"query": {
"series": [
"devices/my-device-uuid-1/temperature_avg_quarter",
"devices/my-device-uuid-2/temperature_avg_quarter"
],
"timeFrom": "2023-01-01T12:00:00.000Z",
"timeTo": "2023-01-01T14:00:00.000Z"
}
}, {
"query": {
"series": [
"devices/my-device-uuid-1/temperature_avg_quarter"
],
"timeFrom": "2023-01-02T12:00:00.000Z",
"timeTo": "2023-01-02T14:00:00.000Z"
}
}]The response from the previous query will have one response item for each query item in the input:
{
"status": true,
"data": [
[
{
"name": "devices/my-device-uuid-1/temperature_avg_quarter",
"data": [
[
"2023-01-02T12:00:00.000Z",
12.14
],
[
"2023-01-02T12:15:00.000Z",
12.98
],
[
"2023-01-02T12:30:00.000Z",
13.01
],
...
]
}
],
[
{
"name": "devices/my-device-uuid-1/temperature_avg_quarter",
"data": [
[
"2023-01-02T12:00:00.000Z",
13.54
],
[
"2023-01-02T12:15:00.000Z",
13.90
],
[
"2023-01-02T12:30:00.000Z",
14.01
],
...
]
}
]
]
}Transforming data with pipelines
Each query can include a pipeline: an ordered list of steps applied to the selected series before the result is returned. Each step is an object with a single key, the name of the transformation.
[{
"query": {
"series": ["devices/meter-1/power", "devices/meter-2/power"],
"timeFrom": "2026-01-01T00:00:00.000Z",
"timeTo": "2026-01-02T00:00:00.000Z"
},
"pipeline": [
{ "resample": { "interval": 3600000, "operation": "avg", "from": "2026-01-01T00:00:00.000Z", "to": "2026-01-02T00:00:00.000Z" } },
{ "aggregate": { "operation": "add", "columns": ["devices/meter-1/power", "devices/meter-2/power"], "output": "total_power" } },
{ "project": { "columns": ["total_power"] } }
]
}]This query computes the hourly average power of two meters, adds them together and returns only the total.
| Step | Parameters | Result |
|---|---|---|
resample | interval (milliseconds), operation, optional from and to | One value per interval for every series |
reduce | operation | A single value for every series |
aggregate | operation, columns, output | A new series computed point by point from other series |
project | columns | Only the listed series |
add | a number | The number is added to every value |
mul | a number | Every value is multiplied by the number |
If a step cannot be applied, the API responds with 400 Bad Request and the index of the query that failed.
resample
Splits the time range into intervals of interval milliseconds and computes one value per interval with operation:
| Operation | Value of each interval | Timestamp |
|---|---|---|
avg | Average of the values | Start of the interval |
sum | Sum of the values | Start of the interval |
max | Highest value | Time of the highest value |
last | Last value | Time of the last value |
Intervals start at from. Without from, they start at the first value found, so always pass from and to when you need intervals aligned to the clock (for example, hours starting at minute zero). Intervals without values are returned with null for avg, max and last, and 0 for sum.
For example, given these values of devices/meter-1/power:
[
["2026-01-01T00:05:00.000Z", 10],
["2026-01-01T00:20:00.000Z", 20],
["2026-01-01T00:35:00.000Z", 30],
["2026-01-01T00:50:00.000Z", 40],
["2026-01-01T01:10:00.000Z", 50]
]the step { "resample": { "interval": 3600000, "operation": "sum", "from": "2026-01-01T00:00:00.000Z", "to": "2026-01-01T02:00:00.000Z" } } returns:
[
["2026-01-01T00:00:00.000Z", 100],
["2026-01-01T01:00:00.000Z", 50]
]reduce
Reduces every series to a single value. operation is one of avg, sum, min, max, first, last or delta (last value minus first value). With the values above, { "reduce": { "operation": "delta" } } returns [["2026-01-01T00:05:00.000Z", 40]].
aggregate
Combines two or more series point by point into a new series named output. operation is one of:
| Operation | Result |
|---|---|
add | Sum of the values |
sub | First series minus the others |
mul | Product of the values |
div | First series divided by the others |
avg | Average of the values |
The original series are kept in the result: add a project step to return only the new one. Values are combined when they have the same timestamp, so resample the series first when they are measured at different times.
project
Keeps only the series listed in columns, in that order. Names that do not match any series are ignored.
add and mul
Add a number to every value, or multiply every value by a number. For example, { "mul": 0.001 } converts values from W to kW.
Other Endpoints
If your client struggles with complex query strings containing JSON, you can use the following POST endpoint and provide the query in the body of the HTTP request.
Retention
Every project has a data retention period. This endpoint reads values within the retention period; to read older values, or a time range that spans both, use the endpoints described in Historical data and export.