> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreflux.org/llms.txt
> Use this file to discover all available pages before exploring further.

# REST API Routes

> Connect to external REST APIs or expose HTTP endpoints from your broker with client/server modes

## REST API Overview

The `REST_API` route enables HTTP communication in both directions:

* **Client Mode** - Make HTTP requests to external APIs triggered by MQTT messages
* **Server Mode** - Expose HTTP endpoints that accept data and publish it to MQTT topics

> [!TIP]
>
> REST API routes are ideal for integrating with web services, webhooks, cloud APIs, and creating HTTP-to-MQTT bridges.

## Basic Syntax

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
DEFINE ROUTE APIConnector WITH TYPE REST_API
    ADD REST_API_CONFIG
        WITH BASE_ADDRESS "https://api.example.com"
        WITH ENABLE_CLIENT "true"
        WITH USE_SSL "true"
    ADD EVENT GetData
        WITH SOURCE_TOPIC "api/requests/data"
        WITH DESTINATION_TOPIC "api/responses/data"
        WITH METHOD "GET"
        WITH ENDPOINT "/v1/data"
```

***

## How REST API Routes Work

A REST API route bridges the HTTP and MQTT worlds. It contains **events** that define what happens when data flows through—either from MQTT to HTTP (client mode) or from HTTP to MQTT (server mode).

```mermaid theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
flowchart LR
    subgraph ClientMode
        A[MQTT Message] -->|triggers| B[HTTP Request]
        B -->|response| C[MQTT Topic]
    end
    subgraph ServerMode
        D[HTTP Request] -->|triggers| E[MQTT Topic]
    end
```

| Component | Purpose |
| - | - |
| `REST_API_CONFIG` | Connection settings—base URL, authentication, SSL, timeouts |
| `EVENT` | Defines a single HTTP operation with its trigger, method, and routing |
| `SOURCE_TOPIC` | MQTT topic that triggers the HTTP request (client mode) |
| `DESTINATION_TOPIC` | MQTT topic where results are published |
| `ENDPOINT` | The HTTP path to call (can include placeholders) |

***

## REST API Configuration

### REST\_API\_CONFIG Parameters

> **Client Settings**
>
> **BASE\_ADDRESS** `string` *required*
>
> Base URL for HTTP requests (e.g., `https://api.example.com`).
>
> **ENABLE\_CLIENT** `boolean`
>
> Enable HTTP client functionality. Default: false.
>
> **REQUEST\_TIMEOUT** `integer`
>
> Request timeout in seconds. Default: 30.
>
> **DEFAULT\_CONTENT\_TYPE** `string`
>
> Default content type. Default: application/json.

> **Server Settings**
>
> **ENABLE\_SERVER** `boolean`
>
> Enable HTTP server functionality. Default: false.
>
> **SERVER\_PORT** `integer`
>
> HTTP server port. Default: 8080.

> **Authentication**
>
> **USERNAME** `string`
>
> Basic authentication username.
>
> **PASSWORD** `string`
>
> Basic authentication password.

> **SSL/Security**
>
> **USE\_SSL** `boolean`
>
> Enable SSL/TLS. Default: false.
>
> **IGNORE\_CERT\_ERRORS** `boolean`
>
> Ignore certificate validation errors. Default: false.

> **CORS**
>
> **ENABLE\_CORS** `boolean`
>
> Enable CORS headers. Default: false.
>
> **CORS\_ORIGINS** `string`
>
> Allowed CORS origins. Default: \* (all).

***

## Client Mode

Use client mode when your broker needs to **call external APIs**. An MQTT message triggers the HTTP request, and the response is published back to MQTT.

```mermaid theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
flowchart LR
    A["MQTT: weather/request<br/>{city: 'London'}"] -->|triggers| B[REST API Route]
    B -->|GET /weather?q=London| C[External API]
    C -->|JSON response| B
    B -->|publishes| D["MQTT: weather/response<br/>{temp: 15, ...}"]
```

### Event Configuration

> **Trigger & Routing**
>
> **SOURCE\_TOPIC** `string`
>
> MQTT topic that triggers the HTTP request.
>
> **DESTINATION\_TOPIC** `string`
>
> MQTT topic to publish HTTP response.

