A command (also called RPC) asks a device to do something: reboot, switch an output, run a test. Every command is stored as a request, and you can follow it until the device answers. Commands are sent only over TLS sessions (unless the profile allows a command in clear), never through the flows that process telemetry, and each one is checked against the sender’s permissions.
The command catalog
Each device profile has a Commands tab: “The commands operators may send to the devices of this profile; each tier needs its own permission.” Editing it needs the permission to manage commands (administrators).
Select Add command and fill in:
| Field | Meaning |
|---|---|
| Method | The wire name, namespace.verb, for example sys.info. Letters, digits, _ and .. |
| Label, Description | What operators see. |
| Tier | Basic, Privileged or Critical: who may send it (see below). |
| High impact (asks for a confirmation) | The sender must confirm; the command is sent at most once and audited. |
| Typed confirmation phrase | Optional, high-impact only: the operator types it to send (for example REBOOT). |
| One-way (no answer) | The device does not answer. |
| Long-running (the answer only says it started) | The device answers at once and reports the result later. |
| Default timeout (ms) | 1,000 to 600,000. Empty: the profile’s Default RPC timeout. |
| Persistent by default (delivered when the device comes back) | Queue the command while the device is offline. |
| Parameters | Built with Fields (name, label, type Text, Number, Yes / no, Choice or Any value (JSON), required, min, max, choices) or as Advanced (JSON). Up to 50 parameters. |
| Masked parameters | Parameter names whose values never show in the history. |
From a template starts the form from a command the platform already sends (such as a board control). Import replaces the whole catalog with an export ({"commands": [ … ]}); Export shows the catalog as JSON. A profile holds up to 200 commands.
Tiers
| Tier | Who may send it (default) |
|---|---|
| Basic | Users |
| Privileged | Administrators |
| Critical | Administrators |
| Raw (a method that is not in the catalog) | Owners |
Note
Some commands are never sent, whoever asks: factory reset, pairing, Wi-Fi forget and cloud.forget. Some method families belong to a module and only that module sends them (for example tunnel.* for remote access and esim.*). Profiles that use only the Legacy compatible topic scheme carry no commands: “RPC is not available for devices on the Legacy compatible scheme; use shared attributes (Attributes tab) to send settings.”
Send a command
- Open the device and its Commands tab.
- Pick a command under Choose a command (or Other method (raw), owners only) and fill in its Parameters.
- Set the options if needed:
| Option | Meaning | Default |
|---|---|---|
| Do not wait for an answer (one-way) | The device does not answer. | Off (two-way) |
| Answer timeout (seconds) | How long to wait for the answer, 1 to 600 seconds. | The command’s default, else 10 seconds |
| Deliver when the device comes back (persistent) | Keep the command queued while the device is offline. | The command’s default |
| Give up after (minutes) | When a queued command is given up. | 24 hours; at most 7 days |
- Select Send. A high-impact command asks Send {method}? (“This command has an impact on the device (it may restart or lose its session).”) and, when it has a phrase, Type {phrase} to confirm.
If the device is offline, the tab warns: “The device is offline: without “persistent” the command fails at once.”
Dashboards, SCADA symbols, rules and flows can also send commands. A board control sends only basic-tier commands. See Control cards.
Command states
| State | Shown as | Meaning |
|---|---|---|
QUEUED | Queued | Stored, waiting for the device. |
SENT | Sent | Sent to the device. |
DELIVERED | Delivered | The device received it. |
SUCCESSFUL | Successful | The device answered with success. |
FAILED | Failed | The device answered with an error. |
TIMEOUT | Timed out | No answer in time. This means “no answer arrived”, not “it did not run”. |
EXPIRED | Expired | It expired before it could be delivered. |
CANCELLED | Cancelled | Someone cancelled it. |
A long-running command shows Running on the device until its result arrives; a command that timed out shows No answer: the outcome is unknown; an answer after the end shows Answered after the end.
The history
The History on the Commands tab lists Method, Status, Sent by (Console, API, A flow, Firmware update, An alarm action, A dashboard control), Created, Completed and Duration. Open a command to see its Request, Response and Progress, to Cancel command while it is queued or sent, or to Send again. Secret parameters are masked.
Limits by default: 10 commands per device per minute and 600 per organisation per minute; parameters up to 16 KiB of JSON; an answer up to 64 KiB. History is kept for 90 days.
On the device
The device subscribes to v1/rpc/req/+ and receives:
PUBLISH v1/rpc/req/42
{"method": "sys.ping", "params": {"host": "8.8.8.8", "count": 3}}
For a two-way command it answers on the same id:
PUBLISH v1/rpc/res/42
{"ok": true, "result": {"sent": 3, "received": 3, "avg_ms": 18.2}}
Rules for the device:
- A command may arrive twice. Remember at least the last 32 request ids for 10 minutes and never run the same id twice.
- If the request carries
expirationTimeand it has passed, do not run it; answer{"ok": false, "error": "expired"}. - If a request is larger than the device can take, do not run it; answer
{"ok": false, "error": "payload_too_large"}. - Commands are delivered only after the device has subscribed to
v1/rpc/req/+on this connection.
HTTP devices wait for commands with GET /api/v1/rpc and answer with POST /api/v1/rpc/{id}. See Device HTTP API.
Long-running commands
PUBLISH v1/rpc/res/43
{"ok": true, "accepted": true, "job_id": "43"}
PUBLISH v1/attributes
{"rpc_result": {"job_id": "43", "method": "sys.traceroute", "ok": true, "result": {...}, "ts": 1759572042000}}
Requests from the device
A device can also ask the cloud: publish to v1/rpc/up/req/{id} with {"method": …, "params": …} and read the answer on v1/rpc/up/res/{id}. Your flows receive and answer these requests.
LoRaWAN and gateway children
- LoRaWAN devices take raw downlinks with the command
lora.downlink. See Sending downlinks. - Commands to devices behind a gateway are in development. See Commands to devices behind a gateway.
By API
POST/tenant/{tenantId}/api/iot/devices/{deviceId}/rpc
Send a command to a device. Body fields: method (required), params, oneway, persistent, timeoutMs (1,000 to 600,000), expiresInS (1 to 604,800), wait, confirm, confirmText, source (console, api or dashboard_control). params is at most 16 KiB of JSON. A two-way, non-persistent call with a timeout of at most 30 seconds waits for the end and answers 200. Any other call answers 202 at once. A high-impact command needs "confirm": true.
Request body application/json
{
"method": "sys.ping",
"params": {
"host": "8.8.8.8",
"count": 3
},
"timeoutMs": 10000
}
Example curl
curl -X POST 'https://<your-host>/tenant/{tenantId}/api/iot/devices/{deviceId}/rpc' \
-H 'Content-Type: application/json' \
-d '{"method":"sys.ping","params":{"host":"8.8.8.8","count":3},"timeoutMs":10000}'
Responses
200OK
{
"rpc": {
"rpcId": "…",
"deviceId": "…",
"method": "sys.ping",
"status": "SUCCESSFUL",
"outcome": null,
"response": {
"ok": true,
"result": {
"sent": 3,
"received": 3,
"avg_ms": 18.2
}
},
"tier": "basic",
"highImpact": false,
"source": "api",
"…": "…"
}
}
202Accepted
{
"rpc": {
"rpcId": "…",
"deviceId": "…",
"method": "sys.reboot",
"status": "QUEUED",
"…": "…"
}
}
400Bad Request
{
"message": "This command needs confirm: true.",
"code": "VALIDATION_ERROR",
"details": {
"reason": "confirm_required"
}
}
403Forbidden
No response body.
404Not Found
{
"message": "Device not found.",
"code": "NOT_FOUND"
}
429Too Many Requests
No response body.
Read a command with GET /tenant/{tenantId}/api/iot/rpc/{rpcId} and cancel it with POST …/rpc/{rpcId}/cancel (only while QUEUED or SENT; audited). The outcome field reads running, unknown or late as described above. See Commands API.
The webhook events rpc.completed and rpc.failed tell other systems the outcome. High-impact and raw commands are written to the audit log when they are created and when they end.

