MQTT API definitions for ESP RainMaker Neo platform for nodes.
This spec documents every MQTT topic a node publishes to or subscribes to, including AWS IoT Core managed topics.
from_cloud (required before reporting online = true)to_cloud with events: getGroupInfo, getAlexaEn, getGVAEn, getSchedVer, getTriggerVer (optionally getTimeSync for a fast coarse clock sync while SNTP converges)from_cloud response → derive {groupInfoStr}user/params-{groupInfoStr}/paramsgroups/{groupId}/control and per-subgroup groups/{groupId}/subgroups/{subgroupId}/controlsetNodeConfig via to_cloudfrom_cloud subscribed, params topic(s) subscribed) → report online: true to both shadowsOnline flag: Node sets online = true only after the above; cloud sets online = false when the device disconnects (e.g. presence). The node does not publish online = false; it may clear local online state on disconnect.
AWS IoT Core endpoint (region-specific, TLS mutual auth)
X.509 certificate-based mutual TLS authentication with AWS IoT Core.
Each node has a unique certificate issued and registered by the ESP RainMaker Neo platform.
The IoT policy restricts topics to ${iot:Connection.Thing.ThingName} and
${iot:Connection.Thing.Attributes[group_id]} for group control.
Devices connect using TLS mutual authentication.
[AWS IoT Core → Cloud] Node connection lifecycle event (auto-generated).
AWS IoT Core lifecycle event — node connected
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
Accepts the following message:
AWS IoT Core connection lifecycle event
{
"clientId": "ABCDEF1234567890",
"eventType": "connected",
"principalIdentifier": "6cf12df543fe301f65b52632c8a59b743467db17bae30ce74120663e96736ff3",
"sessionIdentifier": "adecf6af-2abd-4f23-8309-cf9257de3fa0",
"timestamp": 1743656583784,
"versionNumber": 0,
"ipAddress": "203.0.113.42"
}
[AWS IoT Core → Cloud] Node disconnection lifecycle event (auto-generated).
AWS IoT Core lifecycle event — node disconnected
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
Accepts the following message:
AWS IoT Core disconnection lifecycle event
{
"clientId": "ABCDEF1234567890",
"eventType": "disconnected",
"principalIdentifier": "6cf12df543fe301f65b52632c8a59b743467db17bae30ce74120663e96736ff3",
"sessionIdentifier": "adecf6af-2abd-4f23-8309-cf9257de3fa0",
"timestamp": 1743656583784,
"versionNumber": 0,
"disconnectReason": "CLIENT_INITIATED_DISCONNECT"
}
[Node → Cloud] Unified channel for all node-initiated events.
$aws/rules/node_to_cloud_rule/rainmaker/nodes/<node_id>/to_cloud to save costs.
Node publishes event requests to the cloud
Node sends one or more named events (get/set) to the cloud.
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
Accepts the following message:
Node-to-cloud event request
The node publishes one or more named events. set events carry a payload;
get events are name-only (the cloud returns the data in from_cloud).
Typical first message after MQTT connect
{
"event": [
"getGroupInfo",
"getAlexaEn",
"getGVAEn",
"getSchedVer",
"getTriggerVer",
"getTimeSync"
]
}
Node reports changed node configuration
{
"event": [
"setNodeConfig"
],
"setNodeConfig": {
"node_id": "ABCDEF1234567890",
"config": {
"data_model": "default",
"devices": [
{
"id": "Light",
"type": "esp.device.lightbulb",
"primary": "Power",
"params": [
{
"id": "Power",
"type": "esp.param.power",
"data_type": "bool",
"ui_type": "esp.ui.toggle",
"properties": [
"read",
"write"
]
},
{
"id": "Brightness",
"type": "esp.param.brightness",
"data_type": "int",
"ui_type": "esp.ui.slider",
"properties": [
"read",
"write",
"time_series",
"indexed"
],
"bounds": {
"min": 0,
"max": 100,
"step": 1
}
}
]
}
],
"services": [],
"info": {
"name": "Smart Light",
"type": "esp.node.light",
"fw_version": "2.1.0",
"model": "LED_Smart_v2"
}
}
}
}
Node reports a Matter node config. `i` (indexed) and `ts` (timeseries) may overlap — attr `0x0` below is both. `v` holds config-only values; `a` lists remaining plain attributes and is omitted for clusters exposing only config-only attrs (cluster `0x1d`).
{
"event": [
"setNodeConfig"
],
"setNodeConfig": {
"node_id": "62356B4758474E74",
"config": {
"data_model": "matter",
"endpoints": {
"0x1": {
"c": {
"s": {
"0x6": {
"a": [
"0xfffc",
"0xfffd"
],
"i": [
"0x0",
"0x4000"
],
"ts": [
"0x0"
],
"v": {
"0x10": 42
}
},
"0x1d": {
"v": {
"0x0": 7
}
}
}
}
}
},
"info": {
"type": "smartlight-mtr-app",
"fw_version": "1.0.0"
}
}
}
}
Hello handshake combined with schedule check
{
"event": [
"hello",
"getSchedVer",
"getTriggerVer"
],
"hello": {
"id": "hello-001"
}
}
[Cloud → Node] Unified channel for cloud responses and unsolicited events. Subscribed immediately after MQTT connect (first subscription).
Node receives event responses and unsolicited pushes from the cloud
Cloud sends event responses (e.g. group info, schedule details) and unsolicited pushes (e.g. updated schedule/trigger versions) to the node.
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
Accepts the following message:
Cloud-to-node event response
Cloud returns event payloads keyed by event name.
set events return { "status": "success" } or { "status": "error", "message": "..." }.
get events return event-specific data.
Events may arrive unsolicited (e.g. schedule push after user edits).
Cloud responds to node startup handshake
{
"event": [
"getGroupInfo",
"getAlexaEn",
"getGVAEn",
"getSchedVer",
"getTriggerVer",
"getTimeSync"
],
"getGroupInfo": {
"pgrp": "grp_abc123",
"subgrps": [
"sub_room1",
"sub_floor2"
]
},
"getAlexaEn": {
"enabled": true
},
"getGVAEn": {
"enabled": false
},
"getSchedVer": {
"version": 3
},
"getTriggerVer": {
"version": 2
},
"getTimeSync": {
"time": 1768464000912
}
}
Cloud pushes updated schedule details (may be unsolicited)
{
"event": [
"getSchedDetails"
],
"getSchedDetails": {
"version": 3,
"Schedules": [
{
"name": "MorningLights",
"enabled": true,
"triggers": [
{
"m": 420,
"d": 31
}
],
"action": {
"Light": {
"Power": true,
"Brightness": 80
}
},
"validity": {
"start": 1704067200,
"end": 1735689600
}
},
{
"name": "MatterMorning",
"enabled": true,
"triggers": [
{
"m": 420,
"d": 31
}
],
"action": {
"0x1": {
"c": {
"s": {
"0x6": {
"c": {
"0x1": "0x1518"
}
}
}
}
}
}
}
]
}
}
Cloud pushes automation triggers
{
"event": [
"getTriggerDetails"
],
"getTriggerDetails": {
"version": 2,
"triggers": [
{
"id": "node~temp-high",
"enabled": true,
"path": "Sensor.Temperature",
"operator": "gt",
"value": 30
},
{
"id": "node~light-on",
"path": "Light.Power",
"operator": "eq",
"value": true
},
{
"id": "node~matter-light-on",
"path": "0x1.c.s.0x6.a.0x0",
"operator": "eq",
"value": true
}
]
}
}
Cloud returns the sanitized server config fetched from S3
{
"event": [
"getServerConfig"
],
"getServerConfig": {
"rmng-base": {
"IoTEndpointUrl": "<iot-endpoint-prefix>-ats.iot.<region>.amazonaws.com",
"ApiGatewayUrl": "https://<api-id>.execute-api.<region>.amazonaws.com/prod/",
"UserPoolId": "<region>_XXXXXXXXX",
"IdentityPoolId": "<region>:00000000-0000-0000-0000-000000000000",
"CredentialProviderEndpoint": "<credential-provider-prefix>.credentials.iot.<region>.amazonaws.com",
"NodeFileRoleAliases": "rmng-node-file-role-v1",
"NodeVideoRoleAliases": "rmng-node-video-role-v1"
}
}
}
[Cloud → Node] Unicast parameter control. Subscribed after group info is received. User/app-initiated commands.
Node receives user-initiated parameter control commands (unicast)
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
Group info string: <group_id>[-<sub1>-<sub2>-…] with subgroups sorted alphabetically.
Empty string if node is unassociated (e.g. shadow name becomes params-).
Accepts the following message:
Unicast parameter update command to node
User/app-initiated parameter changes delivered to a single node.
Default data model: device name → { param name → value }.
Matter data model: endpoint hex → { c → { s|c → { cluster hex → { c → { command hex → TLV hex } } } } }.
{
"Light": {
"Power": true,
"Brightness": 75
}
}
{
"0x1": {
"c": {
"s": {
"0x6": {
"c": {
"0x2": "0x1518"
}
}
}
}
}
}
[Cloud → Node] Group broadcast control (device-type addressed). All nodes in the group receive this message; each node applies the payload only to its own devices whose type matches a top-level key.
Node receives device-type-addressed control commands for the group
Available only on servers:
6-character alphanumeric primary group ID
Accepts the following message:
Control command broadcast to all nodes in a group or subgroup
Control payload broadcast on rainmaker/nodes/groups/{groupId}/control (group)
or rainmaker/nodes/groups/{groupId}/subgroups/{subgroupId}/control (subgroup).
Default data model: top-level keys are device types (e.g.
esp.device.light). Each device's value is an object that holds nested
sub-keys describing what to apply — currently only params is defined,
with room for additional sub-keys (e.g. cmd, meta) in future without
another topic rename. Nodes apply the payload only to their own devices
that match the listed device types; other devices are ignored.
Matter data model: command invocations only. Same nested structure as
the unicast ParamControl message, except the top-level endpoint key is the
wildcard endpoint "0xffff" (not a specific endpoint): 0xffff → c →
s|c → cluster → c → { command hex → TLV hex }. Each node invokes the
command on every endpoint that supports the addressed cluster + command,
resolved from its own support list.
Default: map of device type → control envelope. Matter: the unicast ParamControl command structure.
{
"esp.device.light": {
"params": {
"esp.param.power": true
}
}
}
{
"esp.device.light": {
"params": {
"esp.param.power": true,
"esp.param.brightness": 75
}
},
"esp.device.fan": {
"params": {
"esp.param.power": false
}
}
}
{
"*": {
"params": {
"esp.param.power": false
}
}
}
{
"0xffff": {
"c": {
"s": {
"0x6": {
"c": {
"0x2": "0x1518"
}
}
}
}
}
}
[Cloud → Node] Subgroup-specific control (device-type addressed). One subscription per subgroup the node belongs to.
Node receives device-type-addressed control commands for a specific subgroup
Available only on servers:
6-character alphanumeric primary group ID
3-character alphanumeric individual subgroup ID
Accepts the following message:
Control command broadcast to all nodes in a group or subgroup
Control payload broadcast on rainmaker/nodes/groups/{groupId}/control (group)
or rainmaker/nodes/groups/{groupId}/subgroups/{subgroupId}/control (subgroup).
Default data model: top-level keys are device types (e.g.
esp.device.light). Each device's value is an object that holds nested
sub-keys describing what to apply — currently only params is defined,
with room for additional sub-keys (e.g. cmd, meta) in future without
another topic rename. Nodes apply the payload only to their own devices
that match the listed device types; other devices are ignored.
Matter data model: command invocations only. Same nested structure as
the unicast ParamControl message, except the top-level endpoint key is the
wildcard endpoint "0xffff" (not a specific endpoint): 0xffff → c →
s|c → cluster → c → { command hex → TLV hex }. Each node invokes the
command on every endpoint that supports the addressed cluster + command,
resolved from its own support list.
Default: map of device type → control envelope. Matter: the unicast ParamControl command structure.
{
"esp.device.light": {
"params": {
"esp.param.power": true
}
}
}
{
"esp.device.light": {
"params": {
"esp.param.power": true,
"esp.param.brightness": 75
}
},
"esp.device.fan": {
"params": {
"esp.param.power": false
}
}
}
{
"*": {
"params": {
"esp.param.power": false
}
}
}
{
"0xffff": {
"c": {
"s": {
"0x6": {
"c": {
"0x2": "0x1518"
}
}
}
}
}
}
[Node → AWS IoT Shadow] Named shadow update (group-scoped).
Contains full reported state of all node parameters, online status, config version, and notify settings.
Shadow name: params-{groupInfoStr}.
Node reports full/delta state to the named (group-scoped) shadow
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
Group info string: <group_id>[-<sub1>-<sub2>-…] with subgroups sorted alphabetically.
Empty string if node is unassociated (e.g. shadow name becomes params-).
Accepts the following message:
Node reports state to named shadow
Shadow name: params-{groupInfoStr}.
Contains reported node params, online status, config version, and notify metadata.
Delta updates (only changed params) except on reconnection (full state).
{
"state": {
"reported": {
"params": {
"Light": {
"Power": false,
"Brightness": 50
},
"notify": {
"version": 17436565837,
"alexa": true
}
},
"online": true,
"ncfg_ver": 1743656583
}
}
}
{
"state": {
"reported": {
"params": {
"Light": {
"Brightness": 80
}
}
}
}
}
Matter node reports attribute values nested as `<endpoint>.c.s.<cluster>.a.<attribute>`. Config-only attributes (declared under a cluster's `v` in node config) are never reported here.
{
"state": {
"reported": {
"params": {
"0x1": {
"c": {
"s": {
"0x6": {
"a": {
"0x0": true
}
},
"0x300": {
"a": {
"0x0": 130,
"0x1": 128
}
}
}
}
},
"notify": {
"version": 17436565838
}
},
"online": true,
"ncfg_ver": 1743656583
}
}
}
[Node → AWS IoT Shadow] Delete old named shadow during group migration. When group info changes, the old shadow is deleted before creating a new one.
Node deletes old named shadow during group migration
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
Group info string: <group_id>[-<sub1>-<sub2>-…] with subgroups sorted alphabetically.
Empty string if node is unassociated (e.g. shadow name becomes params-).
Accepts the following message:
Empty or minimal JSON
{}
[AWS IoT Shadow → Node] Delta between desired and reported state for the group-scoped named shadow. Delivered when the cloud sets desired state (e.g. an app or automation writes params). This is how a node learns of cloud-driven parameter changes.
Node receives desired-vs-reported delta for the named shadow
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
Group info string: <group_id>[-<sub1>-<sub2>-…] with subgroups sorted alphabetically.
Empty string if node is unassociated (e.g. shadow name becomes params-).
Accepts the following message:
{ state, metadata, version, timestamp } — state carries the desired delta
{}
[AWS IoT Shadow → Node] Confirmation that a shadow update was accepted, carrying the resulting shadow document.
Node receives confirmation that a shadow update was accepted
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
Group info string: <group_id>[-<sub1>-<sub2>-…] with subgroups sorted alphabetically.
Empty string if node is unassociated (e.g. shadow name becomes params-).
Accepts the following message:
Full shadow document { state: { reported, desired }, metadata, version, timestamp }
{}
[AWS IoT Shadow → Node] Notification that a shadow update was rejected (e.g. version conflict), so the node can retry or re-sync.
Node receives notification that a shadow update was rejected
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
Group info string: <group_id>[-<sub1>-<sub2>-…] with subgroups sorted alphabetically.
Empty string if node is unassociated (e.g. shadow name becomes params-).
Accepts the following message:
{ code, message, timestamp }
{}
[Node → AWS IoT Shadow] Request the current named shadow document
(typically on connect/reconnect). The document is returned on
.../get/accepted.
Node requests the current named shadow document (response on get/accepted)
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
Group info string: <group_id>[-<sub1>-<sub2>-…] with subgroups sorted alphabetically.
Empty string if node is unassociated (e.g. shadow name becomes params-).
Accepts the following message:
Empty JSON
{}
[AWS IoT Shadow → Node] Current named shadow document returned in response to a get request.
Node receives the current named shadow document
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
Group info string: <group_id>[-<sub1>-<sub2>-…] with subgroups sorted alphabetically.
Empty string if node is unassociated (e.g. shadow name becomes params-).
Accepts the following message:
Full shadow document { state: { reported, desired }, metadata, version, timestamp }
{}
[Node → AWS IoT Shadow] Indexed shadow update.
Contains only indexed parameters and node tags for fleet indexing.
Shadow name is always iparams (static, not group-scoped).
Node reports indexed parameters and tags to the iparams shadow
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
Accepts the following message:
Node reports indexed params and tags to iparams shadow
Shadow name: iparams (static, not group-scoped). Same state.reported wrapper as the named shadow: optional data (tags), params (only parameters with the indexed config property), online, ncfg_ver, notify.
Tags: state.reported.data.<who>.t with <who> ∈ admin | device | user. Firmware should update device tags only.
Matter: Same nested reporting shape as the named shadow for params, filtered to indexed attributes.
{
"state": {
"reported": {
"data": {
"device": {
"t": {
"type": "Light",
"model": "LED_Smart",
"fw_version": "2.1.0"
}
}
},
"params": {
"Light": {
"Brightness": 50
}
},
"online": true,
"ncfg_ver": 1743656583
}
}
}
[Node → Cloud] Timeseries data.
$aws/rules/node_ts_rule/rainmaker/nodes/<node_id>/ts/<group_info_str> to save costs.
Node publishes timestamped sensor/telemetry data
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
Group info string: <group_id>[-<sub1>-<sub2>-…] with subgroups sorted alphabetically.
Empty string if node is unassociated (e.g. shadow name becomes params-).
Accepts the following message:
Timestamped sensor/telemetry data point
{
"k": "Sensor.Temperature",
"dt": "float",
"t": 1743656583,
"v": 25.5,
"tz": "Asia/Kolkata"
}
{
"k": "Meter.Energy",
"dt": "float",
"t": 1743656583,
"v": 1523.7,
"cumulative": true,
"tz": "UTC"
}
{
"k": "0x1.c.s.0x402.a.0x0",
"dt": "int",
"t": 1743656583,
"v": 2500,
"tz": "UTC"
}
[Node → Cloud] Direct notifications.
$aws/rules/node_notify_rule/rainmaker/nodes/<node_id>/notify/<group_info_str> to save costs.
Node publishes direct notifications (e.g. automation trigger state)
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
Group info string: <group_id>[-<sub1>-<sub2>-…] with subgroups sorted alphabetically.
Empty string if node is unassociated (e.g. shadow name becomes params-).
Accepts the following message:
Direct notification from node
Notification payload grouped by notification type. The top-level notify object is an
open map: each key selects a backend notification service that consumes the value.
Built-in service keys:
automation — Automation trigger state updatespush — Mobile push notificationsnode_reset — Node reports a self factory-reset; backend notifies group members and disassociates the nodewebhook_<platform> — Configured webhook service, keyed by platform nameFor push, automation, and node_reset, the value under the key is a flag — the payload content is ignored by the backend; the service derives its message from notification metadata (node ID, shadow delta, trigger state). For webhook_<platform>, the value is forwarded to the configured webhook.
The same notify object structure is reused inside state.reported.params.notify on the named shadow update — dispatch logic is identical for both paths.
{
"notify": {
"automation": {
"trigger": [
{
"id": "node~temp-high",
"value": true
},
{
"id": "node~light-on",
"value": false
}
]
}
}
}
Flag-only key — triggers mobile push; value is ignored by the backend
{
"notify": {
"push": true
}
}
Flag-only key — node reports it reset itself; backend notifies group members and disassociates the node
{
"notify": {
"node_reset": true
}
}
Custom key `webhook_<platform>` routed to a configured webhook service
{
"notify": {
"webhook_mock": {
"event": "door_opened",
"location": "front_door",
"timestamp": 1743656583
}
}
}
Multiple services triggered from a single notification publish
{
"notify": {
"automation": {
"trigger": [
{
"id": "node~motion-detected",
"value": true
}
]
},
"push": true
}
}
[AWS IoT Jobs → Node] Notification of next pending job. Node subscribes on startup to receive OTA job notifications.
Node subscribes to next pending job notification (OTA)
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
Accepts the following message:
Next pending job notification
{
"timestamp": 1743656583,
"execution": {
"jobId": "AFR_OTA-ota_job_20240115",
"status": "QUEUED",
"queuedAt": 1743656583,
"lastUpdatedAt": 1743656583,
"versionNumber": 1,
"executionNumber": 1,
"jobDocument": {
"name": "MQTT+HTTP OTA with download window",
"payload": {
"afr_ota": {
"protocols": [
"MQTT",
"HTTP"
],
"streamname": "AFR_OTA-stream-1234567890",
"files": [
{
"filepath": "/firmware.bin",
"filesize": 1048576,
"fileid": "firmware_v2.1.0",
"certfile": "/ota-test-cert",
"sig-sha256-ecdsa": "MEQCIG...signature..."
}
]
},
"rmng_ota": {
"fw_version": "2.1.0",
"min_fw_version": "1.0.0",
"metadata": {
"release_notes": "Bug fixes and performance improvements"
},
"download_window": {
"validity": {
"start": 1704067200,
"end": 1706745600
},
"daily": {
"start": 60,
"end": 360
}
}
}
}
}
}
}
[Node → AWS IoT Jobs] Request full job document.
Node requests full job document for a specific job
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
AWS IoT Jobs job ID
Accepts the following message:
Empty object to request job document
{}
[AWS IoT Jobs → Node] Job document response.
Node receives job document
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
AWS IoT Jobs job ID
Accepts the following message:
Full job document response
{
"execution": {
"jobId": "AFR_OTA-ota_job_20240115",
"status": "IN_PROGRESS",
"jobDocument": {
"name": "MQTT+HTTP OTA with download window",
"payload": {
"afr_ota": {
"protocols": [
"MQTT",
"HTTP"
],
"streamname": "AFR_OTA-stream-1234567890",
"files": [
{
"filepath": "/firmware.bin",
"filesize": 1048576,
"fileid": "firmware_v2.1.0",
"certfile": "/ota-test-cert",
"sig-sha256-ecdsa": "MEQCIG...signature..."
}
]
},
"rmng_ota": {
"fw_version": "2.1.0",
"min_fw_version": "1.0.0",
"metadata": {
"release_notes": "Bug fixes and performance improvements"
},
"download_window": {
"validity": {
"start": 1704067200,
"end": 1706745600
},
"daily": {
"start": 60,
"end": 360
}
}
}
}
}
}
}
[Node → AWS IoT Jobs] Report job execution status.
Node reports job execution status (IN_PROGRESS, SUCCEEDED, FAILED)
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
AWS IoT Jobs job ID
Accepts the following message:
Node reports job execution status
{
"status": "IN_PROGRESS",
"statusDetails": {
"downloaded_bytes": 5000000,
"total_bytes": 10000000
},
"expectedVersion": 1
}
{
"status": "SUCCEEDED",
"statusDetails": {
"fw_version": "2.1.0"
},
"expectedVersion": 2
}
{
"status": "FAILED",
"statusDetails": {
"reason": "Post download checks failed"
},
"expectedVersion": 2
}
{
"status": "REJECTED",
"statusDetails": {
"reason": "Unsupported firmware version"
},
"expectedVersion": 2
}
[Node → AWS IoT Streams] GetStream request. data_type is json or cbor; body encoding must match. Use the same data_type on streamsData for block delivery.
Reference: AWS IoT — MQTT-based file delivery in devices (GetStream request fields, limits, optional bitmap).
Node publishes GetStream requests (`…/get/{dataType}`)
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
AWS IoT Streams stream name (for MQTT-based OTA file transfer)
Message encoding suffix for MQTT-based file delivery: json or cbor. Must match across the paired …/get/{dataType} publish and …/data/{dataType} subscription.
Accepts the following message:
AWS GetStream request body. Field names and rules: AWS IoT — MQTT-based file delivery in devices.
{}
[AWS IoT Streams → Node] GetStream response — file blocks. data_type must match the paired …/get/{dataType} topic.
Reference: AWS IoT — MQTT-based file delivery in devices (GetStream response shape, Base64 vs CBOR).
Node receives file blocks (`…/data/{dataType}`)
Available only on servers:
Unique node identifier (Thing Name / Node ID / MQTT Client ID)
AWS IoT Streams stream name (for MQTT-based OTA file transfer)
Message encoding suffix for MQTT-based file delivery: json or cbor. Must match across the paired …/get/{dataType} publish and …/data/{dataType} subscription.
Accepts the following message:
GetStream response payload: JSON with Base64 p when data_type = json, or CBOR when data_type = cbor. AWS IoT — MQTT-based file delivery in devices.
string
Node-to-cloud event request
The node publishes one or more named events. set events carry a payload;
get events are name-only (the cloud returns the data in from_cloud).
Cloud-to-node event response
Cloud returns event payloads keyed by event name.
set events return { "status": "success" } or { "status": "error", "message": "..." }.
get events return event-specific data.
Events may arrive unsolicited (e.g. schedule push after user edits).
Unicast parameter update command to node
User/app-initiated parameter changes delivered to a single node.
Default data model: device name → { param name → value }.
Matter data model: endpoint hex → { c → { s|c → { cluster hex → { c → { command hex → TLV hex } } } } }.
Control command broadcast to all nodes in a group or subgroup
Control payload broadcast on rainmaker/nodes/groups/{groupId}/control (group)
or rainmaker/nodes/groups/{groupId}/subgroups/{subgroupId}/control (subgroup).
Default data model: top-level keys are device types (e.g.
esp.device.light). Each device's value is an object that holds nested
sub-keys describing what to apply — currently only params is defined,
with room for additional sub-keys (e.g. cmd, meta) in future without
another topic rename. Nodes apply the payload only to their own devices
that match the listed device types; other devices are ignored.
Matter data model: command invocations only. Same nested structure as
the unicast ParamControl message, except the top-level endpoint key is the
wildcard endpoint "0xffff" (not a specific endpoint): 0xffff → c →
s|c → cluster → c → { command hex → TLV hex }. Each node invokes the
command on every endpoint that supports the addressed cluster + command,
resolved from its own support list.
Default: map of device type → control envelope. Matter: the unicast ParamControl command structure.
Node reports state to named shadow
Shadow name: params-{groupInfoStr}.
Contains reported node params, online status, config version, and notify metadata.
Delta updates (only changed params) except on reconnection (full state).
Node reports indexed params and tags to iparams shadow
Shadow name: iparams (static, not group-scoped). Same state.reported wrapper as the named shadow: optional data (tags), params (only parameters with the indexed config property), online, ncfg_ver, notify.
Tags: state.reported.data.<who>.t with <who> ∈ admin | device | user. Firmware should update device tags only.
Matter: Same nested reporting shape as the named shadow for params, filtered to indexed attributes.
Timestamped sensor/telemetry data point
Direct notification from node
Notification payload grouped by notification type. The top-level notify object is an
open map: each key selects a backend notification service that consumes the value.
Built-in service keys:
automation — Automation trigger state updatespush — Mobile push notificationsnode_reset — Node reports a self factory-reset; backend notifies group members and disassociates the nodewebhook_<platform> — Configured webhook service, keyed by platform nameFor push, automation, and node_reset, the value under the key is a flag — the payload content is ignored by the backend; the service derives its message from notification metadata (node ID, shadow delta, trigger state). For webhook_<platform>, the value is forwarded to the configured webhook.
The same notify object structure is reused inside state.reported.params.notify on the named shadow update — dispatch logic is identical for both paths.
AWS IoT Core connection lifecycle event
AWS IoT Core disconnection lifecycle event
Next pending job notification
Full job document response
Node reports job execution status
Node configuration payload (sent via setNodeConfig event)
Clusters on this endpoint. s = server-side clusters; inner c = client-side clusters.
Cluster map keys are cluster IDs in lowercase hex (e.g., 0x3d).
Server cluster — exposed attributes, events, accepted commands, indexed, timeseries and config-only attributes.
i (indexed) and ts (timeseries) are independent property sets and may overlap — an attribute that is both indexed and timeseries appears in both arrays. v holds config-only attribute values (reported in node config only, never in state). a lists the remaining plain attribute IDs and is omitted when empty.
Client cluster — available generated commands
Parameter definition within node config
Schedule definition
Date-based schedule trigger
Solar (sunrise/sunset) schedule trigger
One-shot relative trigger (fires once, N seconds from now)
Automation trigger definition
ESP RainMaker Neo OTA job document (extends AFR-OTA format)