Devices (status + listing)
Read device status and metadata across your org.
List — GET /v1/devices
GET /v1/devicesReturns devices in the API key's org, with derived status.
curl -H "Authorization: Bearer scd_live_..." \
"https://api.scadable.com/v1/devices?status=online&limit=50"Query parameters
| Param | Type | Default | Notes |
|---|---|---|---|
ns | string | — | Filter to one namespace. |
status | string | — | online, offline, never_online. |
sort | last_heartbeat_at / connected_at / first_registered_at | last_heartbeat_at | |
order | asc / desc | desc | |
limit | int | 50 | Max 200. |
offset | int | 0 |
Single — GET /v1/devices/{cn}
GET /v1/devices/{cn}{cn} is the device's certificate Common Name (SC-<device_id>).
curl -H "Authorization: Bearer scd_live_..." \
https://api.scadable.com/v1/devices/SC-a3f8b2c4e6d8Status taxonomy
status | Means |
|---|---|
online | MQTT session is currently up. |
offline | Was online; currently disconnected. |
never_online | Device is provisioned (cert minted) but has never connected to the broker yet. |
unknown | Defensive fallback if the underlying state machines are in a transient state we don't model. |
The status field is derived; the underlying provisioning_status (e.g. provisioned, flashed, operational) is also included for power users.
Response shape
{
"cn": "SC-a3f8b2c4e6d8",
"device_id": "a3f8b2c4e6d8",
"namespace_id":"ns_...",
"org_id": "org_...",
"status": "online",
"provisioning_status": "operational",
"connected_at": 1748678400,
"disconnected_at": 0,
"last_heartbeat_at": 1748678430,
"last_edge_hit_at": 1748678400,
"first_registered_at": 1748600000,
"ip": "192.168.1.42",
"firmware_version": "0.2.0",
"uptime_seconds": 1234,
"free_heap_bytes": 187392,
"current_broker_id": "yyz",
"preferred_region": "yyz"
}Empty / zero fields are omitted to keep responses small for big orgs.
How to detect "the device just went offline"
The API is poll-only in v1 — no push for status changes. Two reliable patterns:
1. Poll the list endpoint
import time
import requests
while True:
r = requests.get(
"https://api.scadable.com/v1/devices",
headers={"Authorization": "Bearer scd_live_..."},
params={"sort": "last_heartbeat_at"},
)
for d in r.json():
# Alert if a device that was online stops heartbeating
if d["status"] != "online":
alert_user(d)
time.sleep(30)Cadence of 30–60 seconds is fine — heartbeats happen every 30 seconds by default, so you'll catch state changes in roughly the same window.
2. Tail the MQTT stream
Connect to WS /v1/mqtt/stream and watch for missing heartbeats. The stream is real-time — no polling latency. Slightly more code, but the response is instant. See MQTT stream.
Tips
- Pagination on big orgs. Sort by
first_registered_atand walk forward withoffsetto enumerate the whole fleet deterministically. - CN is stable. A device's CN never changes after provisioning — use it as the durable identifier in your downstream tools.
firmware_versionis reported by the device. Libscadable v0.1.0+ stamps the running library version; your app can add a different field viascadable_mqtt_publishto a custom topic.
Updated 10 days ago
