Devices API

CRUD for hardware units

A device is a hardware unit emitting measurements. See Concepts for the data model.

List devices

GET /v1/devices?site_id=site_4f3c

Returns:

{
  "data": [
    {
      "id":         "dev_b1d2",
      "site_id":    "site_4f3c",
      "local_id":   "fridge01",
      "name":       "Walk-in fridge",
      "model":      "shelly-h-t-gen3",
      "fw_version": "1.2.4",
      "ingest_url_kind": "shelly_get",
      "last_seen_at":    "2026-05-17T08:22:00Z",
      "online":     true
    }
  ],
  "next_cursor": null,
  "has_more": false
}

Filters: site_id (required unless using account_id), online (boolean), model (substring match).

Create a device

POST /v1/devices
{
  "site_id": "site_4f3c",
  "local_id": "fridge02",
  "name": "Reach-in fridge",
  "model": "diy_esp32"
}

Response includes a freshly issued ingest token (only shown once):

{
  "id": "dev_b1d3",
  "local_id": "fridge02",
  "ingest_token": "ds_live_4f3c1a2b…",
  "ingest_url":   "https://api.opensense.murzin.digital/v1/ingest",
  "issued_at":    "2026-05-17T08:30:00Z"
}

Get a device

GET /v1/devices/dev_b1d2

Update a device

PATCH /v1/devices/dev_b1d2
{ "name": "Walk-in fridge (front)" }

Mutable fields: name, local_id, notes. Immutable after creation: site_id (move via the dedicated move endpoint), model (recreate the device).

Delete a device

DELETE /v1/devices/dev_b1d2

Deletes the device row and revokes its ingest token. Measurements are preserved — they remain attached to the (now-removed) device for the retention period. Reports for periods that include the device's lifetime still include them. This is intentional: HACCP cannot tolerate "fridge 3 disappeared" from the audit trail.

Move a device

POST /v1/devices/dev_b1d2/move
{ "to_site_id": "site_4f8b", "effective_at": "2026-05-17T08:30:00Z" }

Future measurements land under the new site. Past measurements remain under the old site. Reports correctly partition by effective_at.

Rotate ingest token

POST /v1/devices/dev_b1d2/rotate-token

Returns the new token (once). The old token is invalidated immediately. The device's URL changes; you must update it in the device's web UI.

POST /v1/devices/dev_b1d2/identify

If the device supports the cmd/identify MQTT command or the equivalent HTTP downlink, it makes its LED blink for 30 s. Used during installation when you have five identical sensors and want to know which is which. Best-effort; many sensors do not support it.

Errors

HTTPcodeWhen
404device_not_foundWrong id or device belongs to another account
409local_id_takenAnother device on the same site has that local_id
422unknown_modelmodel not in the supported set