Skip to main content

GET Device Readings

Pull time-series measurements for a single device with GET /v5/devices/{device_id}/data — parameters, response schema, pagination, and code examples in five languages.

GET /v5/devices/{device_id}/data

Retrieves time-series measurements for a single device. Get the device_id from List Devices, then call this endpoint to pull the device's readings over a date range, timestamp range, or relative window.

Authentication

Authenticated with your API key in the X-API-Key header; the user is resolved from the key. Access requires an Administrator, Editor, or User role in the device's organization. See Authentication and Data access control in the Overview.

Explore the interactive v5 endpoint in the OpenAPI/Swagger reference.

Request

GET https://api.zentracloud.io/v5/devices/{device_id}/data

Path parameters

Parameter

Type

Required

Description

device_id

string

Yes

The unique identifier of the device. Example: z6-12345.

Query Parameters

Parameter

Type

Default

Description

direction

string

descending

Order in which data is retrieved and displayed by date. One of ascending or descending.

start_datetime

string (ISO 8601)

-

Start of the window as an ISO datetime string. A datetime without a timezone is treated as UTC. Example: 2025-10-20T17:15+00:00. Use window or datetimes or timestamps — only one.

end_datetime

string (ISO 8601)

-

End of the window as an ISO datetime string. A datetime without a timezone is treated as UTC. Example: 2025-10-20T17:15+00:00. Use window or datetimes or timestamps — only one.

start_timestamp

integer

-

Start of the window as a Unix timestamp (seconds since 1970-01-01 UTC). Example: 1763445086. Use window or datetimes or timestamps — only one.

end_timestamp

integer

-

End of the window as a Unix timestamp (seconds since 1970-01-01 UTC). Example: 1763445086. Use window or datetimes or timestamps — only one.

window

string

-

A relative time range measured back from the time of the request (server time, UTC). Written as <n><unit>, where <n> is a positive whole number and <unit> is m (minutes), h (hours), d (days), or w (weeks). Example: 24h for the last 24 hours. Must resolve to one year or less — the maximum is 365d or 52w. Use a window or datetimes or timestamps — only one.

units

string

metric

The units the data returns in. One of metric or imperial.

next_token

string

-

The token needed to retrieve the next pagination set. See Pagination below.

Choose one way to specify the time range: the datetime pair (start_datetime / end_datetime), the timestamp pair (start_timestamp / end_timestamp), or a relative window. Combining them returns 422.
A window value must be a positive whole number followed by a single lowercase unit character. Any other form — decimals, negatives, zero, uppercase units, long unit names, whitespace, or a bare number — returns 422.

Example requests

cURL

curl --request GET \
--url 'https://api.zentracloud.io/v5/devices/z6-00930/data?start_datetime=2026-05-29T00%3A00%3A00-00%3A00&end_datetime=2026-05-30T23%3A59%3A00-00%3A00&direction=descending&units=metric' \
--header 'Accept: */*' \
--header 'X-API-Key: YOUR_API_KEY'

curl --request GET \
--url 'https://api.zentracloud.io/v5/devices/z6-00930/data?window=24h&direction=descending&units=metric' \
--header 'Accept: */*' \
--header 'X-API-Key: YOUR_API_KEY'

JavaScript — Fetch

const url = 'https://api.zentracloud.io/v5/devices/z6-00930/data?start_datetime=2026-05-29T00%3A00%3A00-00%3A00&end_datetime=2026-05-30T23%3A59%3A00-00%3A00&direction=descending&units=metric';
const options = {
method: 'GET',
headers: { 'X-API-Key': 'YOUR_API_KEY', Accept: '*/*' }
};

try {
const response = await fetch(url, options);
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}

Python — Requests

import requests

url = "https://api.zentracloud.io/v5/devices/z6-00930/data"
querystring = {
"start_datetime": "2026-05-29T00:00:00-00:00",
"end_datetime": "2026-05-30T23:59:00-00:00",
"direction": "descending",
"units": "metric",
}
headers = {
"X-API-Key": "YOUR_API_KEY",
"Accept": "*/*",
}

response = requests.get(url, headers=headers, params=querystring)
print(response.json())

PHP — cURL

<?php
$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.zentracloud.io/v5/devices/z6-00930/data?start_datetime=2026-05-29T00%3A00%3A00-00%3A00&end_datetime=2026-05-30T23%3A59%3A00-00%3A00&direction=descending&units=metric",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Accept: */*",
"X-API-Key: YOUR_API_KEY",
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}

R — httr

library(httr)

url <- "https://api.zentracloud.io/v5/devices/z6-00930/data"

