Skip to content

REST API Documentation

Overview

This document outlines the REST API endpoints used for entity communication. These APIs complement the WebSocket protocol and provide HTTP-based access to core messaging functionality.

For a comprehensive understanding of entities, roles, and the RBAC communication model, see Entities Documentation.

Authentication

All API endpoints require authentication using a Bearer token in the Authorization header:

Authorization: Bearer your-api-key

Required Permissions

  • entity:CheckMessages - Required for checking messages
  • entity:WriteMessages - Required for publishing messages

Base URL

https://app.tendrl.com/api

Endpoints

GET /entities/check_messages

Retrieves pending messages for the authenticated entity.

Authorization Required: entity:CheckMessages

Query Parameters

Parameter Type Required Description
limit integer No Maximum number of messages to retrieve (default: 1)

Request Example

GET /api/entities/check_messages?limit=5
Authorization: Bearer your-api-key

Response

Success (200 OK):

When messages are available:

[
  {
    "msg_type": "publish",
    "source": "/entities/device-123",
    "dest": "entity-456", 
    "timestamp": "2025-01-09T10:30:00Z",
    "data": {
      "action": "status_update",
      "value": "online"
    },
    "context": {
      "tags": ["status", "health"]
    }
  }
]

When no messages are available:

[]

Error Responses:

{
  "error": "Unauthorized",
  "message": "Invalid API key or missing entity:CheckMessages permission"
}
{
  "error": "Rate Limit Exceeded", 
  "message": "Too many requests. Please try again later."
}

POST /entities/messages

Publishes a message from the authenticated entity. This endpoint supports all message types including regular messages, heartbeats, and other custom message types.

Authorization Required: entity:WriteMessages

Request Body

{
  "msg_type": "publish",
  "data": {
    // Your message payload (any JSON type)
  },
  "dest": "1234567891:us-1:entity:test-esp32-1", //send to another entity
  "context": {
    "tags": ["tag1", "tag2"],
    "wait": false
  }
}
Field Type Required Description
msg_type string Yes Message type (typically "publish")
data any Yes Message payload (can be any JSON type)
dest string No Destination entity identifier
context object No Additional message context
timestamp string No ISO 8601 timestamp (auto-generated if not provided)

Context Object

Field Type Description Constraints
tags string[] Tags for message categorization Max 10 tags
wait boolean Whether to wait for server response Default: false

Request Examples

Basic Message:

POST /api/entities/messages
Authorization: Bearer your-api-key
Content-Type: application/json

{
  "msg_type": "publish",
  "data": {
    "sensor": "temperature",
    "value": 23.5,
    "unit": "celsius"
  },
  "context": {
    "tags": ["sensors", "environment"]
  }
}

Message with Synchronous Response:

POST /api/entities/messages
Authorization: Bearer your-api-key
Content-Type: application/json

{
  "msg_type": "publish", 
  "data": {
    "command": "get_status",
    "target": "device-123"
  },
  "context": {
    "wait": true,
    "tags": ["commands"]
  }
}

Message to Specific Destination:

POST /api/entities/messages
Authorization: Bearer your-api-key
Content-Type: application/json

{
  "msg_type": "publish",
  "dest": "device-456",
  "data": {
    "action": "reboot",
    "scheduled_time": "2025-01-09T15:00:00Z"
  },
  "context": {
    "tags": ["maintenance", "commands"]
  }
}

Heartbeat Message:

POST /api/entities/messages
Authorization: Bearer your-api-key
Content-Type: application/json

{
  "msg_type": "heartbeat",
  "data": {
    "mem_free": 2097152,
    "mem_alloc": 524288,
    "disk_free": 1073741824,
    "disk_size": 2147483648
  },
  "timestamp": "2024-03-15T14:30:45Z"
}

For detailed heartbeat message format and implementation examples, see: Heartbeat Message Format

Response

Asynchronous Message (wait: false):

{
  "status": "accepted"
}

Synchronous Message (wait: true):

{
  "message_id": "msg-789", 
  "timestamp": "2025-01-09T10:30:00Z",
  "result": {
    "id": "msg-789",
    "actionResult": {
      "name": "validation-rule",
      "valid": true,
      "message": "Message processed successfully"
    }
  }
}

Error Responses:

{
  "error": "Validation Failed",
  "message": "Message size exceeds the limit for your plan. Basic plans are limited to 2KB messages."
}
{
  "error": "Rate Limit Exceeded",
  "message": "Monthly data limit exceeded"
}
{
  "error": "Bad Request",
  "message": "Invalid message format: msg_type is required"
}

Error Codes

Status Code Description
200 Success
400 Bad Request - Invalid message format or missing required fields
401 Unauthorized - Invalid API key or insufficient permissions
403 Forbidden - Access denied
413 Payload Too Large - Message exceeds size limits
429 Too Many Requests - Rate limit exceeded
500 Internal Server Error - Server processing error

Rate Limits

  • Message Publishing: 100 requests per minute per API key
  • Message Checking: 200 requests per minute per API key
  • Data Limits: Vary by plan (Basic: 2KB per message, Pro: 64KB per message)

SDKs Usage

These endpoints are used internally by all Tendrl SDKs:

  • JavaScript SDK: TendrlClient.publish() and TendrlClient.checkMessages()
  • Python SDK: Client.publish() and Client.check_messages()
  • Go SDK: Client.Publish() and Client.CheckMessages()
  • MicroPython SDK: Client.publish() and Client.check_messages()

For most use cases, we recommend using the SDKs rather than calling these REST endpoints directly, as the SDKs provide additional features like:

  • Automatic batching and queuing
  • Connection management and retry logic
  • WebSocket fallback for real-time communication
  • Built-in error handling and validation

Migration from WebSocket

If you're currently using WebSocket connections, these REST endpoints provide the same functionality with HTTP semantics:

WebSocket Message REST Endpoint
{"msgType": "publish", ...} POST /entities/messages
{"msgType": "msg_check", ...} GET /entities/check_messages
{"msgType": "heartbeat", ...} POST /entities/messages

The main differences:

  • REST is stateless (no persistent connection)
  • REST has higher latency but better reliability
  • REST is easier to integrate with HTTP-based workflows
  • WebSocket provides real-time bidirectional communication