Два конечных узла чтения дают телеметрию устройств: latest для текущего значения каждого ключа и series для истории. Оба защищены разрешением на чтение телеметрии и возвращают только устройства, которые вызывающая сторона может читать. Эта страница является справочником с примерами; ключи и пути см. в REST API basics и Authentication.
Before you start
- Create an API key with the permission to read telemetry (and to read devices, if you also list them). The Read-only preset is enough. Restrict the key’s allowed networks to your servers.
- Find the device id (a UUID) on the device page or with
GET /api/iot/devices. - Every path is under your organisation:
https://<your host>/tenant/<tenantId>/api/.... - Times are milliseconds since 1 January 1970, UTC.
Latest values
GET /tenant/{tenantId}/api/telemetry/latest?kind=iot_device&entityId={deviceId}&keys=temperature,humidity
| Parameter | Required | Meaning |
|---|---|---|
kind | Yes | iot_device for device telemetry |
entityId | Yes | The device id |
keys | No | Comma-separated keys, at most 50. Leave out for every key. |
{
"kind": "iot_device",
"entityId": "6f1c…",
"latest": {
"temperature": { "ts": 1759572000000, "value": 21.5 },
"humidity": { "ts": 1759572000000, "value": 40 }
}
}
A key the device never sent is absent from latest.
Series
GET /tenant/{tenantId}/api/telemetry/series?kind=iot_device&entityId={deviceId}&keys=temperature&from=1759568400000&to=1759572000000&bucket=auto&agg=avg
| Parameter | Required | Values | Default |
|---|---|---|---|
kind | Yes | iot_device | |
entityId | Yes | The device id | |
keys | Yes | Comma-separated, 1 to 50 keys, each following the key rules | |
from | Yes | Start, inclusive (epoch ms) | |
to | Yes | End, exclusive (epoch ms); must be after from | |
bucket | No | auto, raw, 1m, 1h, 1d | auto |
agg | No | avg, min, max, last, sum, count, increase | avg |
limit | No | Points per key, 1 to 10,000 | 10,000 |
{
"kind": "iot_device",
"entityId": "6f1c…",
"resolution": "1m",
"agg": "avg",
"series": {
"temperature": [
{ "ts": 1759568400000, "value": 21.2 },
{ "ts": 1759568460000, "value": 21.4 }
]
}
}
resolutionis the resolution actually used. Withbucket=autoit israwfor windows up to 24 hours, then1m,1hor1d, whichever is finest under 10,000 buckets.- With a bucket,
tsis the start of the bucket (UTC aligned) andvaluethe aggregate. Buckets without readings are absent, not zero. - With
raw, every stored value is returned as it was stored (numbers, text, booleans, JSON), one point per timestamp, oldest first;aggis ignored. - Points are sorted by time. A key with no data returns an empty list.
See Aggregates and rollups for what each agg returns.
Limits
| Limit | Value |
|---|---|
| Keys per request | 50 |
| Points per key | 10,000 (limit) |
| Buckets in a window | 10,000 at the chosen resolution, else 400 range_too_large |
| Raw values | Only inside your raw retention (at most 90 days) |
| Minute buckets | Only inside the minute retention (at most 31 days) |
| Requests | The API rate limit; 429 with Retry-After when exceeded. See Errors and rate limits. |
Errors
| Status | Body | Cause |
|---|---|---|
| 400 | { "message": "to must be after from" } | to is not after from |
| 400 | { "message": "bad keys" } | Empty keys, more than 50, or a key that breaks the key rules |
| 400 | { "message": "…", "code": "range_too_large" } | Too many buckets for the window; use a coarser bucket |
| 401 / 403 | No valid key, or the key lacks the permission | |
| 404 | { "message": "Not found" } | The device does not exist, or you may not read it (the same answer for both) |
| 429 | Rate limit |
Paging through raw values
A raw read returns at most 10,000 points per key, oldest first. To read more:
- Request
bucket=raw&limit=10000for your window. - If a key returned 10,000 points, request again with
fromset to the last point’sts+ 1. - Repeat until a key returns fewer than
limitpoints.
For long periods, prefer 1m or 1h buckets: they hold the min, max, sum, count and last of every bucket in one value each.
Examples
Latest values with curl:
curl -s -H "Authorization: Bearer $HERMETRY_KEY" \
"https://$HOST/tenant/$TENANT/api/telemetry/latest?kind=iot_device&entityId=$DEVICE&keys=level,pump_running"
Hourly maximum of a pressure over the last 7 days:
TO=$(date +%s000); FROM=$((TO - 7*24*3600*1000))
curl -s -H "Authorization: Bearer $HERMETRY_KEY" \
"https://$HOST/tenant/$TENANT/api/telemetry/series?kind=iot_device&entityId=$DEVICE&keys=pressure&from=$FROM&to=$TO&bucket=1h&agg=max"
Energy used per hour (a kWh meter that only grows) over one day:
curl -s -H "Authorization: Bearer $HERMETRY_KEY" \
"https://$HOST/tenant/$TENANT/api/telemetry/series?kind=iot_device&entityId=$DEVICE&keys=energy_kwh&from=1762642800000&to=1762729200000&bucket=1h&agg=increase"
Daily totals in your time zone
Day buckets are UTC days. For a local day, read hourly increase (or sum) and add the hours that belong to each local day:
// Node.js 18+: daily energy per local day (Europe/Istanbul) for the last 7 days
const tz = 'Europe/Istanbul';
const to = Date.now();
const from = to - 7 * 24 * 3600 * 1000;
const url = `https://${host}/tenant/${tenant}/api/telemetry/series?kind=iot_device&entityId=${device}`
+ `&keys=energy_kwh&from=${from}&to=${to}&bucket=1h&agg=increase`;
const res = await fetch(url, { headers: { Authorization: `Bearer ${key}` } });
const { series } = await res.json();
const days = {};
for (const p of series.energy_kwh) {
const day = new Date(p.ts).toLocaleDateString('en-CA', { timeZone: tz }); // YYYY-MM-DD
days[day] = (days[day] ?? 0) + p.value;
}
console.log(days);
The first hour of the window counts only what rose inside it, so start the window an hour before the first local day you need, and drop that hour. A zone with a half-hour offset needs 1m buckets, which reach back at most 31 days.
Other read routes
| Route | Does |
|---|---|
GET /api/telemetry/kinds | The kinds of readings your organisation has (for example iot_device) |
GET /api/iot/devices/{deviceId}/elements | The keys of one device (declared in its profile or sent), at most 300, with labels and units |
For writes, devices use MQTT or HTTP; the REST API has no telemetry write route. See Device HTTP API and Telemetry and attributes API.