> **HTTP Request**
>
> **METHOD** `string`
>
> HTTP method: `GET`, `POST`, `PUT`, `DELETE`, `PATCH`.
>
> **ENDPOINT** `string`
>
> API endpoint path (supports placeholders).
>
> **BODY** `string`
>
> Request body for POST/PUT (supports placeholders).

### Placeholder Support

Use placeholders in endpoints and bodies to insert dynamic values from the MQTT message:

| Placeholder | Description |
| - | - |
| `{payload}` | Full MQTT payload as-is |
| `{value.json}` | Parsed JSON payload |
| `{value.json.field}` | Specific field from JSON payload |
| `{source_topic}` | Original MQTT topic |
| `{timestamp}` | Message timestamp |

### Client Examples

**GET Request**

Fetch data from an external API when an MQTT message arrives:

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
DEFINE ROUTE WeatherAPI WITH TYPE REST_API
    ADD REST_API_CONFIG
        WITH BASE_ADDRESS "https://api.openweathermap.org"
        WITH ENABLE_CLIENT "true"
        WITH USE_SSL "true"
        WITH REQUEST_TIMEOUT '30'
    ADD EVENT GetWeather
        WITH SOURCE_TOPIC "weather/request"
        WITH DESTINATION_TOPIC "weather/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/data/2.5/weather?q={value.json.city}&appid={value.json.apikey}"
```

When a message like `{"city": "London", "apikey": "abc123"}` arrives at `weather/request`, the route calls the API and publishes the weather data to `weather/response`.

**POST Request**

Send data to an external API:

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
DEFINE ROUTE NotificationAPI WITH TYPE REST_API
    ADD REST_API_CONFIG
        WITH BASE_ADDRESS "https://api.notification-service.com"
        WITH ENABLE_CLIENT "true"
        WITH USE_SSL "true"
    ADD EVENT SendNotification
        WITH SOURCE_TOPIC "notifications/send"
        WITH DESTINATION_TOPIC "notifications/result"
        WITH METHOD "POST"
        WITH ENDPOINT "/v1/notify"
        WITH HEADERS
            ADD "Content-Type" "application/json"
            ADD "Authorization" "Bearer {value.json.api_key}"
        WITH BODY "{payload}"
```

The entire MQTT payload is forwarded as the HTTP request body using `{payload}`.

**With Authentication**

Use basic authentication for protected APIs:

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
DEFINE ROUTE AuthenticatedAPI WITH TYPE REST_API
    ADD REST_API_CONFIG
        WITH BASE_ADDRESS "https://secure-api.example.com"
        WITH ENABLE_CLIENT "true"
        WITH USERNAME "api_user"
        WITH PASSWORD "api_secret"
        WITH USE_SSL "true"
    ADD EVENT SecureRequest
        WITH SOURCE_TOPIC "secure/request"
        WITH DESTINATION_TOPIC "secure/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/protected/data"
```

The username and password are sent as HTTP Basic Authentication headers automatically.

***

## Server Mode

Use server mode when external systems need to **send data to your broker via HTTP**. The broker exposes an HTTP endpoint that accepts requests and publishes the data to MQTT topics.

> [!TIP]
>
> **Common use case:** Your web application, mobile app, or third-party service needs to push data into the MQTT broker without implementing an MQTT client.

### Why Use Server Mode?

| Scenario | How Server Mode Helps |
| - | - |
| Web dashboards | Submit commands or data via simple HTTP POST |
| Mobile apps | Send sensor data without MQTT libraries |
| Webhooks | Receive callbacks from services like GitHub, Stripe, Slack |
| Legacy systems | Integrate systems that only support HTTP |
| Firewalled environments | Accept data through standard HTTP ports |

### Server Event Configuration

> **Endpoint & Method**
>
> **ENDPOINT** `string`
>
> The HTTP path to expose (e.g., `/api/sensors`).
>
> **METHOD** `string`
>
> HTTP method to accept: `GET`, `POST`, `PUT`, `DELETE`.

> **MQTT Routing**
>
> **DESTINATION\_TOPIC** `string`
>
> MQTT topic where incoming HTTP data is published.

### Server Examples

**Accept Sensor Data**

Expose an endpoint for devices to submit readings via HTTP:

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
DEFINE ROUTE SensorHTTPBridge WITH TYPE REST_API
    ADD REST_API_CONFIG
        WITH ENABLE_SERVER "true"
        WITH SERVER_PORT '8080'
        WITH ENABLE_CORS "true"
    ADD EVENT ReceiveSensorData
        WITH ENDPOINT "/api/sensors"
        WITH METHOD "POST"
        WITH DESTINATION_TOPIC "sensors/from/http"
```

