MQTT payload reference

This page documents the JSON payloads exchanged after a control device has completed the MQTT runtime bootstrap. Topics come from the MQTT catalog. Payloads use public IoT identifiers, not database ids.

Publish with QoS 1 and retain disabled. MQTT PUBACK confirms broker acceptance only; the application result arrives later on feed_data_ack_topic. Use field semantics for retry, ordering, desired-state correlation, and result-handling rules.

Topic map

Direction Catalog field Payload
Device to Realer Route feed_data_topic Device publish payload
Realer to device Device feed_data_ack_topic Application acknowledgement payload
Realer to device Command route desired_topic Desired-state payload

Device publish payload

Publish this JSON object to a catalog route feed_data_topic. The topic identifies the device, resource, and source route, so the payload does not include sensor_id or command_id.

Sensor reading

JSON
{
  "message_id": "sensor-temp-20260429T100001Z",
  "value": "21.5",
  "value_received_at": "2026-04-29T10:00:01Z"
}

Command desired-state acknowledgement

JSON
{
  "message_id": "command-relay-20260429T100003Z",
  "value": "1.0",
  "value_received_at": "2026-04-29T10:00:03Z",
  "desired_id": "des_00000000000000000000000001",
  "report_status": "applied",
  "sequence_number": 42
}

Local physical command change

JSON
{
  "message_id": "command-local-20260429T100010Z",
  "value": "0.0",
  "value_received_at": "2026-04-29T10:00:10Z"
}
Field Rule
message_id Required idempotency key scoped to the authenticated device and route source.
value Required raw value for the route source. Send it as a JSON string unless a source-specific contract says otherwise.
value_received_at Required source event timestamp. Use ISO 8601 UTC when possible.
desired_id Use only when answering a desired-state message from Realer.
report_status For desired-state acknowledgements: applied, rejected, or stale. Omit when the status is the default applied. For local physical command reports, omit this field; if sent without desired_id, only reported is valid.
sequence_number Optional integer. Echo the desired-state sequence_number when acknowledging a desired command, or use it as a local ordering hint for device-originated reports. Idempotency still uses message_id.

Application acknowledgement payload

Subscribe to the catalog feed_data_ack_topic. Realer publishes this payload after it validates or rejects a feed-data publish.

JSON
{
  "version": "iot.v1.mqtt.feed_data_ack",
  "status": "accepted",
  "retryable": false,
  "device_id": "cdv_1234567890abcdef",
  "route_id": "rte_bbbbbbbbbbbbbbbbbbbbbbbbbb",
  "resource_id": "res_aaaaaaaaaaaaaaaaaaaaaaaaaa",
  "source_type": "command",
  "source_id": "cmd_aaaaaaaaaaaaaaaaaaaaaaaaaa",
  "desired_id": "des_00000000000000000000000001",
  "message_id": "command-relay-20260429T100003Z",
  "sequence_number": 42,
  "received_at": "2026-04-29T10:00:03.000000Z",
  "processed_at": "2026-04-29T10:00:03.120000Z",
  "error": null
}
Status Firmware handling
accepted Application accepted the publish.
replayed Same message_id and same payload were already accepted. Treat as success.
conflict Same message_id was used for a different payload. Generate a new message_id only after deciding the local event is truly new.
rejected Application rejected the publish. Inspect error and keep local safe behavior.
error Application processing failed. Retry only when retryable is true.

When present, error is an object with type, message, and details.

Rejected acknowledgement with error

JSON
{
  "version": "iot.v1.mqtt.feed_data_ack",
  "status": "rejected",
  "retryable": false,
  "device_id": "cdv_1234567890abcdef",
  "route_id": "rte_bbbbbbbbbbbbbbbbbbbbbbbbbb",
  "resource_id": "res_aaaaaaaaaaaaaaaaaaaaaaaaaa",
  "source_type": "sensor",
  "source_id": "sns_aaaaaaaaaaaaaaaaaaaaaaaaaa",
  "desired_id": null,
  "message_id": "sensor-temp-20260429T100001Z",
  "sequence_number": null,
  "received_at": "2026-04-29T10:00:01.000000Z",
  "processed_at": "2026-04-29T10:00:01.090000Z",
  "error": {
    "type": "validation_failed",
    "message": "feed data ingestion failed",
    "details": {
      "value": [
        "is invalid"
      ]
    }
  }
}

Desired-state payload

Subscribe to each command route desired_topic only when the MQTT credential includes iot:mqtt:desired:read. A desired-state payload asks the device to apply a command value.

JSON
{
  "version": "iot.v1.mqtt.command_desired",
  "desired_id": "des_00000000000000000000000001",
  "device_id": "cdv_1234567890abcdef",
  "route_id": "rte_bbbbbbbbbbbbbbbbbbbbbbbbbb",
  "resource_id": "res_aaaaaaaaaaaaaaaaaaaaaaaaaa",
  "source_type": "command",
  "source_id": "cmd_aaaaaaaaaaaaaaaaaaaaaaaaaa",
  "value": "1.0",
  "issued_at": "2026-04-29T10:00:00.000000Z",
  "valid_for_seconds": 90,
  "expires_at": "2026-04-29T10:01:30.000000Z",
  "sequence_number": 42,
  "metadata": {}
}
  • Use valid_for_seconds as the execution window for stale-command handling.
  • Use the server-assigned sequence_number to ignore stale lower sequence values for the same command route.
  • When applied, publish command feed data with the same desired_id, physical value, and a new message_id.
  • When rejected or stale, publish command feed data with the same desired_id and report_status set to rejected or stale.

Implementation rules

  • Use only topics returned by the MQTT catalog; do not build topic strings from local assumptions.
  • Parse unknown JSON fields as forward-compatible extensions and ignore them unless documented later.
  • Never treat MQTT PUBACK as application success. Wait for feed_data_ack_topic.
  • Keep message_id stable across retries of the same local event.
  • Do not use sequence_number as the retry key. Realer stores it for ordering and diagnostics, while duplicate detection uses message_id.
  • After reconnecting, republish only the latest relevant local state with new message_id values.