Files
lambdaiot-core/API.md

16 KiB

Lambda IoT Core API Documentation

Overview

The Lambda IoT Core API provides a RESTful interface for managing IoT devices, sensors, actors, and sensor readings. The API uses JWT authentication for protected endpoints and integrates with MQTT for real-time device communication.

Base URL: http://localhost:8080 (default)

Authentication

Most endpoints require JWT authentication. Include the token in the Authorization header:

Authorization: Bearer <your-jwt-token>

Tokens are obtained through the /login endpoint and are valid for 24 hours.


Public Endpoints

Health Check

Check the service health status.

Endpoint: GET /health

Authentication: None required

Response:

{
  "status": "ok"
}

Hello

Simple greeting endpoint for testing connectivity.

Endpoint: GET /hello

Authentication: None required

Response:

{
  "message": "hello from lambdaiot"
}

Register

Create a new user account.

Endpoint: POST /register

Authentication: None required

Request Body:

{
  "username": "string (required, min: 3, max: 50)",
  "password": "string (required, min: 6)",
  "email": "string (optional)"
}

Response (201 Created):

{
  "id": "uuid",
  "username": "string"
}

Error Responses:

  • 400 Bad Request: Invalid request format
  • 409 Conflict: Username already exists
  • 500 Internal Server Error: Database or server error

Login

Authenticate and receive a JWT token.

Endpoint: POST /login

Authentication: None required

Request Body:

{
  "username": "string",
  "password": "string"
}

Response (200 OK):

{
  "token": "jwt-token-string"
}

Error Responses:

  • 400 Bad Request: Invalid JSON
  • 401 Unauthorized: Invalid credentials
  • 500 Internal Server Error: Database or token generation error

List All Devices

Retrieve all devices in the system (public read access).

Endpoint: GET /devices

Authentication: None required

Response (200 OK):

[
  {
    "id": "uuid",
    "name": "string",
    "description": "string",
    "location": "string",
    "status_id": 1,
    "created_at": "2026-01-14T10:00:00Z",
    "updated_at": "2026-01-14T10:00:00Z"
  }
]

Status IDs:

  • 1: ok
  • 2: pending
  • 3: lost
  • 4: disabled

Protected Endpoints

All endpoints below require JWT authentication.

Protected Test

Test authentication and view token claims.

Endpoint: GET /protected

Authentication: Required

Response (200 OK):

{
  "claims": {
    "sub": "username",
    "user_id": "uuid",
    "exp": 1705324800
  }
}

Device Endpoints

Create Device

Create a new device.

Endpoint: POST /devices

Authentication: Required

Request Body:

{
  "name": "string (required)",
  "description": "string (required)",
  "location": "string (required)",
  "status_id": 1 (required, range: 1-4)
}

Response (201 Created):

{
  "id": "uuid"
}

Get Device

Retrieve a specific device by ID.

Endpoint: GET /devices/:id

Authentication: Required

Path Parameters:

  • id: Device UUID

Response (200 OK):

{
  "id": "uuid",
  "name": "string",
  "description": "string",
  "location": "string",
  "status_id": 1,
  "created_at": "2026-01-14T10:00:00Z",
  "updated_at": "2026-01-14T10:00:00Z"
}

Error Responses:

  • 400 Bad Request: Invalid device ID
  • 404 Not Found: Device not found

Update Device

Update an existing device.

Endpoint: PUT /devices/:id

Authentication: Required

Path Parameters:

  • id: Device UUID

Request Body (all fields optional):

{
  "name": "string",
  "description": "string",
  "location": "string",
  "status_id": 1
}

Response (200 OK):

{
  "message": "device updated"
}

Delete Device

Delete a device.

Endpoint: DELETE /devices/:id

Authentication: Required

Path Parameters:

  • id: Device UUID

Response (200 OK):

{
  "message": "device deleted"
}

Sensor Endpoints

Create Sensor

Create a new sensor for a device.

Endpoint: POST /sensors

Authentication: Required

Request Body:

