Skip to main content
Table of Contents

GET List Devices

Discover the devices your API key can access with GET /v5/devices — query parameters, response fields, organization filtering, pagination, and the expand option.

Table of Contents

GET /v5/devices

Returns a list of every device the authenticated API key can access — so you can discover device IDs without knowing any of them in advance. Use this endpoint to build a device picker, or to gather the device_id values you'll pass to other v5 endpoints (for example, when pulling readings with Get Device Readings).

The list reflects your memberships: it includes devices from organizations you belong to as well as devices shared with you through individual workspaces. You can optionally scope the list to a single organization, page through large result sets, and opt in to extra per-device detail — measurement dates, logging settings, ports, hardware, connectivity, and subscription status.

Authentication

Authenticated with your API key in the X-API-Key header; the user is resolved from the key. See Authentication in the Overview.

Request

GET https://api.zentracloud.io/v5/devices

Query parameters

Parameter

Type

Required

Default

Description

organization_id

string

No

-

Restricts the list to a single organization. If omitted, the response includes devices across every organization and workspace you can access. See Filtering by organization below.

page_num

integer

No

1

The page of results to return. 1-indexed; must be ≥ 1.

limit

integer

No

50

The maximum number of devices per page. Must be between 1 and 1000.

expand

string

No

-

Attaches extra data to each device. Supplied as a single comma-separated list (repeated expand parameters are not supported). Supported values: max_min_timestamp, settings, hardware, connectivity, subscription, ports.

units

string

No

metric

Unit system for dimensioned fields, currently a port's position. One of metric or imperial.

Example requests

Basic list:

curl "https://api.zentracloud.io/v5/devices" \
-H "X-API-Key: YOUR_API_KEY"

Filter to one organization:

curl "https://api.zentracloud.io/v5/devices?organization_id=c042f395-8466-459b-8b61-7b26557851da" \
-H "X-API-Key: YOUR_API_KEY"

Request a second page of 100 devices:

curl "https://api.zentracloud.io/v5/devices?page_num=2&limit=100" \
-H "X-API-Key: YOUR_API_KEY"

Include each device's measurement range:

curl "https://api.zentracloud.io/v5/devices?expand=max_min_timestamp" \
-H "X-API-Key: YOUR_API_KEY"

Include several expanded objects at once:

curl "https://api.zentracloud.io/v5/devices?expand=max_min_timestamp,settings,hardware,connectivity,subscription" \
-H "X-API-Key: YOUR_API_KEY"

Response

A 200 OK response contains a devices array and a pagination object.

devices[ ]

Each item represents one device. Devices are ordered by device ID (serial number) ascending.

Base fields (always present):

Field

Type

Description

device_id

string

The unique identifier (serial) for the device. Use this value when calling other v5 endpoints.

name

string

The device's display name. When no custom name has been set, this defaults to the device_id.

organization_id

string (UUID)

The organization the device belongs to.

organization_name

string

The display name of the organization the device belongs to. An empty string "" when the organization has no name set.

device_type

integer

Numeric code identifying the specific device version. A single model can have more than one device_type . Use device_type to distinguish versions programmatically.

model

string | null

Human-readable model name derived from device_type (e.g. ATMOS 41W, ZL6). null if the device's device_type is not yet registered.

Expanded fields An expand group's key appears only when you request it.

Field

Type

Present when

Description

data_range

object

expand=max_min_timestamp

First and last measurement timestamps. See max_min_timestamp below.

settings

object

expand=settings

Logging and upload configuration. See settings below.

hardware

object

expand=hardware

Firmware and hardware revision. See hardware below.

connectivity

object

expand=connectivity

Communications module and host server. See connectivity below.

subscription

object

expand=subscription

Subscription status and expiration. See subscription below.

ports

array

expand=ports

Per-port sensor configuration. See ports below.

pagination

Field

Type

Description

page_num

integer

The page number you requested. The response always echoes the requested page.

limit

integer

The maximum number of devices per page.

num_devices

integer

The number of devices returned on this page.

total_pages

integer

The total number of pages available for your full accessible set at the current limit.

Note: num_devices is the count for the current page, not a total across all pages. The endpoint does not return an exact total device count; use total_pages to iterate.

