Appearance
REST API Devices
Base URL: https://api.iotbackend.cloud
GET /v1/user/devices
Return a compact list of devices visible to the authenticated user.
Headers
http
Authorization: Bearer <your-token>
Accept: application/jsonResponse
json
{
"data": [
{
"uid": "espressif8266_G8VfdNhn7jqN",
"name": "test",
"status": "pending",
"last_seen_at": null,
"platform": {
"id": 2,
"name": "ESP8266",
"key": "espressif8266"
},
"board": {
"id": 6,
"name": "ESP-07S",
"key": "esp07s"
},
"board_variant": null
}
]
}GET /v1/user/devices/
Return detailed information for one device.
Headers
http
Authorization: Bearer <your-token>
Accept: application/jsonResponse
json
{
"data": {
"uid": "espressif8266_G8VfdNhn7jqN",
"name": "test",
"description": null,
"status": "pending",
"is_online": false,
"public_ip": null,
"local_ip": null,
"port": 8883,
"last_rssi": null,
"first_seen_at": null,
"last_seen_at": null,
"last_ota_at": null,
"platform": {
"id": 2,
"name": "ESP8266",
"key": "espressif8266"
},
"board": {
"id": 6,
"name": "ESP-07S",
"key": "esp07s"
},
"board_variant": null,
"current_firmware": null,
"target_firmware": null,
"meta": {
"mqtt_port": 8883
}
}
}Detail fields
The detailed device payload can include:
- description and status fields
- online flag and network information
- broker port
- timestamps such as first seen, last seen, and last OTA
- platform, board, and board variant information
- current and target firmware details
- device metadata from the stored
metafield
PATCH /v1/user/devices/
Update editable device fields.
Headers
http
Authorization: Bearer <your-token>
Accept: application/json
Content-Type: application/jsonRequest body
json
{
"name": "Kitchen Sensor",
"description": "Mounted near the back door"
}Response
Returns the full device detail payload for the updated device.
POST /v1/user/devices/{uid}/reboot
Send a reboot command to the device.
Headers
http
Authorization: Bearer <your-token>
Accept: application/jsonResponse
json
{
"message": "Reboot command sent.",
"device_uid": "espressif8266_G8VfdNhn7jqN"
}POST /v1/user/devices/{uid}/wifi-reset
Send a Wi-Fi reset command to the device.
Headers
http
Authorization: Bearer <your-token>
Accept: application/jsonResponse
json
{
"message": "Wi-Fi reset command sent.",
"device_uid": "espressif8266_G8VfdNhn7jqN"
}POST /v1/user/devices/{uid}/ota
Trigger an OTA check for the device.
Headers
http
Authorization: Bearer <your-token>
Accept: application/jsonSuccess response
json
{
"message": "OTA check triggered.",
"device_uid": "espressif8266_G8VfdNhn7jqN"
}Validation response
json
{
"message": "Assign firmware first to trigger OTA."
}POST /v1/user/devices/{uid}/commands
Send a user-defined JSON command directly to the device.
Headers
http
Authorization: Bearer <your-token>
Accept: application/json
Content-Type: application/jsonRequest body
json
{
"payload": {
"cmd": "relay_toggle",
"channel": 1,
"state": "on"
}
}Response
json
{
"message": "Command sent.",
"device_uid": "espressif8266_G8VfdNhn7jqN"
}Note
Built-in control actions already have dedicated endpoints:
POST /v1/user/devices/{uid}/rebootPOST /v1/user/devices/{uid}/wifi-resetPOST /v1/user/devices/{uid}/ota
Use /commands for user-defined payloads instead of those built-in control actions.
GET /v1/user/devices/{uid}/command-buttons
Return saved user-defined command buttons for the device.
Headers
http
Authorization: Bearer <your-token>
Accept: application/jsonResponse
json
{
"data": [
{
"id": "relay_on",
"label": "Relay On",
"payload": {
"cmd": "relay_toggle",
"channel": 1,
"state": "on"
},
"confirm": false
}
]
}POST /v1/user/devices/{uid}/command-buttons
Create a saved user-defined command button.
Headers
http
Authorization: Bearer <your-token>
Accept: application/json
Content-Type: application/jsonRequest body
json
{
"id": "relay_on",
"label": "Relay On",
"payload": {
"cmd": "relay_toggle",
"channel": 1,
"state": "on"
},
"confirm": false
}Response
json
{
"message": "Command button created.",
"device_uid": "espressif8266_G8VfdNhn7jqN",
"data": {
"id": "relay_on",
"label": "Relay On",
"payload": {
"cmd": "relay_toggle",
"channel": 1,
"state": "on"
},
"confirm": false
}
}Validation response
json
{
"message": "A command button with this id already exists."
}DELETE /v1/user/devices/{uid}/command-buttons/
Delete a saved command button.
Headers
http
Authorization: Bearer <your-token>
Accept: application/jsonResponse
json
{
"message": "Command button deleted.",
"device_uid": "espressif8266_G8VfdNhn7jqN"
}POST /v1/user/devices/{uid}/command-buttons/{buttonId}/send
Send the payload stored in a saved command button.
Headers
http
Authorization: Bearer <your-token>
Accept: application/jsonResponse
json
{
"message": "Command sent.",
"device_uid": "espressif8266_G8VfdNhn7jqN"
}GET /v1/user/devices/{uid}/firmwares
Return uploaded firmwares available for this device.
Headers
http
Authorization: Bearer <your-token>
Accept: application/jsonResponse
json
{
"data": [
{
"id": 14,
"name": "Release build",
"version": "1.0.3",
"notes": "Stable OTA build",
"md5": "e4b7f01d6b9f3d6fdb0d53f5e8be2d34",
"size": 421376,
"created_at": "2026-04-16T10:25:00+00:00",
"is_current": false,
"is_target": true
}
]
}POST /v1/user/devices/{uid}/firmwares
Upload a new firmware binary for the device.
Headers
http
Authorization: Bearer <your-token>
Accept: application/json
Content-Type: multipart/form-dataForm fields
namerequiredversionoptionalnotesoptionalfilerequired raw.binfirmware file
Rules
- upload the raw
firmware.binproduced by your build - maximum file size is 4 MB
- firmware identity is tracked by
md5
cURL example
bash
curl -X POST "https://api.iotbackend.cloud/v1/user/devices/espressif8266_G8VfdNhn7jqN/firmwares" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Accept: application/json" \
-F "name=Release build" \
-F "version=1.0.3" \
-F "notes=Stable OTA build" \
-F "[email protected];type=application/octet-stream"Response
json
{
"data": {
"id": 14,
"name": "Release build",
"version": "1.0.3",
"notes": "Stable OTA build",
"md5": "e4b7f01d6b9f3d6fdb0d53f5e8be2d34",
"size": 421376,
"created_at": "2026-04-16T10:25:00+00:00",
"is_current": false,
"is_target": false
}
}Duplicate upload response
json
{
"message": "This firmware file is already uploaded."
}PATCH /v1/user/devices/{uid}/firmwares/
Update editable firmware metadata.
Headers
http
Authorization: Bearer <your-token>
Accept: application/json
Content-Type: application/jsonRequest body
json
{
"name": "Release build",
"version": "1.0.4",
"notes": "Renamed after testing"
}Response
Returns the updated firmware object.
DELETE /v1/user/devices/{uid}/firmwares/
Delete a firmware file if it is not currently in use.
Headers
http
Authorization: Bearer <your-token>
Accept: application/jsonResponse
json
{
"message": "Firmware deleted."
}Validation response
json
{
"message": "Cannot delete firmware while it is assigned to any device."
}POST /v1/user/devices/{uid}/firmwares/set-target
Assign a target firmware to the device using firmware md5.
Headers
http
Authorization: Bearer <your-token>
Accept: application/json
Content-Type: application/jsonRequest body
json
{
"md5": "e4b7f01d6b9f3d6fdb0d53f5e8be2d34"
}Response
json
{
"message": "Firmware assigned to device.",
"device_uid": "espressif8266_G8VfdNhn7jqN",
"md5": "e4b7f01d6b9f3d6fdb0d53f5e8be2d34"
}Not found response
json
{
"message": "Firmware with the provided md5 was not found for this device."
}Typical firmware flow
- Upload the firmware with
POST /v1/user/devices/{uid}/firmwares. - Save the returned
md5value. - Assign it with
POST /v1/user/devices/{uid}/firmwares/set-target. - Trigger delivery with
POST /v1/user/devices/{uid}/ota.
Command restrictions
Command endpoints can return a validation-style JSON response when the device cannot accept commands right now, for example if it is offline or reconnecting.