{
  "device_id": "uuid (required)",
  "name": "string (required)",
  "type": "string (required)",
  "data_type_id": 1 (required, min: 1)
}

Response (201 Created):

{
  "id": "uuid"
}

List All Sensors

Retrieve all sensors.

Endpoint: GET /sensors

Authentication: Required

Response (200 OK):

[
  {
    "id": "uuid",
    "device_id": "uuid",
    "name": "string",
    "type": "string",
    "data_type_id": 1,
    "created_at": "2026-01-14T10:00:00Z",
    "updated_at": "2026-01-14T10:00:00Z"
  }
]

Get Sensor

Retrieve a specific sensor by ID.

Endpoint: GET /sensors/:id

Authentication: Required

Path Parameters:

  • id: Sensor UUID

Response (200 OK):

{
  "id": "uuid",
  "device_id": "uuid",
  "name": "string",
  "type": "string",
  "data_type_id": 1,
  "created_at": "2026-01-14T10:00:00Z",
  "updated_at": "2026-01-14T10:00:00Z"
}

Error Responses:

  • 400 Bad Request: Invalid sensor ID
  • 404 Not Found: Sensor not found

Update Sensor

Update an existing sensor.

Endpoint: PUT /sensors/:id

Authentication: Required

Path Parameters:

  • id: Sensor UUID

Request Body (all fields optional):

{
  "device_id": "uuid",
  "name": "string",
  "type": "string",
  "data_type_id": 1
}

Response (200 OK):

{
  "message": "sensor updated"
}

Delete Sensor

Delete a sensor.

Endpoint: DELETE /sensors/:id

Authentication: Required

Path Parameters:

  • id: Sensor UUID

Response (200 OK):

{
  "message": "sensor deleted"
}

Trigger Sensor

Request a new reading from a sensor via MQTT.

Endpoint: POST /sensors/:id/trigger

Authentication: Required

Path Parameters:

  • id: Sensor UUID

Request Body (optional):

{
  "action": "string (default: 'read')"
}

Response (202 Accepted):

{
  "status": "published",
  "topic": "lambdaiot"
}

MQTT Message Published:

{
  "type": "sensor_trigger",
  "sensor_id": "uuid",
  "action": "read",
  "requested_at": "2026-01-14T10:00:00Z"
}

Error Responses:

  • 400 Bad Request: Invalid sensor ID
  • 404 Not Found: Sensor not found
  • 500 Internal Server Error: Failed to publish to MQTT

Actor Endpoints

Create Actor

Create a new actor for a device.

Endpoint: POST /actors

Authentication: Required

Request Body:

{
  "device_id": "uuid (required)",
  "name": "string (required)",
  "type": "string (required)",
  "data_type_id": 1 (required, min: 1)
}

Response (201 Created):

{
  "id": "uuid"
}

List All Actors

Retrieve all actors.

Endpoint: GET /actors

Authentication: Required

Response (200 OK):

[
  {
    "id": "uuid",
    "device_id": "uuid",
    "name": "string",
    "type": "string",
    "data_type_id": 1,
    "created_at": "2026-01-14T10:00:00Z",
    "updated_at": "2026-01-14T10:00:00Z"
  }
]

Get Actor

Retrieve a specific actor by ID.

Endpoint: GET /actors/:id

Authentication: Required

Path Parameters:

  • id: Actor UUID

Response (200 OK):

{
  "id": "uuid",
  "device_id": "uuid",
  "name": "string",
  "type": "string",
  "data_type_id": 1,
  "created_at": "2026-01-14T10:00:00Z",
  "updated_at": "2026-01-14T10:00:00Z"
}

Error Responses:

  • 400 Bad Request: Invalid actor ID
  • 404 Not Found: Actor not found

Update Actor

Update an existing actor.

Endpoint: PUT /actors/:id

Authentication: Required

Path Parameters:

  • id: Actor UUID

Request Body (all fields optional):

{
  "device_id": "uuid",
  "name": "string",
  "type": "string",
  "data_type_id": 1
}

Response (200 OK):

{
  "message": "actor updated"
}

Delete Actor

Delete an actor.

Endpoint: DELETE /actors/:id

Authentication: Required

Path Parameters:

  • id: Actor UUID

Response (200 OK):

{
  "message": "actor deleted"
}

Write to Actor

Send a command to an actor via MQTT.

Endpoint: POST /actors/:id/write

Authentication: Required

Path Parameters:

  • id: Actor UUID

Request Body:

{
  "action": "string (required)",
  "value": "any JSON value (optional)"
}

Response (202 Accepted):

{
  "status": "published",
  "topic": "lambdaiot"
}

MQTT Message Published:

{
  "type": "actor_command",
  "actor_id": "uuid",
  "action": "string",
  "value": "any",
  "requested_at": "2026-01-14T10:00:00Z"
}

Error Responses:

  • 400 Bad Request: Invalid actor ID or missing action
  • 404 Not Found: Actor not found
  • 500 Internal Server Error: Failed to publish to MQTT

Sensor Reading Endpoints

Create Sensor Reading

Create a new sensor reading.

Endpoint: POST /sensor-readings

Authentication: Required

Request Body:

{
  "sensor_id": "uuid (required)",
  "value": 123.45 (required),
  "value_at": "2026-01-14T10:00:00Z (optional, defaults to now)"
}

Response (201 Created):

{
  "id": 123
}

List Sensor Readings

Retrieve sensor readings with optional filtering and pagination.

Endpoint: GET /sensor-readings

Authentication: Required

Query Parameters:

  • sensor_id: Filter by sensor UUID (optional)
  • limit: Number of results (default: 100, max: 1000)
  • page: Page number for pagination (default: 0)

Response (200 OK):

[
  {
    "id": 123,
    "sensor_id": "uuid",
    "value": 123.45,
    "value_at": "2026-01-14T10:00:00Z"
  }
]

Get Sensor Reading

Retrieve a specific sensor reading by ID.

Endpoint: GET /sensor-readings/:id

Authentication: Required

Path Parameters:

  • id: Reading ID (integer)

Response (200 OK):

{
  "id": 123,
  "sensor_id": "uuid",
  "value": 123.45,
  "value_at": "2026-01-14T10:00:00Z"
}

Error Responses:

  • 400 Bad Request: Invalid reading ID
  • 404 Not Found: Reading not found

Update Sensor Reading

Update an existing sensor reading.

Endpoint: PUT /sensor-readings/:id

Authentication: Required

Path Parameters:

  • id: Reading ID (integer)

Request Body (all fields optional):

{
  "value": 123.45,
  "value_at": "2026-01-14T10:00:00Z"
}

Response (200 OK):

{
  "message": "sensor reading updated"
}

Delete Sensor Reading

Delete a sensor reading.

Endpoint: DELETE /sensor-readings/:id

Authentication: Required

Path Parameters:

  • id: Reading ID (integer)

Response (200 OK):

{
  "message": "sensor reading deleted"
}

MQTT & System Endpoints

MQTT Ping

Publish a ping message to the MQTT broker for testing.

Endpoint: GET /mqttping

Authentication: Required

Response (200 OK):

{
  "timestamp": "2026-01-14T10:00:00Z",
  "topic": "lambdaiot"
}

MQTT Message Published:

{
  "type": "ping",
  "timestamp": "2026-01-14T10:00:00Z"
}

MQTT Integration

Device Discovery

Devices can announce themselves by publishing to the discovery topic:

Topic: {configured_mqtt_topic}/discovery

Message Format:

{
  "mac_address": "00:11:22:33:44:55",
  "device": {
    "id": "uuid",
    "name": "Device Name",
    "description": "Device Description",
    "location": "Device Location",
    "status_id": 1
  },
  "sensors": [
    {
      "id": "uuid",
      "name": "Temperature Sensor",
      "type": "temperature",
      "data_type_id": 1
    }
  ],
  "actors": [
    {
      "id": "uuid",
      "name": "LED Actuator",
      "type": "led",
      "data_type_id": 2
    }
  ]
}

