Skip to content

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

MethodPathAuthDescription
GET/timeNone→ { unix_ms }. The trusted clock a device uses to timestamp its token.

Device endpoints (/iot)

MethodPathAuthDescription
GET/iot/fw_checkDevice→ { fw_id, size, sha256 } (all null if none assigned). Poll to detect an OTA update.
GET/iot/fw_downloadDeviceStreams the assigned firmware bytes; supports a single signed Range request.
POST/iot/telemetryDevice{ content } → 204. UUID Idempotency-Key header required; reuse it + body on retries.
GET/iot/command_checkDevice→ { count } of unexpired pending commands.
GET/iot/commandDevice→ { id, content } of the oldest pending command, or 204 (peek, non-consuming).
GET/iot/commandsDevice→ { commands[] } up to 100 pending (peek).
POST/iot/command_ackDevice{ 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: