A lightweight, human-readable protocol for sending and receiving IoT data to TagoIO. TagoTiP provides a compact alternative to HTTP/JSON for resource-constrained embedded devices.
PUSH|4deedd7bab8817ec|sensor-01|[temperature:=32.5#C;humidity:=65#%]
Where 4deedd7bab8817ec is the Authorization Hash -- first 8 bytes of SHA-256 of the device token (without the at prefix).
- Human-readable -- frames can be read and composed in a terminal
- Type-safe -- explicit operators for numbers (
:=), strings (=), booleans (?=), and locations (@=) - Compact -- ~4.7x smaller than equivalent HTTP/JSON
- Transport-agnostic -- works over UDP, TCP, HTTP(S), MQTT, or any byte-capable channel
- C-friendly -- linear parsing, predictable buffer sizes, minimal string handling
- Complete -- supports all TagoIO data model fields: variable, value, unit, time, group, location, and metadata
| Document | Description |
|---|---|
| TagoTiP.md | Core protocol specification (v1.0, Revision D) -- frame format, methods, variable syntax, parsing rules, ABNF grammar |
| TagoTiPs.md | TagoTiP/S (v1.0, Revision D) -- AEAD encrypted envelope for links without TLS |
| Method | Direction | Purpose |
|---|---|---|
PUSH |
Client -> Server | Send structured data or raw passthrough payloads to a device |
PULL |
Client -> Server | Retrieve last value of one or more variables |
PING |
Client -> Server | Keepalive / connectivity test |
ACK |
Server -> Client | Response to any uplink method (OK, PONG, CMD, ERR) |
| Operator | Type | Example |
|---|---|---|
:= |
Number | temperature:=32.5 |
= |
String | status=running |
?= |
Boolean | active?=true |
@= |
Location | position@=39.74,-104.99,305 |
Each variable supports optional suffixes for unit (#), location (@=), timestamp (@), group (^), and metadata ({}):
temperature:=32.5#C@=39.74,-104.99@1694567890000^reading_001{source=dht22,quality=high}
Defaults that cascade to all variables in a frame, with variable-level overrides:
PUSH|AUTH|SERIAL|@=39.74,-104.99@1694567890000^batch_42{firmware=2.1}[temp:=32#C;humidity:=65#%]
Raw hex or base64 data sent directly to the device's payload parser:
PUSH|AUTH|SERIAL|>xDEADBEEF01020304
PUSH|AUTH|SERIAL|>b3q2+7wECAwQ=
Optional replay protection and request-response correlation:
PUSH|!42|AUTH|SERIAL|[temperature:=32]
ACK|!42|OK|1
TagoTiP/S wraps TagoTiP data in a binary AEAD-encrypted envelope for links where TLS is unavailable (LoRa, Sigfox, NB-IoT, raw UDP). It uses a compact headless inner frame that omits redundant header fields, saving ~40-50 bytes per message.
| ID | Cipher | Key | Tag |
|---|---|---|---|
| 0 | AES-128-CCM (mandatory) | 16 B | 8 B |
| 1 | AES-128-GCM | 16 B | 16 B |
| 2 | AES-256-CCM | 32 B | 8 B |
| 3 | AES-256-GCM | 32 B | 16 B |
| 4 | ChaCha20-Poly1305 | 32 B | 16 B |
[Flags 1B] [Counter 4B] [Auth Hash 8B] [Device Hash 8B] [Ciphertext + Auth Tag]
Total overhead: 29 bytes (CCM) or 37 bytes (GCM / ChaCha20-Poly1305).
| Format | Size | Ratio |
|---|---|---|
| HTTP/JSON | ~487 bytes | -- |
| TagoTiP | ~103 bytes | 4.7x smaller |
| TagoTiP/S | ~110 bytes | 4.4x smaller |
Apache License 2.0 -- see LICENSE for details.
Anyone is free to implement TagoTiP for any purpose, including commercial use. The names "TagoTiP", "TagoTiP/S", and "TagoIO" are trademarks of TagoIO Inc. See NOTICE for trademark details.
