Skip to content

Devices & Properties

The flake module is the device tree: every device of the tenant, the services it exposes, and the current value of every property — served from the backend's cache of the last transmissions. Reads never wake a device; writes are queued and confirmed by the device.

{deviceId} accepts the device id or the IMEI throughout. Property ids are canonical hex strings (0x0800).

Reading devices, services and properties

One request returns the whole fleet with all current values:

js
const response = await client.fetch(
    "GET",
    "https://<<URL>>/api/v1/devices?depth=2&expand=propertyType,modifier",
    { accessToken },
);
const devices = await response.json();
json
[
  {
    "crn": "crn#tenant:Ba9mN3pQ.device:A1B2C3D4",
    "imei": "350000000000001",
    "services": [
      {
        "serviceId": "00000000-0000-2001-8003-006d0099ab53",
        "properties": [
          {
            "id": "0x0800",
            "value": 215,
            "measuredAt": 1756800000000,
            "pending": null,
            "propertyType": "UINT16",
            "modifier": { "isReadOnly": true, "isActionable": false, "isVolatile": false, "isError": false, "isMeta": false, "isNull": false }
          }
        ]
      }
    ]
  }
]
  • depth folds the hierarchy into one response: 0 devices only, 1 plus their services, 2 plus every current property. depth=2 is usually all a dashboard needs at startup.
  • expand adds optional per-property fields: propertyType, modifier, transmittedAt, streamData.
  • pending is non-null while a write to that property is still in flight (below).

For a single device or service there are direct routes:

text
GET /api/v1/devices/{deviceId}/services?depth=1
GET /api/v1/devices/{deviceId}/services/{serviceId}/properties
GET /api/v1/devices/{deviceId}/services/{serviceId}/properties/{propertyId}

Human-readable names, units and enums for the raw values come from schemas; display names and locations from metadata.

Writing property values

Writes go through REST and are asynchronous by default — the backend queues the value for the device:

text
PUT /api/v1/devices/{deviceId}/services/{serviceId}/properties/0x0801
js
await client.fetch(
    "PUT",
    "https://<<URL>>/api/v1/devices/A1B2C3D4/services/00000000-0000-2001-8003-006d0099ab53/properties/0x0801",
    {
        accessToken,
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ value: 3 }),
    },
);

How to reason about a write:

  • The property's pending field is set immediately and stays non-null until the device confirms. Render pending state in your UI instead of optimistically showing the new value.
  • The confirmation is the next OBJECT_UPDATED event for that service carrying the property — the same path every other value change takes. There is no separate "write succeeded" event.
  • ?immediate=true makes the write fail fast with an offline error instead of queueing when the device is not connected — for interactions where "later" is worse than "not at all".
  • ?retries= controls how often the backend retries delivery.
  • Several properties of one service can be written in one request: PUT …/properties with [ { "id": "0x0801", "value": 3 }, … ].

Values follow the property's type; INT64/UINT64 travel as decimal strings, BIN/UUID as base64. Details: flake module reference.

Calling device methods

Where a schema defines methods for a service, you can invoke them by name — this is v5's replacement for addressing things by schema names in URLs:

text
POST /api/v1/devices/{deviceId}/services/{serviceId}/messages/{name}
js
const response = await client.fetch(
    "POST",
    "https://<<URL>>/api/v1/devices/A1B2C3D4/services/00000000-0000-2001-8003-006d0099ab53/messages/reboot",
    {
        accessToken,
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ params: [] }),
    },
);

Unlike property writes, a method call is synchronous: the device must be online, the call waits for the device's answer, and the response carries the properties the device returned (or an error outcome). Each parameter states its own id, type and value — the schema's method definition tells you which parameters a method takes.

Reference: POST /devices/…/messages/{name}.