# API documentation

When integrating the Efento Gateway with a custom application or server, several key factors must be considered to ensure reliable communication, data integrity, and security:

1. **Message Format and Structure**
   * Messages from the gateway are sent in **JSON format** and may include:
     * **Measurements messages**, containing logger data, measurement timestamps, and parameter values.
     * **Heartbeat messages**, containing gateway status, power information, logger count, and uptime.
2. **Server Response Requirements**
   * The server **must respond with HTTP status code `201 Created`** for every message sent by the gateway. If any other response is returned, the gateway will interpret the message as **not received** and will **resend it repeatedly** until a valid acknowledgment is received. This ensures no data is lost due to temporary network interruptions or server errors.
   * A **`503 Service Unavailable`** response indicates that the server is temporarily unable to process the request—for example, due to maintenance, overload, or other temporary conditions. Efento Gateway receives a **503** response, it will pause for **5 minutes** and then attempt to resend the data.
   * Your application must correctly parse these messages to extract measurements, identify loggers, and handle synchronization instructions sent to the gateway in the server response.
3. **Custom headers**
   * You can configure up to **ten custom HTTP headers** on the Gateway. These headers are included with every message sent by the gateway and can be used, for example, to **authenticate the gateway** with your server.
4. **Security Considerations**
   * Ensure that communication between the gateway and your server is **encrypted using TLS/SSL (HTTPS)**. You may upliad custom certificates to the Gateway
   * Validate any API keys or tokens sent via custom headers to prevent unauthorized access.

## Measurements

The measurements message provides logger data collected by the Efento Gateway and sent to the server in **JSON format**. Each message can contain multiple measurements, either from a single logger—such as when the gateway reconnects to the Internet and resends stored data—or from multiple loggers if several are within the gateway’s range. This structure allows efficient transmission of all relevant sensor data in one message.

The JSON body includes key details about each measurement, including the logger serial number, battery and signal status, measurement timestamps, and the recorded parameters with their values and statuses.&#x20;

<table data-header-hidden><thead><tr><th width="132.80078125"></th><th></th></tr></thead><tbody><tr><td>ENDPOINT</td><td><p>/api/v4/measurements</p><p>(default endpoint, can be overwritten in Server settings)</p></td></tr><tr><td>METHOD</td><td>POST</td></tr><tr><td>HEADERS</td><td><p>Content-Type: application/json</p><p>charset=UTF-8</p><p>X-Api-Token: &#x3C;value of the “Organization Token” field><br>&#x3C;Name of the 1st custom header>: &#x3C;Value of the 1st custom header><br>&#x3C;Name of the 2nd custom header>: &#x3C;Value of the 2nd custom header><br>...</p></td></tr></tbody></table>

The structure of the measurements JSON is as follows:

```json
{
  "measurements" : [
        {
"serial" : [string], // serial number of the logger
"response_handle":[number], // logger ID in response (optional)
"battery" : [string], // battery level: ok/low
"signal" : [number], // RSSI
"measured_at" : [string], // UTC date
"measurement_interval" : [number], // measurement interval in seconds  
             "next_measurement_at" : [string], // next connection date
"params" : [
  {
               "channel" : [number], // logger channel number: 1/2/3
               "type" : [string], // temperature / humidity / pressure / pressure_diff / open-close
               "value" : [string],
               "status" : [string] // status of the measurement - ‘ok’ or ‘error’
              }
           ]
        }
    ]
}
```

Examples of the messages sent by Efento Gateway to the server:

{% code expandable="true" %}

```json
{
"measurements" : [
{
"serial" : "282C024FFFB1",
"response_handle": 1,
"battery" : "ok",
"signal" : -70,
"measured_at" : "2024-10-12 15:28:21 UTC",
"measurement_interval" : 180,
"next_measurement_at" : "2024-10-12 18:28:21 UTC",
"params" : [
{ "channel": 1, "type": "temperature", "value": 6 , "status" : "ok"}
]
},


{
"serial" : "282C024FFFB2",
"response_handle": 2,
"battery" : "ok",
"signal" : -70,
"measured_at" : "2024-10-12 15:28:21 UTC",
"measurement_interval" : 180,
"next_measurement_at" : "2024-10-12 18:58:21 UTC",
"params" : [
{ "channel": 1, "type": "temperature", "value": 12, "status": "ok"},
{ "channel": 2, "type": "humidity", "value": 51, "status": "ok"}
]
},
{
"serial" : "282C024FFFB3",
"response_handle": 3,
"battery" : "ok",
"signal" : -70,
"measured_at" : "2024-10-12 15:28:21 UTC",
"measurement_interval" : 180,
"next_measurement_at" : "2024-10-12 20:28:21 UTC",
"params" : [
{ "channel": 1, "type": "temperature", "value": 50, "status": "ok"},
{ "channel": 2, "type": "humidity", "value": 30, "status": "ok"},
{ "channel": 3, "type": "pressure_diff", "value": 21, "status": "ok"}
]
},


     {
"serial" : "282C024FFFB4",
"response_handle": 4,
"battery" : "ok",
"signal" : -70,
"measured_at" : "2024-10-12 15:28:21 UTC",
"measurement_interval" : 180,
"next_measurement_at" : "2024-10-12 16:28:21 UTC",
"params" : [
{ "channel: 1, "type: "open-close", "value": "open", "status": "ok"},
{ "channel":2, "type":"open-close", "value":"closed", "status":"ok"},
{ "channel":3, "type":"open-close", "value":"closed", "status":"ok"}
                ]
}
   ]
}

```

