CloudZao Burner
RegistryCloudZao CloudBook toolsSerial logOTA API guide
☰Menu
RegistryCloudZao CloudBook toolsSerial logOTA API guide
Login

Device OTA

OTA API guide

Use a personal security key and device MAC address to retrieve your approved community firmware. Stable builds need no extra header. Test builds require X-OTA-Channel: test.

Integration steps

  1. 1Get an OTA security key from Settings first. You can reveal the current key at any time; generating another key immediately revokes the old one.
  2. 2Embed the key in the device firmware before flashing. Never commit it to a public repository or print it in device logs.
  3. 3Send X-OTA-Key and Device-Id. Omit X-OTA-Channel for stable builds. Test builds require X-OTA-Channel: test.
  4. 4Set board.type to the board name in the left sidebar and application.name to the firmware title. Official boards and community boards you create use the same name. Spaces and letter case are ignored.
  5. 5chip_model_name is required. Send the chip the device actually runs. Boards may share a name as long as their chips differ, so the name plus the chip is what identifies one board.
Get a security key in Settings

Endpoint

Method
POST

POST only. Opening this URL in a browser, or sending GET, does not return firmware.

URL
https://admin.metalio.world/xiaozhi/api/firmware-ota/check

Request headers

HeaderRequired / OptionalDescription
X-OTA-KeyRequiredOTA security key from Settings. It can download only firmware published by that key's owner.
Device-IdRequiredDevice MAC, for example AA:BB:CC:DD:EE:FF.
X-OTA-ChannelRequired for test buildsOmit it, or send latest, to receive stable builds only. Send test to include test builds. An explicit application.version matches that version whether it is stable or test.
Client-IdOptionalClient identifier. It is not used to select firmware.

Request body

FieldRequired / OptionalDescription
board.typeRequiredBoard name from the left sidebar, such as Metalio E-Ink4 or Metalio Claw4. Spaces and letter case are ignored, so MetalioE-Ink4 matches too.
chip_model_nameRequiredThe chip the device actually runs, such as esp32s3 or bk7258. Letter case and hyphens are ignored, so ESP32-S3 and esp32s3 are the same chip. This is what tells same-named boards apart.
application.nameRequiredFirmware title, exactly as shown in My Firmware, such as ai.
application.versionOptionalOmit it to get the highest available version in the selected channel. Provide it to download that exact version string.

Get the latest stable build

Do not send X-OTA-Channel or application.version. Only an approved stable build is returned.

{
  "chip_model_name": "esp32s3",
  "board": {
    "type": "Metalio E-Ink4"
  },
  "application": {
    "name": "Metalio-WhiteAI"
  }
}

Get a test build

Add the request header X-OTA-Channel: test. Stable and test builds are both considered, and the highest available one is returned.

X-OTA-Channel: test

{
  "chip_model_name": "esp32s3",
  "board": {
    "type": "Metalio E-Ink4"
  },
  "application": {
    "name": "Metalio-WhiteAI"
  }
}

Get an exact version

Send application.version. Matching is exact. That version can be either stable or test.

{
  "chip_model_name": "esp32s3",
  "board": {
    "type": "Metalio E-Ink4"
  },
  "application": {
    "name": "Metalio-WhiteAI",
    "version": "1.2.0"
  }
}

Complete request example

Do not send X-OTA-Channel or application.version. Only an approved stable build is returned.

curl -X POST 'https://admin.metalio.world/xiaozhi/api/firmware-ota/check' \
  -H 'Device-Id: AA:BB:CC:DD:EE:FF' \
  -H 'X-OTA-Key: fw_ota_u1024_your_random_secret' \
  --json '{"chip_model_name": "esp32s3","board": {"type": "Metalio E-Ink4"},"application": {"name": "Metalio-WhiteAI"}}'

Add the request header X-OTA-Channel: test. Stable and test builds are both considered, and the highest available one is returned.

curl -X POST 'https://admin.metalio.world/xiaozhi/api/firmware-ota/check' \
  -H 'Device-Id: AA:BB:CC:DD:EE:FF' \
  -H 'X-OTA-Key: fw_ota_u1024_your_random_secret' \
  -H 'X-OTA-Channel: test' \
  --json '{"chip_model_name": "esp32s3","board": {"type": "Metalio E-Ink4"},"application": {"name": "Metalio-WhiteAI"}}'

Successful response

Devices normally only need firmware.version and firmware.url.

{
  "has_update": true,
  "firmware": {
    "version": "1.2.0",
    "url": "https://admin.metalio.world/OTA/example.bin",
    "size": 1488978,
    "version_status": "latest",
    "firmware_name": "Metalio-WhiteAI"
  }
}

Error responses

HTTPerrorDescription
401X-OTA-Key is requiredThe key header is missing.
401invalid OTA access keyThe key does not exist or was revoked. Generating a new key revokes the old one immediately.
400Device-Id is required and must be a MAC addressDevice-Id is missing or is not a MAC such as AA:BB:CC:DD:EE:FF.
400board.type is requiredThe body has no board name.
400application.name is requiredThe body has no firmware name.
400chip_model_name is requiredThe body has no chip model.
404no board matches board.type and chip_model_nameSeveral boards share this name, but none of them uses the reported chip. Check the chip you report, or which board the firmware is attached to.
404firmware not foundThis key's owner has no firmware with that name on this board.
404available firmware version not foundNo version was requested, and the selected channel has nothing to deliver. A test build without X-OTA-Channel: test also returns this.
404requested firmware version not foundapplication.version was sent, but no approved version with a firmware file matches it exactly.
409firmware OTA is disabledOTA is switched off for this firmware. Taking the firmware or a version offline does not cause this error.
409firmware download URL is unavailableThe version exists, but a download URL could not be built.
409firmware name matches more than one firmware on this boardThe same owner has more than one firmware with this name on this board.

Matching and security rules

  • A board is identified by board.type plus chip_model_name. Boards may share a name as long as their chips differ, which is why the chip model is required.
  • When several boards share the name, only the one with the matching chip is searched. If no chip matches, the request returns 404 instead of picking a board at random.
  • When board.type maps to exactly one board, the chip is not used to filter. A mismatch is only logged on the server and does not block delivery.
  • One board can have several firmwares. application.name tells them apart. The same user cannot publish two firmwares with the same name on one board.
  • A key can access only firmware published by its owner. Cross-user downloads are rejected.
  • Taking a firmware or version offline only hides it from the public registry. A device with the owner's key can still download it.
  • The version must be approved and have a firmware file. Pending, rejected, or file-less versions return 404.
  • Test builds are not returned unless X-OTA-Channel is test.
  • A missing firmware or no deliverable version returns 404. Disabled OTA or an unavailable download URL returns 409. A successful response never contains an empty URL.
  • A missing or invalid key returns 401. A missing board.type, chip_model_name or application.name, or an invalid Device-Id MAC, returns 400.