Device integration
A device authenticates to the /iot/* endpoints by minting a short-lived token, signed with its private key. There is no login step and no stored session — every request carries a fresh, self-contained token.
The token format
The token is a base64-encoded 76-byte buffer:
base64( dev_id (4 bytes, big-endian int32)
‖ unix_ms (8 bytes, big-endian uint64)
‖ ECDSA P-256 / SHA-256 signature (64 bytes, raw r ‖ s) )The signature is computed over the first 12 bytes (the dev_id and unix_ms) using the device's private key. Send it as Authorization: Bearer <token>.
How the server verifies it
- The signature is checked against the public key stored on the device record.
- The timestamp must not be in the future.
- The timestamp must be strictly newer than the last accepted one for that device — this is the replay protection, so a captured token can't be reused.
Because of the timestamp check, the device needs a trusted clock: fetch it from the public GET /time endpoint ({ "unix_ms": N }) right before signing.
Example: sign a token and post telemetry (Python)
import base64, struct, requests
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec, utils
DEV_ID = 4
PRIVATE_KEY_HEX = "cdc3551f..." # 32-byte P-256 private scalar (hex)
API = "https://api.hiveron.net"
def fetch_unix_ms() -> int:
# The trusted clock. On real hardware this is your only HTTP dependency.
return requests.get(f"{API}/time").json()["unix_ms"]
def create_auth_token() -> str:
ts = fetch_unix_ms()
header = struct.pack(">iq", DEV_ID, ts) # 4-byte BE int + 8-byte BE long
priv = ec.derive_private_key(int(PRIVATE_KEY_HEX, 16), ec.SECP256R1())
der = priv.sign(header, ec.ECDSA(hashes.SHA256()))
r, s = utils.decode_dss_signature(der)
sig = r.to_bytes(32, "big") + s.to_bytes(32, "big") # raw r ‖ s (64 bytes)
return base64.b64encode(header + sig).decode()
token = create_auth_token()
requests.post(f"{API}/iot/telemetry",
headers={"Authorization": f"Bearer {token}"},
json={"content": '{"temp_c": 21.4}'})The device loop
Devices poll: check for firmware, post telemetry, and drain queued commands. Commands are a peek / acknowledge queue — reading one does not consume it; acking does.
# The device is a mailbox client. A typical loop:
token = create_auth_token() # fresh token per request
# 1) firmware
fw = GET /iot/fw_check # -> { "fw_id": <id or -1> }
if fw_id changed:
binary = GET /iot/fw_download # raw bytes -> flash & reboot
# 2) telemetry
POST /iot/telemetry { "content": "<reading>" } # -> 204
# 3) commands
n = GET /iot/command_check # -> { "count": n }
while n > 0:
cmd = GET /iot/command # -> { "id", "content" } (peek oldest)
execute(cmd.content)
POST /iot/command_ack { "id": cmd.id } # -> 204, removes it
n -= 1Once the loop is running, the device's own page in the console shows its readings arriving and whether it is on the latest firmware:

Ready-made helpers
You don't have to implement the crypto yourself. We provide a ready-made create_auth_token() helper in three languages — only the GET /time call is left as a platform stub for you to wire up:
- C — dependency-free, bundles micro-ecc for P-256 (ESP32-friendly).
- C++ — Arduino-friendly.
- Python — uses the
cryptographypackage.
Download the helpers below. The archive contains the C, C++, and Python sources, the bundled micro-ecc library, and a README with build instructions.