Devices (status + listing)

Read device status and metadata across your org.

List — GET /v1/devices

Returns 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

ParamTypeDefaultNotes
nsstringFilter to one namespace.
statusstringonline, offline, never_online.
sortlast_heartbeat_at / connected_at / first_registered_atlast_heartbeat_at
orderasc / descdesc
limitint50Max 200.
offsetint0

Single — 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-a3f8b2c4e6d8

Status taxonomy

statusMeans
onlineMQTT session is currently up.
offlineWas online; currently disconnected.
never_onlineDevice is provisioned (cert minted) but has never connected to the broker yet.
unknownDefensive 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_at and walk forward with offset to 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_version is reported by the device. Libscadable v0.1.0+ stamps the running library version; your app can add a different field via scadable_mqtt_publish to a custom topic.