This is the reference for what a device publishes and subscribes to. Connection, login and session rules are in MQTT. HTTP devices use the same payloads; see Device HTTP API.
Topics of the default scheme
All topics start with v1/. Use QoS 1.
| Direction | Topic | Use | Page |
|---|---|---|---|
| Up | v1/telemetry | Telemetry | below |
| Up | v1/attributes | Client attributes | Attributes |
| Up | v1/attributes/req/{id} | Ask for attributes | Attributes |
| Down | v1/attributes/res/{id} | Answer to an attribute request | Attributes |
| Down | v1/attributes/set | Shared attribute changes, including firmware offers (fw_*) | Firmware updates (OTA) |
| Down | v1/rpc/req/{id} | Command from the cloud | Sending commands to devices |
| Up | v1/rpc/res/{id} | Answer to a command | same |
| Up | v1/rpc/up/req/{id} | Request from the device to the cloud | same |
| Down | v1/rpc/up/res/{id} | Answer to a device request | same |
| Up | v1/provision/req | Provisioning request (provisioning session only) | Adding and claiming devices |
| Down | v1/provision/res | Provisioning answer | same |
| Up | v1/hello | The device’s self-description (licensed devices) | Licensed devices |
| Up | v1/csr | Certificate signing request (licensed devices) | Device certificates |
| Down | v1/cert | The issued certificate | same |
| Up | v1/claim | Open or close the claim window (licensed devices) | Adding and claiming devices |
| Up | v1/gw/connect, v1/gw/disconnect, v1/gw/telemetry, v1/gw/attributes, v1/gw/attributes/req (In development) | Gateways only: report for child devices | Devices behind a gateway |
| Down | v1/gw/attributes, v1/gw/attributes/res, v1/gw/rpc | Gateways only; In development (commands and shared attributes to child devices) | same |
A device may subscribe only to its downlink topics: v1/attributes/set, v1/attributes/res/+, v1/rpc/req/+, v1/rpc/up/res/+ and v1/cert, plus v1/gw/attributes, v1/gw/rpc and v1/gw/attributes/res for gateways. A device never receives another device’s messages.
Refused topics
| Published to | Result |
|---|---|
An unknown topic under v1/ | Rejected as unknown_reserved_topic, never stored. |
A downlink topic, v1/gw/* from a device that is not a gateway, or v1/provision/req outside a provisioning session | Rejected as forbidden_topic. |
Both are acknowledged and dropped. Three rejected topics in a minute close the session.
Connect sequence
CONNECT
SUBSCRIBE v1/attributes/set (QoS 1)
SUBSCRIBE v1/attributes/res/+ (QoS 1)
SUBSCRIBE v1/rpc/req/+ (QoS 1)
SUBSCRIBE v1/rpc/up/res/+ (QoS 1, only if the device sends requests)
PUBLISH v1/attributes/req/1 {} catch-up: all shared attributes
PUBLISH v1/attributes current state
PUBLISH v1/telemetry buffered data first, then live data
Legacy compatible topics
Profiles with the Legacy compatible scheme also accept:
| Direction | Topic |
|---|---|
| Up | v1/devices/me/telemetry |
| Up and down | v1/devices/me/attributes |
| Up | v1/devices/me/attributes/request/{id} |
| Down | v1/devices/me/attributes/response/{id} |
They carry no commands, claiming, provisioning or gateway topics.
Custom topics
Profiles with Custom topics accept any topic outside v1/ as telemetry of the device:
- A JSON object becomes keys. Anything else (a number, an array, text, binary) becomes the single key
raw, as its text, up to the profile’s Max raw payload (bytes) (4,096 by default). - The topic must stay within the profile’s Max topic depth (8), Max topic length (128) and Distinct topics per device (50).
- With Prefix keys with the topic, each key is stored as
<topic>.<key>: the topic’s/become., other characters outside the key rule become_. For examplesite1/boilerandtempgivesite1.boiler.temp. A joined key over 64 characters is dropped. Without the prefix, the same key from two topics overwrites itself.
Telemetry payload forms
Telemetry is JSON, UTF-8.
Form A, a flat object. One record, stamped with the time Hermetry received it:
{"temperature": 21.5, "humidity": 40, "door_open": false}
Form B, an object with exactly ts and values. One record at ts:
{"ts": 1759572000000, "values": {"temperature": 21.5, "humidity": 40}}
Form C, an array of form A and form B objects. One record per element, in order:
[
{"ts": 1759572000000, "values": {"sys.cpu_load": 0.42}},
{"ts": 1759572060000, "values": {"sys.cpu_load": 0.38}},
{"net.wan.up": true}
]
Not JSON. A body that is not JSON is stored as one raw key on the default telemetry topic. A JSON scalar (42, "on") on v1/telemetry is refused (bad_form).
An object with ts and values plus any other member is form A, not form B: all its members become keys.
Time stamps
tsis an integer: milliseconds since the Unix epoch, UTC.- A device without a synchronised clock must use form A. It must not invent a time stamp.
- Records more than 10 minutes in the future, or older than your telemetry retention, are dropped. They are never moved to another time.
- Duplicates of the same device, key and time are stored once.
See Timestamps, late and duplicate readings.
Keys
- Pattern:
^[A-Za-z0-9_.\-]{1,64}$. Keys are case-sensitive:abcandABCare two keys. - Refused in telemetry: keys that start with
_,fw_,current_fw_orcfg.. - Tip: use dot-separated lower-case names, for example
net.wan.up.
A bad key drops that key only; the rest of the record is kept.
Values
| JSON value | Stored as | Rule |
|---|---|---|
| Integer | long | Above ±2^53, send it as a string. |
| Fraction | double | NaN and Infinity are not JSON and are refused. |
true / false | boolean | Charts read numbers: send 0/1 when you want a history. |
| String | string | Up to 1,024 characters. Shown as the latest value, not charted. |
| Object or array | JSON | Up to 4 KiB, stored as it is. |
null | nothing | Means “no reading”. It does not delete anything. |
A bad value drops that key only.
Size
- One message: up to 64 KiB and up to 1,000 key-value points. More points drop the whole message; a larger message is dropped whole. The connection stays up.
- Nesting depth: up to 8 levels.
- Batch your messages when you send more than one sample per second.
Client attributes
PUBLISH v1/attributes
{"current_fw_title": "boiler-fw", "current_fw_version": "26.10.2", "lan.ip": "192.168.1.1"}
Attribute keys may be up to 128 characters. See Attributes.
Commands
PUBLISH v1/rpc/req/42 (down)
{"method": "sys.ping", "params": {"host": "8.8.8.8", "count": 3}}
PUBLISH v1/rpc/res/42 (up)
{"ok": true, "result": {"sent": 3, "received": 3, "avg_ms": 18.2}}
PUBLISH v1/rpc/up/req/5 (up)
{"method": "app.request", "params": {}}
Provisioning
username: provision, password: empty
SUBSCRIBE v1/provision/res
PUBLISH v1/provision/req
{"deviceName": "boiler-07", "provisionDeviceKey": "pk_…", "provisionDeviceSecret": "ps_…"}
What counts as a message
Each accepted telemetry or attribute publish counts once toward your monthly message quota, whatever it holds. Command answers, connection events and alarms do not count. One message with 50 readings costs the same as one with a single reading, so batching saves quota.