Example response

A base response (no expand).

{
"devices": [
{
"device_id": "A4100001",
"name": "A4100001",
"organization_id": "c042f395-8466-459b-8b61-7b26557851da",
"organization_name": "Forks",
"device_type": 181,
"model": "ATMOS 41W"
},
{
"device_id": "A4100002",
"name": "Butterriver",
"organization_id": "c042f395-8466-459b-8b61-7b26557851da",
"organization_name": "Forks",
"device_type": 181,
"model": "ATMOS 41W"
}
// ... additional devices omitted for brevity
],
"pagination": {
"page_num": 1,
"limit": 50,
"num_devices": 13,
"total_pages": 1
}
}

A fully expanded response

(expand=max_min_timestamp,settings,hardware,connectivity,subscription):

{
"devices": [
{
"device_id": "A4100110",
"name": "A4100110",
"organization_id": "1ee7f222-e5d8-4ace-ba71-039143727293",
"organization_name": "Forks",
"device_type": 181,
"model": "ATMOS 41W",
"data_range": {
"first_measurement": 1670611500,
"last_measurement": 1784664000
},
"settings": {
"logging_interval": 10,
"upload_frequency": 60,
"upload_hours": {
"enabled_count": 24,
"all_hours": true
}
},
"hardware": {
"firmware_version": 1.17,
"hardware_revision": null
},
"connectivity": {
"connectivity_type": "cellular",
"module": "4G LTE-M and NB-IoT (SARA-R410M)",
"module_code": "SARA-R410M",
"sim": "89148000007474115272",
"host_server": "in.zentracloud.io",
"pending_host_server": null
},
"subscription": {
"status": "exempt",
"exempt_reason": "dev",
"expiration_date": 1779346800,
"auto_renew": false,
"high_data": false
}
}
// ... additional devices omitted for brevity
],
"pagination": {
"page_num": 1,
"limit": 50,
"num_devices": 4,
"total_pages": 1
}
}

Empty result

If your memberships grant access to no devices (or no devices in a filtered organization), the response is still 200 with an empty array and a valid pagination block:

{
"devices": [],
"pagination": {
"page_num": 1,
"limit": 50,
"num_devices": 0,
"total_pages": 0
}
}

Filtering by organization

Pass organization_id to restrict the list to a single organization.

  • If you are a member of that organization, the response is 200 and every returned device belongs to it.
  • If you have only workspace-level access in that organization (no full-organization membership), the response is still 200, restricted to the devices shared with you through your workspace(s) there. Workspace access counts as membership.
  • If you are not a member of the organization at all, the response is 403 Forbidden — never a silently empty 200. This lets you distinguish "you don't have access" from "you have access, but there are no devices."

Pagination

The list is paginated with page_num and limit, ordered by device ID ascending across your entire accessible set. Because the ordering is stable, iterating page_num=1, 2, 3, … at a fixed limit neither skips nor repeats devices.

  • page_num is 1-indexed and defaults to 1.
  • limit defaults to 50 and can be set from 1 to 1000.
  • Requesting page_num below 1, limit below 1, or limit above 1000 returns 422 before any device lookup runs.
  • To page through everything, start at page_num=1 and continue until you reach total_pages.

The expand parameter

By default the response contains only the base device fields. Add one or more expand values to attach extra objects to each device. Multiple values are supplied as a single comma-separated list (?expand=max_min_timestamp,settings); repeated expand parameters are not supported. Unrecognized values return 422 and identify the offending value.

Supported values: max_min_timestamp, settings, hardware, connectivity, subscription , ports.

An expand group's key appears only when you request it. When you do request it, the key is always present even if the device has no data for it — the inner fields come back null. That way you can tell "not requested" apart from "no data".

max_min_timestamp

Attaches a data_range object describing when the device first and last produced a measurement.

Field

Type

Description

first_measurement

integer | null

Unix timestamp (whole seconds since the epoch, UTC) of the device's first measurement, or null if it has never produced one.

last_measurement

integer | null

Unix timestamp (whole seconds since the epoch, UTC) of the device's most recent measurement, or null if it has never produced one.

Timestamps are seconds since the Unix epoch (UTC). For example, 1643390100 is January 28, 2022 at 17:15 UTC. A device that has never produced a measurement returns data_range with both values null.

