Protocol Reference
The HxTP/3.1 protocol uses a FROZEN Pipe-Separated Framing format for signing. This ensures bit-perfect identical representations across JavaScript, Python, Go, and C++ while being more efficient for embedded parsers.
Canonical Framing (Pipe-Separated)â
HxTP/3.1 uses a deterministic framing string. This string is built by concatenating specific fields separated by the pipe character (|).
Deterministic Rulesâ
- Strict Order: Fields must follow the exact 11-field sequence defined below.
- Escaping: Special characters within fields (
|,\,\n,\r) must be escaped with a backslash. - NFC Normalization: All strings are normalized using Unicode NFC before framing.
- Timestamp/Sequence: Numeric values are converted to their base-10 string representation.
Canonical Fields (11 total)â
The following fields are included in the signature base string, in this exact order:
version|device_id|tenant_id|client_id|message_id|request_id|sequence_number|timestamp|nonce|message_type|payload_hash
| Field | Type | Description |
|---|---|---|
version | string | Protocol version (must be "HxTP/3.1") |
device_id | string | Originating device ID (UUID) |
tenant_id | string | Tenant namespace (UUID or slug) |
client_id | string | Originating client ID or MQTT Session Token |
message_id | string | Unique message ID (UUID v4) |
request_id | string | Correlation ID (UUID v4) |
sequence_number | number | Monotonic sequence number |
timestamp | number | Unix timestamp (seconds or milliseconds) |
nonce | string | Cryptographic nonce (minimum 16 bytes) |
message_type | string | Message type (state, command, heartbeat, hello, ack) |
payload_hash | string | SHA-256 hex digest of the payload (params or state) |
Implementation Examplesâ
JavaScript (TypeScript)â
import { BuildCanonical } from 'hxtp-js';
const message = {
version: 'HxTP/3.1',
device_id: '...',
tenant_id: '...',
client_id: '...',
message_id: '...',
request_id: '...',
sequence_number: 101,
timestamp: 1713984000,
nonce: '...',
message_type: 'command',
payload_hash: '...',
};
const canonical = BuildCanonical(message);
// Result: HxTP/3.1|device-uuid|tenant-uuid|client-uuid|msg-uuid|req-uuid|101|1713984000|nonce|command|hash
Validation Pipelineâ
Server (7 Steps)â
- Version â Must equal
HxTP/3.1. - Timestamp Freshness â Must be within Âą30 seconds of server time.
- Payload Size â Hard limit of 16KB.
- Nonce Uniqueness â Verified against global Redis cache (60s TTL).
- Payload Hash â SHA-256 of the payload (canonical JSON) must match the header.
- Sequence Monotonicity â Must be strictly increasing per-device/tenant boundary.
- Ed25519 Signature â Verified using the device's registered Public Key.
Client (Embedded)â
- Version â Must equal
HxTP/3.1. - Timestamp Freshness â Validated using internal RTC or NTP sync.
- Payload Size â Validated against internal buffer capacity.
- Nonce â Optional local replay cache.
- Payload Hash â SHA-256 verification of the command params.
- Signature â Ed25519 verification using the hardcoded Cloud Root Public Key.
Error Codesâ
| Code | Description |
|---|---|
VERSION_MISMATCH | Unsupported protocol version (requires 3.1) |
TIMESTAMP_REJECTED | Message outside allowed Âą30s window |
NONCE_REUSED | Replay detected via nonce cache |
PAYLOAD_TOO_LARGE | Exceeds 16KB limit |
HASH_MISMATCH | Payload hash verification failed |
SEQUENCE_VIOLATION | Sequence number is not strictly increasing |
SIGNATURE_INVALID | Ed25519 signature verification failed |
DEVICE_NOT_ACTIVE | Device has not completed the HELLO handshake |
DEVICE_REVOKED | Device permanently blacklisted |