**Usage:** Send sensor data with a simple HTTP POST:

```bash wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
curl -X POST http://broker-ip:8080/api/sensors \
  -H "Content-Type: application/json" \
  -d '{"sensor_id": "temp-01", "value": 25.5}'
```

The data is published to `sensors/from/http` and available to all MQTT subscribers.

**Multiple Endpoints**

Expose different endpoints for different data types:

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
DEFINE ROUTE MultiEndpointAPI WITH TYPE REST_API
    ADD REST_API_CONFIG
        WITH ENABLE_SERVER "true"
        WITH SERVER_PORT '8080'
        WITH ENABLE_CORS "true"
    
    ADD EVENT ReceiveTemperature
        WITH ENDPOINT "/api/temperature"
        WITH METHOD "POST"
        WITH DESTINATION_TOPIC "sensors/temperature/http"
    
    ADD EVENT ReceivePressure
        WITH ENDPOINT "/api/pressure"
        WITH METHOD "POST"
        WITH DESTINATION_TOPIC "sensors/pressure/http"
    
    ADD EVENT ReceiveCommands
        WITH ENDPOINT "/api/commands"
        WITH METHOD "POST"
        WITH DESTINATION_TOPIC "commands/from/http"
```

Each endpoint routes to a different MQTT topic for organized data handling.

**Webhook Receiver**

Accept webhooks from external services:

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
DEFINE ROUTE WebhookReceiver WITH TYPE REST_API
    ADD REST_API_CONFIG
        WITH ENABLE_SERVER "true"
        WITH SERVER_PORT '9000'
    
    ADD EVENT GitHubWebhook
        WITH ENDPOINT "/webhooks/github"
        WITH METHOD "POST"
        WITH DESTINATION_TOPIC "webhooks/github/events"
    
    ADD EVENT StripeWebhook
        WITH ENDPOINT "/webhooks/stripe"
        WITH METHOD "POST"
        WITH DESTINATION_TOPIC "webhooks/stripe/events"
```

Configure GitHub or Stripe to send webhooks to `http://your-broker:9000/webhooks/github`. Events appear on the corresponding MQTT topics.

**CORS for Web Apps**

Enable cross-origin requests for browser-based applications:

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
DEFINE ROUTE WebAppAPI WITH TYPE REST_API
    ADD REST_API_CONFIG
        WITH ENABLE_SERVER "true"
        WITH SERVER_PORT '3000'
        WITH ENABLE_CORS "true"
        WITH CORS_ORIGINS "https://app.example.com, https://admin.example.com"
    ADD EVENT SubmitData
        WITH ENDPOINT "/api/submit"
        WITH METHOD "POST"
        WITH DESTINATION_TOPIC "webapp/submissions"
```

Only requests from the specified origins are allowed. Use `"*"` for development (not recommended for production).

***

## Combined Client and Server

A single route can operate in both modes—accepting HTTP requests AND calling external APIs:

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
DEFINE ROUTE BidirectionalHTTP WITH TYPE REST_API
    ADD REST_API_CONFIG
        WITH BASE_ADDRESS "https://external-api.com"
        WITH ENABLE_CLIENT "true"
        WITH ENABLE_SERVER "true"
        WITH SERVER_PORT '8080'
        WITH USE_SSL "true"
        WITH ENABLE_CORS "true"
    
    // Server: Accept HTTP, publish to MQTT
    ADD EVENT ReceiveFromHTTP
        WITH ENDPOINT "/api/receive"
        WITH METHOD "POST"
        WITH DESTINATION_TOPIC "http/incoming"
    
    // Client: MQTT triggers external HTTP call
    ADD EVENT CallExternalAPI
        WITH SOURCE_TOPIC "http/outgoing"
        WITH DESTINATION_TOPIC "http/response"
        WITH METHOD "POST"
        WITH ENDPOINT "/api/data"
```

***

## Complete Examples

**IoT Dashboard API**