queryString <- list(
start_datetime = "2026-05-29T00:00:00-00:00",
end_datetime = "2026-05-30T23:59:00-00:00",
direction = "descending",
units = "metric"
)

response <- VERB("GET", url, query = queryString,
add_headers('X-API-Key' = 'YOUR_API_KEY'),
accept("*/*"))

content(response, "text")

Response

A 200 OK returns the device's measurements for the requested window, with a next_token when more pages are available.

metadata

Describes the device the readings belong to.

Field

Type

Description

device_id

string

The unique identifier (serial) of the device.

device_name

string

The device's display name. Defaults to the device_id when no custom name is set.

location

string

The folder path the device sits in, for example Zone/Farm/Plot etc.

coordinates

string

The device's latitude and longitude, comma-separated.

values []

Each item is a single measurement from one sensor port at one point in time. Ordering follows the direction parameter.

Field

Type

Description

port_num

integer

The sensor port the reading came from.

measurement

string

The measured quantity (e.g. Gust Speed).

unit

string

The unit of value, reflecting the requested units (e.g. m/s).

sensor_name

string

The sensor that produced the reading (e.g. ATMOS 41W).

value

number

The measured value. null when there is no value.

timestamp

integer

The reading time as a Unix timestamp (seconds since the epoch, UTC).

datetime

string

The reading time as a human-readable datetime with UTC offset.

error_code

integer

0 when the sensor is reporting normally. Any other value indicates a problem; look it up in Device & Sensor Error Codes.

A reading with a non-zero error_code is still returned — the sensor reported a problem rather than a value, so the row is present with the code attached rather than being dropped.

pagination

Field

Type

Description

num_readings

integer

The number of readings returned on this page.

next_token

string | null

The token to pass on the next request to fetch the following page, or null when there are no more pages. See Pagination below.

start_datetime

string (ISO 8601)

The start of the window covered by this page.

end_datetime

string (ISO 8601)

The end of the window covered by this page.

next_url

string | null

A ready-to-use URL that fetches the next page. Follow it exactly as given. null on the last page.

Example response

{
"metadata": {
"device_id": "A4100123",
"device_name": "JersyField",
"location": "Upper East Field",
"coordinates": "40.6673487, -74.61492299999999"
},
"values": [
{
"port_num": 1,
"measurement": "Gust Speed",
"unit": "m/s",
"sensor_name": "ATMOS 41W",
"value": 0.53,
"timestamp": 1771401600,
"datetime": "2026-02-18 00:00:00-08:00",
"error_code": 0
},
{
"port_num": 1,
"measurement": "Gust Speed",
"unit": "m/s",
"sensor_name": "ATMOS 41W",
"value": 0.57,
"timestamp": 1771400700,
"datetime": "2026-02-17 23:45:00-08:00",
"error_code": 0
}
// ... additional readings omitted for brevity
],
"pagination": {
"num_readings":
97, "next_token":
"AErxaX_LHGoA",
"next_url": "https://api.zentracloud.io/v5/devices/A4100123/data?direction=descending&latest=false&units=metric&next_token=AErxaX_LHGoA",
"start_datetime": "2026-02-17T08:00:00Z",
"end_datetime": "2026-02-18T08:00:00Z" }
}

Pagination

The simplest way to page is to follow next_url. It already carries the correct path, your choices such as units and direction, and the new token — so you do not have to rebuild the URL yourself. Keep following it until it comes back null.

next_url deliberately leaves out the time-window parameters (start_datetime, end_datetime, start_timestamp, end_timestamp, and window). The token already encodes the remaining window and the sort direction, so carrying the original time parameters forward would conflict with it. Because window resolves against the server clock at request time, this also means a paged window is fixed at the first request and does not shift as you follow next_url.

If you would rather build requests yourself, pass the returned next_token back as the next_token parameter.

When requesting data in descending order (newest first), the first page contains only the portion of the current month up to your requested end_datetime or end_timestamp. As a result, this initial page is often smaller than subsequent pages, which each contain a full calendar month of data.

Rate limiting

Rate limited per device, not per user. The budget belongs to the device and is shared by every client reading it, so another integration polling the same device can exhaust it. See Rate Limiting.

HTTP Status Codes

Status

Endpoint-specific cause

403

You lack an Administrator/Editor/User role in the device's organization.

422

Mixing window with datetime or timestamp parameters, mixing datetime and timestamp parameters, a window that resolves to more than one year, a malformed window value, or an otherwise invalid parameter value.

See HTTP Status Codes for the full model, including 401 and 429.

Notes

  • Carry the device_id from List Devices into the path.
  • Timestamps are seconds since the Unix epoch (UTC).

How did we do?

GET List Devices

Contact