settings

Attaches a settings object describing the device's logging and upload configuration.

Field

Type

Description

logging_interval

integer

How often the device records a measurement, in minutes.

upload_frequency

integer

How often the device uploads recorded data, in minutes.

upload_hours

object

Which hours of the day the device is permitted to upload. See below.

upload_hours.enabled_count

integer

The number of hours per day during which uploads are enabled (0–24).

upload_hours.all_hours

boolean

true when uploads are enabled for all 24 hours; false when restricted to a subset.

hardware

Attaches a hardware object describing the device's firmware and hardware revision.

Field

Type

Description

firmware_version

number | null

The firmware version currently running on the device. null when it cannot be determined (for example, a device that has not reported).

hardware_revision

string | null

Reserved. Currently always null; population is planned for a future release. To distinguish hardware versions today, use the base device_type field.

connectivity

Attaches a connectivity object describing how the device communicates and where it sends data.

Field

Type

Description

connectivity_type

string | null

The device's connectivity method: cellular or wifi. (radio is reserved and not currently produced.) null when connectivity cannot be determined.

module

string | null

Human-readable description of the communications module (e.g. 4G LTE-M and NB-IoT (SARA-R410M)), or null when unavailable.

module_code

string | null

Short identifier for the communications module (e.g. SARA-R410M). null when the module has no part number (such as older 2G/3G modules) or is unknown.

sim

string | null

The device's SIM identifier (ICCID) for cellular devices, or null when none is present.

host_server

string | null

The hostname the device currently uploads to (e.g. in.zentracloud.io), or null when unavailable.

pending_host_server

string | null

The hostname of a pending host-server change, or null when no change is queued. A non-null value is the signal that a server migration is in progress.

subscription

Attaches a subscription object describing the device's data-subscription status.

Field

Type

Description

status

string

The subscription status: active (a current, unexpired subscription), inactive (expired or never set), or exempt (exempted by METER from requiring a paid subscription; see exempt_reason).

exempt_reason

string | null

When status is exempt, an internal designation for why the device was exempted — one of dev, marketing, sales, support, loaner, demo, or other. Set by METER support and read-only here; informational only. null when the device is not exempt.

expiration_date

integer | null

Unix timestamp (whole seconds since the epoch, UTC) when the subscription expires, or null when no expiration date is set.

auto_renew

boolean

Whether the subscription is set to renew automatically.

high_data

boolean

true when the device is on a high-data-volume subscription plan.

Exemptions apply mostly to METER's own internal devices, though occasionally a customer device is exempted by METER support. Either way, the exemption is set internally and cannot be changed through the API.

ports

Attaches a ports array, one entry per configured port

Field

Type

Description

port_num

integer

The port number on the device.

sensor_id

integer

Numeric identifier for the sensor on that port.

sensor_short_name

string

The sensor model, e.g. TEROS 12.

position

object/null

Object with value and unit. The value is signed: negative is below ground (a depth), positive is above ground (a height). unit follows the units parameter (cm metric, in imperial). null for multi-depth sensors and when no position is set.

calibration

string/null

Name of the soil water content calibration applied to this port's data, e.g. Mineral. null for sensors that are not soil moisture sensors.

Notes on expand
  • When expand is not supplied, all expanded objects are omitted from every device and no extra computation is performed.
  • expand accepts multiple values as a single comma-separated list (e.g. ?expand=max_min_timestamp,settings). Repeated expand parameters are not supported.
  • Passing an unrecognized expand value returns 422 and identifies the offending value.

Rate limiting

Rate limited per user, not per device. Requests beyond your limit return 429. See Rate Limiting for the burst and steady-state figures.

HTTP Status Codes

Status

Endpoint-specific cause

403

Passing an organization_id you have no membership in.

422

page_num < 1, limit outside 1–1000, an unrecognized expand value, or a repeated expand parameter. The error names the offending value. Rejected before any device lookup runs.

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

Notes

  • Results are scoped to your memberships, so the same request made by two different users can return different devices.
  • device_id is the value to carry into other v5 API calls; name is for display only and may change.

How did we do?

Device & Sensor Error Codes

GET Device Readings

Contact