Full API for a web dashboard to read sensor data and send commands:

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
DEFINE ROUTE DashboardAPI WITH TYPE REST_API
    ADD REST_API_CONFIG
        WITH ENABLE_SERVER "true"
        WITH SERVER_PORT '8080'
        WITH ENABLE_CORS "true"
        WITH DEFAULT_CONTENT_TYPE "application/json"
    
    ADD EVENT PostSensorData
        WITH ENDPOINT "/api/sensors"
        WITH METHOD "POST"
        WITH DESTINATION_TOPIC "dashboard/sensors/incoming"
    
    ADD EVENT PostCommand
        WITH ENDPOINT "/api/commands"
        WITH METHOD "POST"
        WITH DESTINATION_TOPIC "commands/from/dashboard"
    
    ADD EVENT PostAlert
        WITH ENDPOINT "/api/alerts"
        WITH METHOD "POST"
        WITH DESTINATION_TOPIC "alerts/from/dashboard"
```

**Third-Party Integration**

Integrate with an external CRM or ERP system:

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
DEFINE ROUTE CRMIntegration WITH TYPE REST_API
    ADD REST_API_CONFIG
        WITH BASE_ADDRESS "https://api.crm-system.com"
        WITH ENABLE_CLIENT "true"
        WITH USE_SSL "true"
        WITH REQUEST_TIMEOUT '60'
    
    ADD EVENT CreateRecord
        WITH SOURCE_TOPIC "crm/create"
        WITH DESTINATION_TOPIC "crm/created"
        WITH METHOD "POST"
        WITH ENDPOINT "/v2/records"
        WITH HEADERS
            ADD "Authorization" "Bearer {value.json.token}"
            ADD "Content-Type" "application/json"
        WITH BODY "{value.json.data}"
    
    ADD EVENT UpdateRecord
        WITH SOURCE_TOPIC "crm/update"
        WITH DESTINATION_TOPIC "crm/updated"
        WITH METHOD "PUT"
        WITH ENDPOINT "/v2/records/{value.json.id}"
        WITH BODY "{value.json.data}"
    
    ADD EVENT DeleteRecord
        WITH SOURCE_TOPIC "crm/delete"
        WITH DESTINATION_TOPIC "crm/deleted"
        WITH METHOD "DELETE"
        WITH ENDPOINT "/v2/records/{value.json.id}"
```

***

## Troubleshooting

> **Connection Timeout**
>
> * Verify BASE\_ADDRESS is correct
> * Check firewall allows outbound connections
> * Increase REQUEST\_TIMEOUT if API is slow
> * Verify network connectivity

> **SSL/TLS Errors**
>
> * Ensure USE\_SSL matches the API requirements
> * For self-signed certificates, set IGNORE\_CERT\_ERRORS (not recommended for production)
> * Verify certificate chain is complete

> **Authentication Failed**
>
> * Verify USERNAME and PASSWORD are correct
> * Check Authorization header format
> * Ensure API key is valid and not expired

> **CORS Errors**
>
> * Enable CORS on the server: `WITH ENABLE_CORS "true"`
> * Configure specific allowed origins
> * Check browser console for specific CORS error messages

> **No Response Published**
>
> * Verify DESTINATION\_TOPIC is configured
> * Check MQTT broker connectivity
> * Monitor broker logs for errors

***

## Best Practices

> **Use HTTPS in Production**
>
> Always use SSL/TLS for external API connections:
>
> ```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
> WITH USE_SSL "true"
> ```

> **Set Appropriate Timeouts**
>
> Configure timeouts based on expected API response times:
>
> ```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
> WITH REQUEST_TIMEOUT '30'
> ```

> **Handle Errors Gracefully**
>
> Subscribe to response topics to monitor API call results and handle failures in your Actions.

> **Secure Server Endpoints**
>
> When exposing HTTP server endpoints:
>
> * Use authentication where needed
> * Limit CORS origins to specific domains
> * Consider rate limiting at the network level

> **Use Environment-Specific Base URLs**
>
> Configure different base URLs for development and production environments.

***

## Next Steps

> **[Streaming Routes](./streaming/kafka)**
>
> Stream MQTT messages through Kafka.

> **[Route Examples](./examples)**
>
> See complete route configuration examples.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.