IoT Messaging Standard
Version 1.1 - May 2025
Table of Contents
- Introduction
- Message Structure
- Message Types
- Topic Structure
- Schema Validation
- Best Practices
- Examples
1. Introduction
This document specifies the standard for IoT message exchange, including message format, topic structure, and naming conventions. It defines a flexible and extensible framework for IoT communications across various domains.
1.1 Design Principles
- Consistent message structure for diverse IoT applications
- Human-readable identification codes
- Flexible payload structure
- Standardized topic routing
- Future-proof versioning
- Efficient storage in time-series databases
- Cross-domain applicability
1.2 Related Documents
- Edge Concept Documentation
- Location Concept Documentation
- Thing Concept Documentation
2. Message Structure
2.1 Base Message Format
{
"id": "018e7507-c547-7f43-9485-71c71b3b0445",
"ts": "2025-03-17T15:23:45.123456Z",
"thing_id": "018e7507-c547-7f43-9485-71c71b3b0446",
"edge_id": "018e7507-c547-7f43-9485-71c71b3b0447",
"type": "sensor.temperature.reading",
"version": 1,
"context": {},
"payload": {},
"metadata": {}
}
2.2 Field Definitions
| Field | Type | Required | Description |
|---|---|---|---|
| id | UUIDv7 | Yes | Unique message identifier |
| ts | ISO8601 | Yes | Timestamp with microsecond precision |
| thing_id | UUIDv7 | Yes | Unique thing identifier |
| edge_id | UUIDv7 | Yes | Unique edge identifier |
| type | string | Yes | Message type in dot notation |
| version | integer | Yes | Schema version |
| context | object | Yes (can be empty) | Operational context |
| payload | object | Yes | Event-specific data |
| metadata | object | Yes (can be empty) | Thing state/health data |
2.3 Required vs Optional Content
- The fields
id,ts,thing_id,edge_id,type, andversionare required and must contain valid values. - The objects
context,payload, andmetadatamust be present, but: contextandmetadatacan be empty objects ({}) when not neededpayloadshould contain event-specific data based on the message type
2.4 Context Field Specification
The context field provides operational context about where the event occurred and what generated it:
"context": {
"thing_code": "sens-temp-001",
"thing_type": "sensor",
"edge": {
"code": "prd-eu-001",
"type": "production"
},
"location": {
"code": "room-101",
"path": "floor-1/production/room-101",
"type": "office"
}
}
For detailed information on Edge, Location, and Thing structures, refer to their respective documentation.
2.5 Payload Field Specification
The payload field contains the actual data specific to the message type:
"payload": {
"value": 23.5,
"unit": "celsius",
"accuracy": 0.1,
"range": {
"min": -40.0,
"max": 85.0
}
}
The payload structure varies by message type but should follow these principles: - Keep data fields flat when possible - Use clear, descriptive field names - Include units of measurement when applicable - Provide accuracy/confidence when relevant - Use nested objects only when logically necessary
2.6 Metadata Field Specification
The metadata field provides device health and operational information:
"metadata": {
"firmware_version": "1.2.3",
"battery_level": 85,
"signal_strength": -67,
"uptime": 1209600
}
The metadata structure is flexible to accommodate different types of Things, but common patterns are recommended for each Thing category (see Thing documentation).
3. Message Types
3.1 Message Type Pattern
Message types follow a hierarchical dot notation:
{domain}.{entity}.{action}
Examples:
- sensor.temperature.reading
- access.door.opened
- device.status.online
- service.authentication.successful
3.2 Common Domains
| Domain | Description |
|---|---|
| sensor | Sensor readings and status |
| device | Device operations and status |
| service | Service operations and status |
| access | Access control events |
| system | System-level events |
| network | Network-related events |
| user | User interaction events |
3.3 Custom Domain Registration
Organizations can register custom domains for their specific needs while following the established pattern.
4. Topic Structure
4.1 Topic Format
{org_id}.{edge_code}.{thing_type}.{thing_code}.{message_type}
4.2 Topic Levels
| Level | Format | Example | Description |
|---|---|---|---|
| org_id | [a-z0-9-]+ | acme | Organization identifier |
| edge_code | [type]-[region]-[number] | prd-eu-001 | Edge installation identifier |
| thing_type | [a-z-]+ | sensor | Thing category |
| thing_code | [type]-[subtype]-[number] | sens-temp-001 | Thing identifier |
| message_type | [a-z]+ | telemetry | Message category |
4.3 Topic Examples
acme.prd-eu-001.sensor.sens-temp-001.telemetry
acme.ret-na-002.controller.ctrl-hvac-001.command
acme.bld-ap-003.service.srv-auth-001.event
4.4 Subscription Patterns
NATS provides powerful subscription capabilities:
| Pattern | Description | Example |
|---|---|---|
| Exact | Match exact subject | acme.prd-eu-001.sensor.sens-temp-001.telemetry |
| Wildcard | Single level wildcard | acme.prd-eu-001.*.*.telemetry |
| Full Wildcard | Multi-level wildcard | acme.prd-eu-001.> |
4.5 MQTT Translation
NATS provides native MQTT support through its MQTT gateway. The platform automatically translates between these formats:
MQTT: acme/prd-eu-001/sensor/sens-temp-001/telemetry
NATS: acme.prd-eu-001.sensor.sens-temp-001.telemetry
5. Schema Validation
5.1 Regular Expressions
Edge Code: ^[a-z]{2,4}-[a-z]{2,4}-\d{3,4}$
Location Code: ^[a-z]+-\d{1,4}$
Thing Code: ^[a-z]{3,4}-[a-z]+-\d{3,4}$
Message Type: ^[a-z]+\.[a-z]+\.[a-z]+$
NATS Subject: ^[a-z0-9-]+\.[a-z]{2,4}-[a-z]{2,4}-\d{3,4}\.[a-z-]+\.[a-z]{3,4}-[a-z]+-\d{3,4}\.[a-z]+$
MQTT Topic: ^[a-z0-9-]+/[a-z]{2,4}-[a-z]{2,4}-\d{3,4}/[a-z-]+/[a-z]{3,4}-[a-z]+-\d{3,4}/[a-z]+$
5.2 Validation Rules
- UUIDs must be UUIDv7 format
- Timestamps must be ISO8601 with microsecond precision
- All codes must follow their respective patterns
- Context, payload, and metadata must be valid JSON objects
- Required fields must be present and valid
6. Best Practices
6.1 Message Design
- Keep root-level fields minimal
- Use context for operational data
- Use payload for event-specific data
- Use metadata for thing health/state
- Maintain consistent patterns for similar message types
- Consider message size when designing field content
6.2 Database Considerations
- Index primary fields:
id,ts,thing_id,edge_id,type - Consider JSONB expression indexes for frequently queried fields
- Use TimescaleDB hypertables and compression for historical data
- Create appropriate retention policies
- Consider partitioning strategy for high-volume deployments
6.3 Security Considerations
- TLS for all connections
- Client certificate authentication
- Subject-level permissions
- Encrypted payloads when necessary
- Audit logging for sensitive operations
7. Examples
7.1 Sensor Reading Message
{
"id": "018e7507-c547-7f43-9485-71c71b3b0445",
"ts": "2025-03-17T15:23:45.123456Z",
"thing_id": "018e7507-c547-7f43-9485-71c71b3b0446",
"edge_id": "018e7507-c547-7f43-9485-71c71b3b0447",
"type": "sensor.temperature.reading",
"version": 1,
"context": {
"thing_code": "sens-temp-001",
"thing_type": "sensor",
"edge": {
"code": "prd-eu-001",
"type": "production"
},
"location": {
"code": "room-101",
"path": "floor-1/production/room-101",
"type": "office"
}
},
"payload": {
"value": 23.5,
"unit": "celsius",
"accuracy": 0.1
},
"metadata": {
"firmware_version": "1.2.3",
"battery_level": 85,
"signal_strength": -67
}
}
7.2 Device Status Message
{
"id": "018e7507-c547-7f43-9485-71c71b3b0449",
"ts": "2025-03-17T15:23:45.123456Z",
"thing_id": "018e7507-c547-7f43-9485-71c71b3b0450",
"edge_id": "018e7507-c547-7f43-9485-71c71b3b0447",
"type": "device.status.online",
"version": 1,
"context": {
"thing_code": "ctrl-hvac-001",
"thing_type": "controller",
"edge": {
"code": "prd-eu-001",
"type": "production"
},
"location": {
"code": "floor-1",
"path": "floor-1",
"type": "floor"
}
},
"payload": {
"status": "online",
"uptime": 0,
"boot_time": "2025-03-17T15:23:45.000000Z"
},
"metadata": {
"firmware_version": "2.1.0",
"hardware_version": "B",
"network_type": "ethernet"
}
}
7.3 Service Event Message
{
"id": "018e7507-c547-7f43-9485-71c71b3b0451",
"ts": "2025-03-17T15:23:45.123456Z",
"thing_id": "018e7507-c547-7f43-9485-71c71b3b0452",
"edge_id": "018e7507-c547-7f43-9485-71c71b3b0447",
"type": "service.authentication.successful",
"version": 1,
"context": {
"thing_code": "srv-auth-001",
"thing_type": "service",
"edge": {
"code": "prd-eu-001",
"type": "production"
},
"location": {
"code": "virt-1",
"path": "services/authentication",
"type": "virtual"
}
},
"payload": {
"user_id": "018e7507-c547-7f43-9485-71c71b3b0453",
"method": "card",
"permissions": ["access", "operate", "view"]
},
"metadata": {
"version": "1.5.2",
"response_time_ms": 125,
"cache_hit": false
}
}