API reference
This is the device-facing API — the endpoints your hardware calls. The base URL is https://api.hiveron.net. Everything an operator does (creating accounts, device types, devices, firmware, and roll-outs) is done in the console UI, so it isn't listed here.
The Auth column shows what a request needs: None (public) or Device (an RFC 9421 signed request — see Device integration).
Clock
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /time | None | → { unix_ms }. The trusted clock a device uses to timestamp its token. |
Device endpoints (/iot)
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /iot/fw_check | Device | → { fw_id, size, sha256 } (all null if none assigned). Poll to detect an OTA update. |
| GET | /iot/fw_download | Device | Streams the assigned firmware bytes; supports a single signed Range request. |
| POST | /iot/telemetry | Device | { content } → 204. UUID Idempotency-Key header required; reuse it + body on retries. |
| GET | /iot/command_check | Device | → { count } of unexpired pending commands. |
| GET | /iot/command | Device | → { id, content } of the oldest pending command, or 204 (peek, non-consuming). |
| GET | /iot/commands | Device | → { commands[] } up to 100 pending (peek). |
| POST | /iot/command_ack | Device | { id } → 204 (repeat is harmless; expired command returns 409). |
Authentication
A device signs every request (RFC 9421) — there is no login step and no stored session. The GET /time endpoint is public and needs no signature. See Device integration for the full scheme.
# Every /iot request is individually signed (RFC 9421, "iotnet-v2" profile):
Content-Digest: sha-256=:BASE64_SHA256_OF_BODY:
Signature-Input: sig1=("@method" "@target-uri" "content-digest");created=EPOCH;expires=EPOCH+300;nonce="32_HEX";keyid="device:ID:VERSION";alg="ecdsa-p256-sha256";tag="iotnet-v2"
Signature: sig1=:BASE64_64_BYTE_R_THEN_S: