> ## 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.
</Tip>

## Basic Syntax

```lot theme={null}
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={null}
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

<AccordionGroup>
  <Accordion title="Client Settings">
    <ParamField path="BASE_ADDRESS" type="string" required>
      Base URL for HTTP requests (e.g., `https://api.example.com`).
    </ParamField>

    <ParamField path="ENABLE_CLIENT" type="boolean">
      Enable HTTP client functionality. Default: false.
    </ParamField>

    <ParamField path="REQUEST_TIMEOUT" type="integer">
      Request timeout in seconds. Default: 30.
    </ParamField>

    <ParamField path="DEFAULT_CONTENT_TYPE" type="string">
      Default content type. Default: application/json.
    </ParamField>
  </Accordion>

  <Accordion title="Server Settings">
    <ParamField path="ENABLE_SERVER" type="boolean">
      Enable HTTP server functionality. Default: false.
    </ParamField>

    <ParamField path="SERVER_PORT" type="integer">
      HTTP server port. Default: 8080.
    </ParamField>
  </Accordion>

  <Accordion title="Authentication">
    <ParamField path="USERNAME" type="string">
      Basic authentication username.
    </ParamField>

    <ParamField path="PASSWORD" type="string">
      Basic authentication password.
    </ParamField>
  </Accordion>

  <Accordion title="SSL/Security">
    <ParamField path="USE_SSL" type="boolean">
      Enable SSL/TLS. Default: false.
    </ParamField>

    <ParamField path="IGNORE_CERT_ERRORS" type="boolean">
      Ignore certificate validation errors. Default: false.
    </ParamField>
  </Accordion>

  <Accordion title="CORS">
    <ParamField path="ENABLE_CORS" type="boolean">
      Enable CORS headers. Default: false.
    </ParamField>

    <ParamField path="CORS_ORIGINS" type="string">
      Allowed CORS origins. Default: \* (all).
    </ParamField>
  </Accordion>
</AccordionGroup>

***

## 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={null}
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

<AccordionGroup>
  <Accordion title="Trigger & Routing">
    <ParamField path="SOURCE_TOPIC" type="string">
      MQTT topic that triggers the HTTP request.
    </ParamField>

    <ParamField path="DESTINATION_TOPIC" type="string">
      MQTT topic to publish HTTP response.
    </ParamField>
  </Accordion>

  <Accordion title="HTTP Request">
    <ParamField path="METHOD" type="string">
      HTTP method: `GET`, `POST`, `PUT`, `DELETE`, `PATCH`.
    </ParamField>

    <ParamField path="ENDPOINT" type="string">
      API endpoint path (supports placeholders).
    </ParamField>

    <ParamField path="BODY" type="string">
      Request body for POST/PUT (supports placeholders).
    </ParamField>
  </Accordion>
</AccordionGroup>

### 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

<Tabs>
  <Tab title="GET Request">
    Fetch data from an external API when an MQTT message arrives:

    ```lot theme={null}
    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`.
  </Tab>

  <Tab title="POST Request">
    Send data to an external API:

    ```lot theme={null}
    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}`.
  </Tab>

  <Tab title="With Authentication">
    Use basic authentication for protected APIs:

    ```lot theme={null}
    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.
  </Tab>
</Tabs>

***

## 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.
</Tip>

### 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

<AccordionGroup>
  <Accordion title="Endpoint & Method">
    <ParamField path="ENDPOINT" type="string">
      The HTTP path to expose (e.g., `/api/sensors`).
    </ParamField>

    <ParamField path="METHOD" type="string">
      HTTP method to accept: `GET`, `POST`, `PUT`, `DELETE`.
    </ParamField>
  </Accordion>

  <Accordion title="MQTT Routing">
    <ParamField path="DESTINATION_TOPIC" type="string">
      MQTT topic where incoming HTTP data is published.
    </ParamField>
  </Accordion>
</AccordionGroup>

### Server Examples

<Tabs>
  <Tab title="Accept Sensor Data">
    Expose an endpoint for devices to submit readings via HTTP:

    ```lot theme={null}
    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 theme={null}
    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.
  </Tab>

  <Tab title="Multiple Endpoints">
    Expose different endpoints for different data types:

    ```lot theme={null}
    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.
  </Tab>

  <Tab title="Webhook Receiver">
    Accept webhooks from external services:

    ```lot theme={null}
    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.
  </Tab>

  <Tab title="CORS for Web Apps">
    Enable cross-origin requests for browser-based applications:

    ```lot theme={null}
    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).
  </Tab>
</Tabs>

***

## Combined Client and Server

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

```lot theme={null}
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

<Tabs>
  <Tab title="IoT Dashboard API">
    Full API for a web dashboard to read sensor data and send commands:

    ```lot theme={null}
    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"
    ```
  </Tab>

  <Tab title="Third-Party Integration">
    Integrate with an external CRM or ERP system:

    ```lot theme={null}
    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}"
    ```
  </Tab>
</Tabs>

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="Connection Timeout">
    * Verify BASE\_ADDRESS is correct
    * Check firewall allows outbound connections
    * Increase REQUEST\_TIMEOUT if API is slow
    * Verify network connectivity
  </Accordion>

  <Accordion title="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
  </Accordion>

  <Accordion title="Authentication Failed">
    * Verify USERNAME and PASSWORD are correct
    * Check Authorization header format
    * Ensure API key is valid and not expired
  </Accordion>

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

  <Accordion title="No Response Published">
    * Verify DESTINATION\_TOPIC is configured
    * Check MQTT broker connectivity
    * Monitor broker logs for errors
  </Accordion>
</AccordionGroup>

***

## Best Practices

<AccordionGroup>
  <Accordion title="Use HTTPS in Production">
    Always use SSL/TLS for external API connections:

    ```lot theme={null}
    WITH USE_SSL "true"
    ```
  </Accordion>

  <Accordion title="Set Appropriate Timeouts">
    Configure timeouts based on expected API response times:

    ```lot theme={null}
    WITH REQUEST_TIMEOUT '30'
    ```
  </Accordion>

  <Accordion title="Handle Errors Gracefully">
    Subscribe to response topics to monitor API call results and handle failures in your Actions.
  </Accordion>

  <Accordion title="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
  </Accordion>

  <Accordion title="Use Environment-Specific Base URLs">
    Configure different base URLs for development and production environments.
  </Accordion>
</AccordionGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Data Pipeline Routes" icon="arrow-right-arrow-left" href="./data-pipeline-routes">
    MQTT bridges and email notifications.
  </Card>

  <Card title="Route Examples" icon="code" href="./examples">
    See complete route configuration examples.
  </Card>
</CardGroup>
