Appearance
MQTT API
Broker & connection
CoppelBox devices connect to AWS IoT Core as the MQTT broker.
| Property | Value |
|---|---|
| Protocol | MQTT over TLS 1.2 |
| Port | 8883 |
| Authentication | Mutual TLS — X.509 client certificate, no username/password |
| Topic access control | Enforced by AWS IoT policy, scoped per-device to that device's own topics |
There is no username/password mode and no anonymous access. A device (or any other client) authenticates purely by presenting a valid, IoT-Core-registered X.509 certificate during the TLS handshake — see Authentication & Access for how that certificate model works and what it means for third-party integrators.
Topic structure (/cbox/...)
All CoppelBox MQTT traffic uses a hierarchical topic with a leading slash:
/cbox/{DEVICE_ID}/{subtopic}{DEVICE_ID}— the device's unique identifier, derived from its MAC address (e.g.CBOX-F8B3B737B800){subtopic}— the message category (status,alerts,command, etc.)
The leading slash matters
/cbox/... is correct — not cbox/.... This is a known gotcha: dropping the leading slash is the most common cause of a subscription silently receiving nothing.
Topics a device publishes to (i.e. what you subscribe to, to receive data):
| Topic | Purpose | Frequency |
|---|---|---|
/cbox/{DEVICE_ID}/status | System status, health, and relay state changes (includes energy data) | Every 20 seconds + on relay change |
/cbox/{DEVICE_ID}/alerts | Fault and warning events | On alert / clear / resend |
/cbox/{DEVICE_ID}/power | Buffered power history samples | On buffer flush |
/cbox/{DEVICE_ID}/ivy | Ivy Board telemetry (if fitted) | Every 60 seconds |
/cbox/{DEVICE_ID}/config | Relay configuration (type: "relayConfig") | On MQTT connect + after a config change |
/cbox/{DEVICE_ID}/ota | OTA firmware update progress and post-update notifications | During/after an update |
/cbox/{DEVICE_ID}/command | Command responses and acknowledgments | On request |
Topics a device subscribes to (i.e. where you'd publish, to send it a command):
| Topic | Purpose |
|---|---|
/cbox/{DEVICE_ID}/command | Control commands (relay control, status requests, diagnostics, etc.) |
Certificate rotation (/cbox/{DEVICE_ID}/csr/...) is a device-internal cloud handshake and not relevant to a data-consumption integration — it's mentioned here only so you don't mistake it for a telemetry topic if you subscribe with a wildcard (/cbox/{DEVICE_ID}/#).
Message payloads
Every telemetry and response message carries three timestamp fields:
| Field | Type | Description |
|---|---|---|
time | string | ISO 8601 UTC timestamp with milliseconds |
timeU | number | Unix epoch seconds |
uptime | number | Seconds since device boot |
The core payload types are:
- Status packet (heartbeat) — the main telemetry message, published every 20 seconds. See Telemetry → Status packets for the full field breakdown.
- Relay delta — a lightweight message published immediately on a relay state change (
type: "rlyDelta"). - Relay config — the full per-relay configuration, published on connect and after any config change (
type: "relayConfig"). - Power history — buffered energy-meter samples. See Telemetry → Power data.
- Alerts — fault/warning events. See Alerts for the full spec.
Field names on the wire are deliberately compact (e.g. batt not battery, PkW not power_kW) — this keeps status packets under 1 KB. See Examples for complete sample payloads of each message type.
Commands
Commands are sent as JSON to /cbox/{DEVICE_ID}/command. All commands are validated before execution; an invalid or missing parameter produces an error response on the same topic rather than being silently dropped.
The commands most relevant to a data-integration (rather than a fleet-control) use case are:
| Command | Purpose | Response topic |
|---|---|---|
request_status_packet | Request an immediate, complete status packet (rather than waiting up to 20s for the next heartbeat) | /status |
get_relay_config | Request the current relay configuration (labels, modes, pulse durations) | /command |
Example — request an immediate status packet:
json
{
"command": "request_status_packet"
}Relay-control commands (relay, toggle_relay, pulse_relay) and the rest of the command surface exist, but actuating a device is normally done through the platform's GraphQL API (publishDeviceCommand) rather than by publishing MQTT directly — see Authentication & Access. See Examples for a worked command/response pair.