{% endcode %}

The server must respond with **“201 Created”** for each message received from the Efento Gateway. If any other response is returned, the gateway will treat the message as **not received** and will **resend it repeatedly** until a valid response is received.

Additionally, the server’s response body should be a **JSON** containing a list of **accepted loggers IDs** and indicate whether the gateway should **save in its memory and synchronize the measurements** of these loggers with the server. Each logger ID corresponds to the **“response\_handle”** field sent by the gateway in the original JSON message.

```json
{
"Y": [number], // IDs of loggers, which should be synchronised with the server
"N": [number] //  IDs of loggers, which should NOT be synchronised with the server
}
```

Example of the response body sent to the gateway:

```json
{
"Y":[1,2,3],
"N":[4]
}
```

## Heartbeat

The heartbeat message provides regular status updates from the Efento Gateway. These messages are by default sent automatically every **15 minutes** and allow monitoring of the gateway’s health, connectivity, and power status. The HTTP request body contains the information in **JSON format**, detailing key parameters such as gateway identification, software version, uptime, logger count, and power status.

This message helps ensure that the gateway is operating correctly and allows the server or cloud platform to track its status in real time. On the other hand, it allows for proactive monitoring and helps detect issues such as power outages, connectivity problems, or unexpected gateway downtime.

<table data-header-hidden><thead><tr><th width="129.64453125"></th><th></th></tr></thead><tbody><tr><td>ENDPOINT</td><td><p>/api/v4/gateways/heartbeat</p><p>(default endpoint, can be overwritten in Server settings)</p></td></tr><tr><td>METHOD</td><td>POST</td></tr><tr><td>HEADERS</td><td><p>Content-Type: application/json</p><p>charset=UTF-8</p><p>X-Api-Token: &#x3C;value of the “Organization Token” field><br>&#x3C;Name of the 1st custom header>: &#x3C;Value of the 1st custom header><br>&#x3C;Name of the 2nd custom header>: &#x3C;Value of the 2nd custom header><br>...</p></td></tr></tbody></table>

The structure of the heartbeat JSON is as follows:

```json
{
    "name" : [string], // Name of the Gateway
    "model" : [string], // Model of the Gateway
    "software_version" : [string], // Software version
    "current_time" : [int], // Current time on the Gateway (Unix representation)
    "uptime" : [int], // Number of seconds since power up
    "mac" : [string], // MAC address
    "sensors_number" : [string], // number of loggers in the Gateway's range
    "next_communication_at" : [int], // Timestamp of the next communication
    "power_monitor" : {
        "is_usb_connected" : [boolean], // Information if the USB power adapter is connected
        "is_charging" : [boolean], // Information if the battery is charging
        "battery_level" : [int] // Battery level in %. ‘Null’, if power supply is connected
    }
}

```

Example of a heartbeat message:

```json
{
    "name": "Efento-Gateway-030A",
    "model": "HG6-v1.2-LECH",
    "software_version": "01.00.00-c723d",
    "current_time": 1731074192,
    "uptime": 2401,
    "mac": "28:2C:02:4F:03:0A",
    "sensors_number": "128/128",
    "next_communication_at": 1731075392,
    "power_monitor": {
        "is_usb_connected": true,
        "is_charging": true,
        "battery_level": null
    }
}
```

The server must respond with **“201 Created”** for each message received from the Efento Gateway. If any other response is returned, the gateway will treat the message as **not received** and will **resend it repeatedly** until a valid response is received.

## 503 response code

A **503 Service Unavailable** response indicates that the server is temporarily unable to process the request—for example, due to maintenance, overload, or other temporary conditions. When the Efento Gateway receives a **503** response, it will pause for **5 minutes** and then attempt to resend the data.

If the server responds with **201 Created** after the retry, the gateway will continue transmitting all remaining buffered measurements. However, if the server again returns **503**, the gateway will wait another **5 minutes** and repeat the process.

This retry mechanism ensures that no data is lost during temporary server downtime and applies to both types of messages: measurements and heartbeat.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.efento.io/efento-gateways/integration/api-documentation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