Behavior:

  • New devices are automatically created with all sensors and actors
  • Existing devices are updated, and sensors/actors are synced
  • Device status is set to OK (1) upon discovery (payload device.status_id is ignored)

Device Check (State Polling)

The server periodically publishes device check requests to the main MQTT topic and expects devices to respond on the same topic.

Topic: {configured_mqtt_topic}

Request Message Published:

{
  "type": "device_check_request",
  "device_id": "uuid",
  "requested_at": "2026-01-14T10:00:00Z"
}

Expected Device Response:

{
  "type": "device_check_response",
  "device_id": "uuid",
  "status": "ok" | "lost" | "pending"
}

Sensor Readings via MQTT

Devices can publish sensor readings directly to the main MQTT topic. The server stores readings only if the sensor_id exists in the database.

Topic: {configured_mqtt_topic}

Message Format:

{
  "type": "sensor_reading",
  "sensor_id": "uuid",
  "value": 23.7,
  "value_at": "2026-01-14T10:00:00Z"
}

Notes:

  • type may also be sensor_value.
  • value may be a number, boolean, or numeric string (e.g., "1", "0", "23.7").
  • value_at is optional; if omitted, the server uses the current time.

Error Responses

All endpoints may return the following standard error responses:

400 Bad Request

{
  "error": "descriptive error message"
}

401 Unauthorized

{
  "error": "invalid credentials" // or "no claims"
}

404 Not Found

{
  "error": "resource not found"
}

409 Conflict

{
  "error": "resource already exists"
}

500 Internal Server Error

{
  "error": "descriptive error message"
}

Data Types

Device Status IDs

ID Status Description
1 OK Device is online and functioning
2 Pending Device is initializing or awaiting
3 Lost Device has not checked in recently
4 Disabled Device is administratively disabled

Date/Time Format

All timestamps use RFC3339 format: 2026-01-14T10:00:00Z

UUIDs

UUIDs follow the standard UUID format (any version), e.g. 550e8400-e29b-41d4-a716-446655440000.


Configuration

The server uses a configuration file (typically config.toml) with the following structure:

[server]
address = ":8080"
port = 8080
jwt_secret = "your-secret-key"

[database]
host = "localhost"
port = 3306
user = "root"
password = "password"
name = "lambdaiot"

[mqtt]
broker = "tcp://localhost:1883"
topic = "lambdaiot"
client_id = "lambdaiot-core"
username = ""
password = ""

Rate Limiting & Best Practices

  1. Pagination: Use limit and page parameters for large result sets
  2. MQTT Topics: All MQTT messages are published to the configured topic
  3. Token Expiry: JWT tokens expire after 24 hours - refresh as needed
  4. UUID Format: Always use valid UUID v4 format for device, sensor, and actor IDs
  5. Date Format: Use RFC3339 format for all timestamp fields
  6. Device Discovery: Devices can self-register via MQTT discovery messages

Example Workflows

Complete Device Setup Workflow

  1. Register a user:

    POST /register
    {"username": "admin", "password": "secret123"}
    
  2. Login and get token:

    POST /login
    {"username": "admin", "password": "secret123"}
    
  3. Create a device:

    POST /devices (with JWT)
    {"name": "Room Sensor", "description": "Living room", "location": "Floor 1", "status_id": 1}
    
  4. Create a sensor:

    POST /sensors (with JWT)
    {"device_id": "device-uuid", "name": "Temperature", "type": "temp", "data_type_id": 1}
    
  5. Trigger a reading:

    POST /sensors/{sensor-id}/trigger (with JWT)
    {"action": "read"}
    
  6. Create a reading:

    POST /sensor-readings (with JWT)
    {"sensor_id": "sensor-uuid", "value": 22.5}
    

Query Readings for a Specific Sensor

GET /sensor-readings?sensor_id={uuid}&limit=50&page=0 (with JWT)

Support & Documentation

For more information about device discovery specifications, see DEVICE_DISCOVERY_SPEC.md.


Generated: January 14, 2026