# HTTP API (V4)

EMQX Edge offers a comprehensive HTTP API for seamless integration with external systems. These APIs allow you to retrieve broker metrics, inspect client and subscription data, manage configurations, and control broker behavior, such as triggering a restart.

The HTTP API server listens on port `8081` by default, which can be customized via the configuration file located at `etc/nanomq.conf`.

> All endpoints are accessible under the `/api/v4` URI prefix.

## Interface Security

EMQX Edge supports two authentication methods for securing its HTTP API endpoints: [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication) and [JWT Authentication](../access-control/jwt.md).

- **Basic Authentication**: Requires a `username` and `password` in each request.
- **JWT Authentication**: Requires a signed JSON Web Token (JWT) to be included in the `Authorization` header.

By default, the credentials are:

- **Username**: `admin`
- **Password**: `public`

You can change these credentials in the `etc/nanomq.conf` configuration file.

## Response Code

### HTTP Status Codes

The HTTP API uses standard HTTP status codes to indicate the outcome of each request. When a request is successful, a `200 OK` response is returned along with a JSON body.

The possible status codes are as follows:

| Status Code | Description                                                  |
| ----------- | ------------------------------------------------------------ |
| 200         | Succeed, and the returned JSON data will provide more information |
| 400         | Invalid client request, such as wrong request body or parameters |
| 401         | Client authentication failed , maybe because of invalid authentication credentials |
| 404         | The requested path cannot be found or the requested object does not exist |
| 500         | An internal error occurred while the server was processing the request |

### Result Codes

In addition to the HTTP status code, every response includes a JSON `code` field that provides more granular information about the result of the API call.

The possible returned codes are as follows:

| Return Code | Description                                      |
| ----------- | ------------------------------------------------ |
| 0           | Succeed                                          |
| 101         | RPC error                                        |
| 102         | Unknown mistake                                  |
| 103         | Invalid user name or password                    |
| 104         | Empty username or password                       |
| 105         | User does not exist                              |
| 106         | Administrator account cannot be deleted          |
| 107         | Missing key request parameters                   |
| 108         | Request parameter error                          |
| 109         | Request parameters are not in legal JSON format  |
| 110         | Plug-in is enabled                               |
| 111         | Plugin is closed                                 |
| 112         | Client is offline                                |
| 113         | User already exists                              |
| 114         | Old password is wrong                            |
| 115         | Illegal subject                                  |
| 116         | Token expired                                    |
| 117         | Request parameters are not in legal HOCON format |
| 118         | Write config file failed                         |


## API Endpoints 

### GET /api/v4

Return all Endpoints supported by EMQX Edge.

**Parameters:** NULL

**Success Response Body (JSON):**

| Name             | Type    | Description    |
| ---------------- | ------- | -------------- |
| code             | Integer | 0              |
| data             | Array   | Endpoints list |
| - data[0].path   | String  | Endpoint       |
| - data[0].name   | String  | Endpoint Name  |
| - data[0].method | String  | HTTP Method    |
| - data[0].descr  | String  | Description    |

**Examples:**

```bash
$ curl -i --basic -u admin:public -X GET "http://localhost:8081/api/v4"

{"code":0,"data":[{"path":"/brokers/","name":"list_brokers","method":"GET","descr":"A list of brokers in the cluster"},{"path":"/nodes/","name":"list_nodes","method":"GET","descr":"A list of nodes in the cluster"},{"path":"/clients/","name":"list_clients","method":"GET","descr":"A list of clients on current node"},{"path":"/clients/:clientid","name":"lookup_client","method":"GET","descr":"Lookup a client in the cluster"},{"path":"/clients/username/:username","name":"lookup_client_via_username","method":"GET","descr":"Lookup a client via username in the cluster"},{"path":"/subscriptions/","name":"list_subscriptions","method":"GET","descr":"A list of subscriptions in the cluster"},{"path":"/subscriptions/:clientid","name":"lookup_client_subscriptions","method":"GET","descr":"A list of subscriptions of a client"},{"path":"/topic-tree/","name":"list_topic-tree","method":"GET","descr":"A list of topic-tree in the cluster"},{"path":"/configuration/","name":"get_broker_configuration","method":"GET","descr":"show broker configuration"},{"path":"/configuration/","name":"set_broker_configuration","method":"POST","descr":"set broker configuration"},{"path":"/ctrl/:action","name":"ctrl_broker","method":"POST","descr":"Control broker stop or restart"}]}
```

## Broker Basic Information

### GET /api/v4/brokers

Return basic information of EMQX Edge.

**Success Response Body (JSON):**

| Name             | Type                    | Description                                                  |
| ---------------- | ----------------------- | ------------------------------------------------------------ |
| code             | Integer                 | 0                                                            |
| data             | Object/Array of Objects | Returns the information of all nodes*(Only one node for EMQX Edge)* |
| data.datetime    | String                  | Current time, in the format of "YYYY-MM-DD HH: mm: ss"       |
| data.node_status | String                  | Node status                                                  |
| data.sysdescr    | String                  | Software description                                         |
| data.uptime      | String                  | EMQX Edge runtime, in the format of "H hours, m minutes, s seconds" |
| data.version     | String                  | EMQX Edge version                                            |

```bash
$ curl -i --basic -u admin:public -X GET "http://localhost:8081/api/v4/brokers"

{"code":0,"data":[{"datetime":"2022-06-07 10:02:24","node_status":"Running","sysdescr":"NanoMQ Broker","uptime":"15 Hours, 1 minutes, 38 seconds","version":"0.7.9-3"}]}
```

## Node

### GET /api/v4/nodes

Return the status of the node.

**Success Response Body (JSON):**

| Name             | Type                    | Description                                        |
| ---------------- | ----------------------- | -------------------------------------------------- |
| code             | Integer                 | 0                                                  |
| data             | Object/Array of Objects | Returns information about all nodes in an Array    |
| data.connections | Integer                 | Number of clients currently connected to this node |
| data.node_status | String                  | Node status                                        |
| data.uptime      | String                  | EMQX Edge runtime                                  |
| data.version     | String                  | EMQX Edge version                                  |

**Examples:**

```bash
$ curl -i --basic -u admin:public -X GET "http://localhost:8081/api/v4/nodes"

{"code":0,"data":[{"connections":0,"node_status":"Running","uptime":"15 Hours, 22 minutes, 4 seconds","version":"0.8.1"}]}
```

## Statistical information

### GET /api/v4/metrics

Return statistical information of EMQX Edge.

**Success Response Body (JSON):**

| Name    | Type                    | Description            |
| ------- | ----------------------- | ---------------------- |
| metrics | Object/Array of Objects | Unsupport now, (null)  |
| cpuinfo | Integer Percent         | EMQX Edge CPU usage    |
| memory  | Integer                 | EMQX Edge memory usage |

**Examples:**

```bash
$ curl -i --basic -u admin:public -X GET "http://localhost:8081/api/v4/metrics"

{"metrics":[],"cpuinfo":"0.00%","memory":"20049920"}
```


### GET /api/v4/prometheus

Return Prometheus statistical information.

**Success Response Body (text/plain):**

| Name                          | Type           | Description                   |
| ----------------------------- | -------------- | ----------------------------- |
| nanomq_connections_count      | gauge          | Number of connections         |
| nanomq_connections_max        | gauge          | Maximum supported number of connections |
| nanomq_sessions_count         | gauge          | Number of sessions            |
| nanomq_sessions_max           | gauge          | Maximum supported number of sessions |
| nanomq_topics_count           | gauge          | Number of topics              |
| nanomq_topics_max             | gauge          | Maximum supported number of topics |
| nanomq_subscribers_count      | gauge          | Number of subscribers         |
| nanomq_subscribers_max        | gauge          | Maximum supported number of subscribers |
| nanomq_messages_received      | counter        | The counter of messages received |
| nanomq_messages_sent          | counter        | The counter of messages sent  |
| nanomq_messages_dropped       | counter        | The counter of messages dropped |
| nanomq_memory_usage           | gauge          | CPU Usage                     |
| nanomq_memory_usage_max       | gauge          | Maximum CPU Usage             |
| nanomq_cpu_usage              | gauge          | Memory Usage                  |
| nanomq_cpu_usage_max          | gauge          | Maximum memory Usage          |

**Examples:**

```bash
$ curl -i --basic -u admin:public -X GET "http://localhost:8081/api/v4/prometheus"

# TYPE nanomq_connections_count gauge
# HELP nanomq_connections_count
nanomq_connections_count 0
# TYPE nanomq_connections_max gauge
# HELP nanomq_connections_max
nanomq_connections_max 0
# TYPE nanomq_sessions_count gauge
# HELP nanomq_sessions_count
nanomq_sessions_count 0
# TYPE nanomq_sessions_max gauge
# HELP nanomq_sessions_max
nanomq_sessions_max 0
# TYPE nanomq_topics_count gauge
# HELP nanomq_topics_count
nanomq_topics_count 0
# TYPE nanomq_topics_max gauge
# HELP nanomq_topics_max
nanomq_topics_max 0
# TYPE nanomq_subscribers_count gauge
# HELP nanomq_subscribers_count
nanomq_subscribers_count 0
# TYPE nanomq_subscribers_max gauge
# HELP nanomq_subscribers_max
nanomq_subscribers_max 0
# TYPE nanomq_messages_received counter
# HELP nanomq_messages_received
nanomq_messages_received 0
# TYPE nanomq_messages_sent counter
# HELP nanomq_messages_sent
nanomq_messages_sent 0
# TYPE nanomq_messages_dropped counter
# HELP nanomq_messages_dropped
nanomq_messages_dropped 0
# TYPE nanomq_memory_usage gauge
# HELP nanomq_memory_usage (b)
nanomq_memory_usage 19922944
# TYPE nanomq_memory_usage_max gauge
# HELP nanomq_memory_usage_max (b)
nanomq_memory_usage_max 19922944
# TYPE nanomq_cpu_usage gauge
# HELP nanomq_cpu_usage (%)
nanomq_cpu_usage 0.00
# TYPE nanomq_cpu_usage_max gauge
# HELP nanomq_cpu_usage_max (%)
nanomq_cpu_usage_max 0.00
```

## Client

### GET /api/v4/clients

Multiple conditions are supported. The query parameters included are shown below.

| Name        | Type    | Required | Description                                                  |
| ----------- | ------- | -------- | ------------------------------------------------------------ |
| clientid    | String  | False    | Client identifier                                            |
| username    | String  | False    | Client username                                              |
| conn_state  | Enum    | False    | The current connection status of the client, the possible values are`connected`,`idle`,`disconnected` |
| clean_start | Bool    | False    | Whether the client uses a new session                        |
| proto_name  | Enum    | False    | Client protocol name, the possible values are`MQTT`,`CoAP`,`LwM2M`,`MQTT-SN` |
| proto_ver   | Integer | False    | Client protocol version                                      |

**Success Response Body (JSON):**

| Name                | Type             | Description                                              |
| ------------------- | ---------------- | -------------------------------------------------------- |
| code                | Integer          | 0                                                        |
| data                | Array of Objects | Information for all clients                              |
| data[0].clientid    | String           | Client identifier                                        |
| data[0].username    | String           | User name of client when connecting                      |
| data[0].proto_name  | String           | Client protocol name*(MQTT,CoAP,LwM2M,MQTT-SN)*          |
| data[0].proto_ver   | Integer          | Protocol version used by the client                      |
| data[0].connected   | Boolean          | Whether the client is connected                          |
| data[0].keepalive   | Integer          | keepalive time, with the unit of second                  |
| data[0].clean_start | Boolean          | Indicate whether the client is using a brand new session |
| data[0].recv_msg    | Integer          | Number of PUBLISH packets received                       |

**Examples:**

```bash
$ curl -i --basic -u admin:public -X GET "http://localhost:8081/api/v4/clients"

{"code":0,"data":[{"client_id":"nanomq-f6d6fbfb","username":"alvin","keepalive":60,"conn_state":"connected","clean_start":true,"proto_name":"MQTT","proto_ver":5,"recv_msg":3},{"client_id":"nanomq-bdf61d9b","username":"nanomq","keepalive":60,"conn_state":"connected","clean_start":true,"proto_name":"MQTT","proto_ver":5,"recv_msg":0}]}
```

### GET /api/v4/clients/{clientid}

Returns information for the specified client

**Path Parameters:**

| Name     | Type   | Required | Description |
| -------- | ------ | -------- | ----------- |
| clientid | String | True     | ClientID    |

**Success Response Body (JSON):**

| Name | Type             | Description                                                  |
| ---- | ---------------- | ------------------------------------------------------------ |
| code | Integer          | 0                                                            |
| data | Array of Objects | Client information, for details, see  [GET /api/v4/clients](#GET /api/v4/clients) |

**Examples:**

Query the specified client

```bash
$ curl -i --basic -u admin:public -X GET "http://localhost:8081/api/v4/clients/nanomq-29978ec1"

{"code":0,"data":[{"client_id":"nanomq-29978ec1","username":"","keepalive":60,"conn_state":"connected","clean_start":true,"proto_name":"MQTT","proto_ver":5}]}
```

### GET /api/v4/clients/username/{username}

Query client information by Username. Since there may be multiple clients using the same user name, multiple client information may be returned at the same time.

**Path Parameters:**

| Name     | Type   | Required | Description |
| -------- | ------ | -------- | ----------- |
| username | String | True     | Username    |

**Success Response Body (JSON):**

| Name | Type             | Description                                                  |
| ---- | ---------------- | ------------------------------------------------------------ |
| code | Integer          | 0                                                            |
| data | Array of Objects | Information about clients, for details, see [GET /api/v4/clients](#GET /api/v4/clients) |

**Examples:**

```bash
$ curl -i --basic -u admin:public -X GET "http://localhost:8081/api/v4/clients/username/user001"

{"code":0,"data":[{"client_id":"nanomq-56baa74d","username":"user001","keepalive":60,"conn_state":"connected","clean_start":true,"proto_name":"MQTT","proto_ver":5}]}
```

## Subscription Information

### GET /api/v4/subscriptions

Multiple conditions queries are supported:

| Name     | Type   | Description                    |
| -------- | ------ | ------------------------------ |
| clientid | String | Client identifier              |
| topic    | String | congruent query                |
| qos      | Enum   | Possible values are 0`,`1`,`2` |
| share    | String | Shared subscription group name |

**Success Response Body (JSON):**

| Name             | Type             | Description                  |
| ---------------- | ---------------- | ---------------------------- |
| code             | Integer          | 0                            |
| data             | Array of Objects | All subscription information |
| data[0].clientid | String           | Client identifier            |
| data[0].topic    | String           | Subscribe to topic           |
| data[0].qos      | Integer          | QoS level                    |

**Examples:**

```bash
$ curl -i --basic -u admin:public -X GET "http://localhost:8081/api/v4/subscriptions"

{"code":0,"data":[{"clientid":"nanomq-29978ec1","topic":"topic123","qos":2},{"clientid":"nanomq-3020ffac","topic":"topic123","qos":2}]}
```

### GET /api/v4/subscriptions/{clientid}

Return the subscription information of the specified client in the Broker.

**Path Parameters:**

| Name     | Type   | Required | Description |
| -------- | ------ | -------- | ----------- |
| clientid | String | True     | ClientID    |

**Success Response Body (JSON):**

| Name          | Type    | Description                  |
| ------------- | ------- | ---------------------------- |
| code          | Integer | 0                            |
| data          | Object  | All subscription information |
| data.clientid | String  | Client identifier            |
| data.topic    | String  | Subscribe to topic           |
| data.qos      | Integer | QoS level                    |

**Examples:**

```bash
$ curl -i --basic -u admin:public -X GET "http://localhost:8081/api/v4/subscriptions/123"

{"data":[{"topic":"a/b/c","qos":1,"clientid":"123"}],"code":0}
```

## Publish message

### POST /api/v4/mqtt/publish

Publish MQTT message。

**Parameters (json):**

| Name       | Type    | Required | Default | Description                                                  |
| ---------- | ------- | -------- | ------- | ------------------------------------------------------------ |
| topic      | String  | Optional |         | For topic and topics, with at least one of them specified    |
| topics     | String  | Optional |         | Multiple topics separated by `,`. This field is used to publish messages to multiple topics at the same time |
| clientid   | String  | Optional |         | Client identifier (Default: EMQX Edge-HTTP-Client)           |
| payload    | String  | Required |         | Message body                                                 |
| encoding   | String  | Optional | plain   | The encoding used in the message body. Currently only plain and base64 are supported. |
| qos        | Integer | Optional | 0       | QoS level                                                    |
| retain     | Boolean | Optional | false   | Whether it is a retained message                             |
| properties | Object  | Optional | {}      | The Properties of the PUBLISH message                        |

Properties：

| Name                     | Type    | Description                                                  |
| ------------------------ | ------- | ------------------------------------------------------------ |
| payload_format_indicator | Integer | 0 (0x00) Byte Indicates that the Payload is unspecified bytes, which is equivalent to not sending a Payload Format Indicator. 1 (0x01) Byte Indicates that the Payload is UTF-8 Encoded Character Data. The UTF-8 data in the Payload MUST be well-formed UTF-8 as defined by the Unicode specification and restated in RFC 3629 |
| message_expiry_interval  | integer | Identifier of the Message Expiry Interval. If the Message Expiry Interval has passed and the Server has not managed to start onward delivery to a matching subscriber, then it MUST delete the copy of the message for that subscriber |
| response_topic           | String  | Identifier of the Response Topic.The Response Topic MUST be a UTF-8 Encoded, It MUST NOT contain wildcard characters. |
| correlation_data         | String  | Identifier of the Correlation Data. The Server MUST send the Correlation Data unaltered to all subscribers receiving the Application Message |
| subscription_identifier  | Integer | Identifier of the Subscription Identifier. It can have the value of 1 to 268,435,455. It is a Protocol Error if the Subscription Identifier has a value of 0. Multiple Subscription Identifiers will be included if the publication is the result of a match to more than one subscription, in this case their order is not significant. |
| content_type             | String  | The Content Type MUST be a UTF-8 Encoded String              |
| user_properties          | Object  | Identifier of the User Property. The Server send all User Properties unaltered in a PUBLISH packet when forwarding the Application Message to a Client |

**Success Response Body (JSON):**

| Name | Type    | Description |
| ---- | ------- | ----------- |
| code | Integer | 0           |

**Examples:**

```bash
$ curl -i --basic -u admin:public -X POST "http://localhost:8081/api/v4/mqtt/publish" -d \
'{"topic":"a/b/c", "payload":"Hello World", "qos":1, "retain":false, "clientid":"example", "properties": {"user_properties": { "id": 10010, "name": "emqx", "foo": "bar"}, "content_type": "text/plain"}}'

{"code":0}
```

## Subscribe to topic

### POST /api/v4/mqtt/subscribe (Unsupported now)

Subscribe to MQTT topic.

**Parameters (json):**

| Name     | Type    | Required | Default | Description                                                  |
| -------- | ------- | -------- | ------- | ------------------------------------------------------------ |
| topic    | String  | Optional |         | For topic and topics, with at least one of them specified    |
| topics   | String  | Optional |         | Multiple topics separated by `,`. This field is used to subscribe to multiple topics at the same time |
| clientid | String  | Required |         | Client identifier                                            |
| qos      | Integer | Optional | 0       | QoS level                                                    |

**Success Response Body (JSON):**

| Name | Type    | Description |
| ---- | ------- | ----------- |
| code | Integer | 0           |

**Examples:**

Subscribe to the three topics of `a`, `b`, `c` at the same time

```bash
$ curl -i --basic -u admin:public -X POST "http://localhost:8081/api/v4/mqtt/subscribe" -d '{"topics":"a,b,c","qos":1,"clientid":"example"}'

{"code":0}
```

### POST /api/v4/mqtt/unsubscribe (Unsupported now)

Unsubscribe.

**Parameters (json):**

| Name     | Type   | Required | Default | Description       |
| -------- | ------ | -------- | ------- | ----------------- |
| topic    | String | Required |         | Topic             |
| clientid | String | Required |         | Client identifier |

**Success Response Body (JSON):**

| Name | Type    | Description |
| ---- | ------- | ----------- |
| code | Integer | 0           |

**Examples:**

Unsubscribe from a topic

```bash
$ curl -i --basic -u admin:public -X POST "http://localhost:8081/api/v4/mqtt/unsubscribe" -d '{"topic":"a","qos":1,"clientid":"example"}'

{"code":0}
```

## Message Publish in Batch

### POST /api/v4/mqtt/publish_batch

Publish MQTT messages in batch.

**Parameters (json):**

| Name           | Type    | Required | Default | Description                                                  |
| -------------- | ------- | -------- | ------- | ------------------------------------------------------------ |
| [0].topic      | String  | Optional |         | Topic, at least one of which is specified with `topics`      |
| [0].topics     | String  | Optional |         | Multiple topics divided by `,`, which can be used to publish messages to multiple topics at the same time |
| [0].clientid   | String  | Optional |         | Client identifier (Default: EMQX Edge-HTTP-Client)           |
| [0].payload    | String  | Required |         | Message body                                                 |
| [0].encoding   | String  | Optional | plain   | The encoding method used in the message body, only `plain` and `base64` are supported currently |
| [0].qos        | Integer | Optional | 0       | QoS level                                                    |
| [0].retain     | Boolean | Optional | false   | Whether it is a retained message or not                      |
| [0].properties | Object  | Optional | {}      | The Properties of the PUBLISH message                        |

**Success Response Body (JSON):**

| Name | Type    | Description |
| ---- | ------- | ----------- |
| code | Integer | 0           |

**Examples:**

```bash
$ curl -i --basic -u admin:public -X POST "http://localhost:8081/api/v4/mqtt/publish_batch" -d '[{"topic":"a/b/c","payload":"Hello World","qos":1,"retain":false,"clientid":"example","properties": {"user_properties":{"id": 10010, "name": "nanomq", "foo": "bar"}}},{"topic":"a/b/c","payload":"Hello World Again","qos":0,"retain":false,"clientid":"example","properties":{"user_properties": { "id": 10010, "name": "nanomq", "foo": "bar"},"content_type": "text/plain"}}]'

{"data":[{"topic":"a/b/c","code":0},{"topic":"a/b/c","code":0}],"code":0}
```

## Topic Subscription in Batch

### POST /api/v4/mqtt/subscribe_batch (Unsupported now)

Subscribe to MQTT topics in batch.

**Parameters (json):**

| Name         | Type    | Required | Default | Description                                                  |
| ------------ | ------- | -------- | ------- | ------------------------------------------------------------ |
| [0].topic    | String  | Optional |         | Topic, at least one of which is specified with `topics`      |
| [0].topics   | String  | Optional |         | Multiple topics divided by `,`, which can be used to publish messages to multiple topics at the same time |
| [0].clientid | String  | Required |         | Client identifier                                            |
| [0].qos      | Integer | Optional | 0       | QoS level                                                    |

**Success Response Body (JSON):**

| Name | Type    | Description |
| ---- | ------- | ----------- |
| code | Integer | 0           |

**Examples:**

Subscribe to the three topics of `a`,`b`, and `c` at one time

```bash
$ curl -i --basic -u admin:public -X POST "http://localhost:8081/api/v4/mqtt/subscribe_batch" -d '[{"topic":"a","qos":1,"clientid":"example"},{"topic":"b","qos":1,"clientid":"example"},{"topic":"c","qos":1,"clientid":"example"}]'

{"code":0}
```

### POST /api/v4/mqtt/unsubscribe_batch (Unsupported now)

Unsubscribe in batch.

**Parameters (json):**

| Name         | Type   | Required | Default | Description       |
| ------------ | ------ | -------- | ------- | ----------------- |
| [0].topic    | String | Required |         | Topic             |
| [0].clientid | String | Required |         | Client identifier |

**Success Response Body (JSON):**

| Name | Type    | Description |
| ---- | ------- | ----------- |
| code | Integer | 0           |

**Examples:**

Unsubscribe from `a`,`b` topics at one time

```bash
$ curl -i --basic -u admin:public -X POST "http://localhost:8081/api/v4/mqtt/unsubscribe_batch" -d '[{"topic":"a","qos":1,"clientid":"example"},{"topic":"b","qos":1,"clientid":"example"}]'

{"code":0}
```

## Topic Tree Structure

### GET /api/v4/topic-tree

**Success Response Body (JSON):**

| Name             | Type             | Description                |
| ---------------- | ---------------- | -------------------------- |
| code             | Integer          | 0                          |
| data             | Array of Objects |                            |
| data[0].clientid | Array of String  | Array of client identifies |
| data[0].topic    | String           | Subscribe to topic         |
| data[0].cld_cnt  | Integer          | Number of child node       |

**Examples:**

```bash
$ curl -i --basic -u admin:public -X GET "http://localhost:8081/api/v4/topic-tree"

{"code":0,"data":[[{"topic":"","cld_cnt":1}],[{"topic":"topic123","cld_cnt":1,"clientid":["nanomq-3a4a0956"]}],[{"topic":"123","cld_cnt":1,"clientid":["nanomq-0cfd69bb"]}],[{"topic":"456","cld_cnt":0,"clientid":["nanomq-26971dc8"]}]]}
```

## Get Hot Updatable Configuration

### GET /api/v4/reload

Return all configuration that can be hot updatable.

**Success Response Body (JSON):**

| Name                        | Type    | Description                                 |
| --------------------------- | ------- | ------------------------------------------- |
| code                        | Integer | 0                                           |
| data.property_size          | Integer | Max size for a MQTT property.               |
| data.msq_len                | Integer | Queue length for resending messages.        |
| data.qos_duration           | Integer | The interval of the qos timer.              |
| data.allow_anonymous        | Boolean | Allow anonymous login.                      |
| data.max_packet_size        | Kbytes  | The max packet size of EMQX Edge (Kbytes).  |
| data.client_max_packet_size | Kbytes  | The default max packet size of each client. |
| data.keepalive_backoff      | Integer | The backoff for MQTT keepalive timeout.     |

**Examples:**

```bash
$ curl -i --basic -u admin:public -X GET 'http://127.0.0.1:8081/api/v4/reload' -d \
'{
    "code": 0,
    "data": {
        "property_size": 64,
        "max_packet_size": 3,
        "client_max_packet_size": 5,
        "msq_len": 2048,
        "qos_duration": 10,
        "keepalive_backoff": 1250,
        "allow_anonymous": false
    }
}'
```

## Hot Update Configuration

### POST /api/v4/reload

Set configuration that can be hot updatable.

**Parameters (json):**

| Name | Type   | Required | Value | Description                                                  |
| ---- | ------ | -------- | ----- | ------------------------------------------------------------ |
| data | Object | Required |       | See [Get hot updatable configuration](#Get hot updatable configuration)。 |

**Success Response Body (JSON):**

| Name | Type    | Description |
| ---- | ------- | ----------- |
| code | Integer | 0           |

**Examples:**

```bash
$ curl -i --basic -u admin:public -X POST 'http://localhost:8081/api/v4/reload' -d \
'{
       "data": {
        "property_size": 64,
        "max_packet_size": 3,
        "client_max_packet_size": 5,
        "msq_len": 2048,
        "qos_duration": 10,
        "keepalive_backoff": 1250,
        "allow_anonymous": false
    }
}'

{"code":0}
```


### POST /api/v4/bridges/switch/:bridge

Turn on or off the target bridging channel. This will trigger a transport disconnect and a reconnect with a failed output. Then go into silent mode.

**Parameters (json):**

| Name | Type   | Required | Value | Description                                                  |
| ---- | ------ | -------- | ----- | ------------------------------------------------------------ |
| data | Object | Required |   true/false    |  only `bridge_switch`  |

**Success Response Body (JSON):**

| Name | Type    | Description |
| ---- | ------- | ----------- |
| code | Integer | 0           |

**Examples:**

As you got a bridge setting in config file with name : `emqx1`.
```bash
$ curl -i --basic -u admin:public -X POST 'http://localhost:8081/api/v4/bridges/switch/emqx1' -d \
'{
       "data": {
        "bridge_switch": false
    }
}'

{"code":0}
```

## Update Configuration File

### POST /api/v4/config_update

Update config file.

**Parameters (json):**

| Name | Type   | Required | Value | Description                                              |
| ---- | ------ | -------- | ----- | -------------------------------------------------------- |
| data | Object | Required |       | The transferred data content is a new configuration. You can refer to the [configuration](../config-description/introduction.md) for details.|

**Success Response Body (JSON):**

| Name | Type    | Description |
| ---- | ------- | ----------- |
| code | Integer | 0           |

**Examples:**

```bash
$ curl --basic -u admin:public -X POST "http://localhost:8081/api/v4/config_update" -d \
'

 mqtt {
     property_size = 32
     max_packet_size = 10KB
     max_mqueue_len = 2048
     retry_interval = 10s
     keepalive_multiplier = 1.25
 
     # Three of below, unsupported now
     max_inflight_window = 2048
     max_awaiting_rel = 10s
     await_rel_timeout = 10s
 }
 
 listeners.tcp {
     bind = "0.0.0.0:1883"
 }
 
 # listeners.ssl {
 # 	bind = "0.0.0.0:8883"
 # 	keyfile = "/etc/certs/key.pem"
 # 	certfile = "/etc/certs/cert.pem"
 # 	cacertfile = "/etc/certs/cacert.pem"
 # 	verify_peer = false
 # 	fail_if_no_peer_cert = false
 # }
 
 listeners.ws {
     bind = "0.0.0.0:8083/mqtt"
 }
 
 http_server {
     port = 8081
     limit_conn = 2
     username = admin
     password = public
     auth_type = basic
     jwt {
         public.keyfile = "/etc/certs/jwt/jwtRS256.key.pub"
     }
 }
 
 log {
     to = [file, console]
     level = info
     dir = "/tmp"
     file = "nanomq.log"
     rotation {
         size = 10MB
         count = 5
     }
 }
 
 auth {
     allow_anonymous = true
     no_match = allow
     deny_action = ignore
 
     # password = {include "/etc/nanomq_pwd.conf"}
     # acl = {include "/etc/nanomq_acl.conf"}
 }
'

{"code":0}
```

## Get Bridges Configuration

### GET /api/v4/bridges/

Get all nodes configuration of  bridges

**Success Response Body (JSON):**

| Name                                               | Type             | Description                                                  |
| -------------------------------------------------- | ---------------- | ------------------------------------------------------------ |
| code                                               | Integer          | 0                                                            |
| data                                               | Array of Objects | All configuration of bridges' node                           |
| data.bridges.nodes[0].name                         | String           | Node name                                                    |
| data.bridges.nodes[0].enable                       | Boolean          | Enter MQTT bridge mode (default `false` ).                   |
| data.bridges.nodes[0].connector.server             | String           | Remote Broker address.                                       |
| data.bridges.nodes[0].connector.proto_ver          | Boolean          | MQTT client version（4｜5）.                                 |
| data.bridges.nodes[0].connector.clientid           | String           | MQTT client identifier.                                      |
| data.bridges.nodes[0].connector.keepalive          | Integer          | Interval of keepalive.                                       |
| data.bridges.nodes[0].connector.clean_start        | Boolean          | Clean session.                                               |
| data.bridges.nodes[0].connector.username           | String           | Login user name.                                             |
| data.bridges.nodes[0].connector.password           | String           | Login password.                                              |
| data.bridges.nodes[0].connector.conn_properties    | Object           | MQTT V5 Property of  Connector (see table below)             |
| data.bridges.nodes[0].connector.ssl.enable         | Boolean          | Launch TLS （ _default false_）。                            |
| data.bridges.nodes[0].connector.ssl.key_password   | String           | String containing the user's password. only used if the private keyfile is password-protected. |
| data.bridges.nodes[0].connector.ssl.keyfile        | String           | User's private PEM-encoded key.                              |
| data.bridges.nodes[0].connector.ssl.certfile       | String           | User certificate data.                                       |
| data.bridges.nodes[0].connector.ssl.cacertfile     | String           | User's PEM-encoded CA certificates.                          |
| data.bridges.nodes[0].quic_keepalive               | Duration         | Interval of a sending keepalive packet via QUIC transport., （_default 120s_ ) |
| data.bridges.nodes[0].quic_idle_timeout            | Duration         | How long a connection can go idle before it is gracefully shut down. 0 to disable timeout, which may lost disconnect event msg. （_default 120s_ ) |
| data.bridges.nodes[0].quic_discon_timeout          | Duration         | How long to wait for an ACK before declaring a path dead and disconnecting, This affects stream living time.（_default 20s_ ) |
| data.bridges.nodes[0].quic_handshake_timeout       | Duration         | The Max time EMQX Edge waits for establishing QUIC connection（_default 60s_ ) |
| data.bridges.nodes[0].hybrid_bridging              | Boolean          | Hybrid bridging: enable or disable the hybrid bridging mode，(default: `false`), recommend to enable it when you want to take advantage of QUIC |
| data.bridges.nodes[0].quic_send_idle_timeout       | Duration         | *Reset congestion control after being idle `SendIdleTimeout`* (*default `60s`*) |
| data.bridges.nodes[0].quic_initial_rtt_ms          | Duration         | Initial RTT estimate. (ms)<br/>(*default: `800ms`*)          |
| data.bridges.nodes[0].quic_max_ack_delay_ms        | Duration         | *How long to wait after receiving data before sending an ACK.* (*default: `100ms`*) |
| data.bridges.nodes[0].quic_qos_priority            | Boolean          | *Send QoS 1/2 msg in high prority*. (*default: `true`*)      |
| data.bridges.nodes[0].quic_0rtt                    | Boolean          | 0RTT is a feature of QUIC to re-establish *connection quickly.* . （*default: `true`*） |
| data.bridges.nodes[0].multi_stream                 | Boolean          | Multiple stream option，（_default `false`_）                |
| data.bridges.nodes[0].parallel                     | Long             | Parallel of mqtt client.                                     |
| data.bridges.nodes[0].forwards[0].remote_topic     | String           | First forward remote_topics.                                 |
| data.bridges.nodes[0].forwards[0].local_topic      | String           | First forward remote_topics.                                 |
| data.bridges.nodes[0].subscription[0].remote_topic | String           | First `remote_topic`.                                        |
| data.bridges.nodes[0].subscription[0].local_topic  | String           | First `local_topic`.                                         |
| data.bridges.nodes[0].subscription[0].qos          | Integer          | First `Qos`.                                                 |
| data.bridges.nodes[0].sub_properties               | Object           | MQTT V5 Property of Subscription (see table below)           |
| data.bridges.nodes[0].max_send_queue_len           | Integer          | Maximum number of message send queue length                  |
| data.bridges.nodes[0].max_recv_queue_len           | Integer          | Maximum number of message receive queue length               |

**Examples:**

```bash
$ curl -i --basic -u admin:public -X GET "http://localhost:8081/api/v4/bridges"

{
    "code": 0,
    "data": {
        "bridge": {
            "nodes": [
                {
                    "name": "emqx",
                    "enable": true,
                    "parallel": 2,
                    "connector": {
                        "server": "mqtt-tcp://broker.emqx.io:1883",
                        "proto_ver": 5,
                        "clientid": null,
                        "clean_start": true,
                        "username": "",
                        "password": "",
                        "keepalive": 60,
                        "conn_properties": {
                            "session_expiry_interval": 30,
                            "receive_maximum": 65535,
                            "maximum_packet_size": 0,
                            "topic_alias_maximum": 0,
                            "request_response_information": false,
                            "request_problem_information": true
                        },
                        "will_properties": {
                            "payload_format_indicator": 0,
                            "message_expiry_interval": 360,
                            "will_delay_interval": 20,
                            "user_properties": [
                                {
                                    "key": "key1",
                                    "value": "value1"
                                },
                                {
                                    "key": "key2",
                                    "value": "value2"
                                }
                            ]
                        }
                    },
                    "forwards": [
                        {
                            "remote_topic": "fwd/topic1",
                            "local_topic": "topic1",
                        },
                        {
                            "remote_topic": "fwd/topic2",
                            "local_topic": "topic2",
                        }
                    ],
                    "subscription": [
                        {
                            "remote_topic": "cmd/topic1",
                            "local_topic": "topic1",
                            "qos": 1
                        },
                        {
                            "remote_topic": "cmd/topic2",
                            "local_topic": "topic2",
                            "qos": 2
                        }
                    ],
                    "sub_properties": {
                        "identifier": 1,
                        "user_properties": [
                            {
                                "key": "key1",
                                "value": "value1"
                            },
                            {
                                "key": "key2",
                                "value": "value2"
                            }
                        ]
                    },
                    "tls": {
                        "enable": false,
                        "url": null,
                        "key_password": null,
                        "key": null,
                        "cert": null,
                        "cacert": null,
                        "verify_peer": false,
                        "fail_if_no_peer_cert": false
                    }
                }
            ]
        }
    }
}
```

### GET /api/v4/bridges/{bridge_name}

Returns configuration for the specified bridge node.

**Path Parameters:**

| Name        | Type   | Required | Description      |
| ----------- | ------ | -------- | ---------------- |
| bridge_name | String | True     | bridge node name |

**Success Response Body (JSON):**

| Name | Type             | Description                                                  |
| ---- | ---------------- | ------------------------------------------------------------ |
| code | Integer          | 0                                                            |
| data | Array of Objects | for details, see [GET /api/v4/bridges](#GET /api/v4/bridges/) |

**Example:**

```bash
$ curl -i --basic -u admin:public -X GET "http://localhost:8081/api/v4/bridges/emqx"

{
    "code": 0,
    "data": {
        "bridge": {
            "nodes": [
                {
                    "name": "emqx",
                    "enable": true,
                    "parallel": 2,
                    "connector": {
                        "server": "mqtt-tcp://broker.emqx.io:1883",
                        "proto_ver": 5,
                        "clientid": null,
                        "clean_start": true,
                        "username": "",
                        "password": "",
                        "keepalive": 60,
                        "conn_properties": {
                            "session_expiry_interval": 30,
                            "receive_maximum": 65535,
                            "maximum_packet_size": 0,
                            "topic_alias_maximum": 0,
                            "request_response_information": false,
                            "request_problem_information": true
                        },
                        "will_properties": {
                            "payload_format_indicator": 0,
                            "message_expiry_interval": 360,
                            "will_delay_interval": 20,
                            "user_properties": [
                                {
                                    "key": "key1",
                                    "value": "value1"
                                },
                                {
                                    "key": "key2",
                                    "value": "value2"
                                }
                            ]
                        }
                    },
                    "forwards": [
                        {
                            "remote_topic": "fwd/topic1",
                            "local_topic": "topic1",
                        },
                        {
                            "remote_topic": "fwd/topic2",
                            "local_topic": "topic2",
                        }
                    ],
                    "subscription": [
                        {
                            "remote_topic": "cmd/topic1",
                            "local_topic": "topic1",
                            "qos": 1
                        },
                        {
                            "remote_topic": "cmd/topic2",
                            "local_topic": "topic2",
                            "qos": 2
                        }
                    ],
                    "sub_properties": {
                        "identifier": 1,
                        "user_properties": [
                            {
                                "key": "key1",
                                "value": "value1"
                            },
                            {
                                "key": "key2",
                                "value": "value2"
                            }
                        ]
                    },
                    "tls": {
                        "enable": false,
                        "url": null,
                        "key_password": null,
                        "key": null,
                        "cert": null,
                        "cacert": null,
                        "verify_peer": false,
                        "fail_if_no_peer_cert": false
                    }
                }
            ]
        }
    }
}
```

## Update Bridge Configuration

### PUT /api/v4/bridges/{bridge_name}

update bridge configuration dynamically, and trigger a reconnection to valid it. (This API works for TLS/TCP & QUIC bridging)

**Path Parameters:**

| Name        | Type   | Required | Description      |
| ----------- | ------ | -------- | ---------------- |
| bridge_name | String | True     | bridge node name |

**Success Response Body (JSON):**


| Name                              | Type          | Description                                                  |
| -------------------------------    | ------------- | ------------------------------------------------------------ |
| code                              | Integer       | 0                                                            |
| bridge_name                        | Objects       | name of bridging node                                           |
| bridge_name.name                    | String        | Node name                                                   |
| bridge_name.enable                     | Boolean       | MQTT bridge mode (default `false` ).                  |
| bridge_name.server                      | String        | Remote Broker address.                                     |
| bridge_name.proto_ver                   | Integer       | MQTT client version（4｜5）                           |
| bridge_name.clientid                   | String        | MQTT client identifier.                     |
| bridge_name.keepalive                  | Duration      | Interval of keepalive.                                              |
| bridge_name.clean_start                | Boolean       | Clean session flag.                                                  |
| bridge_name.username                   | String        | Login user name.                                                |
| bridge_name.password                   | String        | Login password.                                                |
| bridge_name.conn_properties            | Object        | MQTT V5 Property                                    |
| bridge_name.will_properties            | Object        | MQTT V5 Property of  will message                    |
| bridge_name.ssl.enable                | Boolean       | Launch TLS                               |
| bridge_name.ssl.key_password           | String        | String containing the user's password. only used if the private keyfile is password-protected.         |
| bridge_name.ssl.keyfile                | String        | User's private PEM-encoded key.                               |
| bridge_name.ssl.certfile              | String        | User certificate data.                                       |
| bridge_name.ssl.cacertfile            | String        | User's PEM-encoded CA certificates.                                |
| bridge_name.parallel                   | Long          | number of Parallel processor of mqtt client.                                           |
| bridge_name.forwards[0].remote_topic   | String        | No.x forward remote_topic.                     |
| bridge_name.forwards[0].local_topic    | String        | No.x forward local_topic.                     |
| bridge_name.subscription[0].remote_topic      | String        | No.x subscribe `remote_topic`.                                           |
| bridge_name.subscription[0].local_topic       | String        | No.x subscribe `local_topic`.                                            |
| bridge_name.subscription[0].qos        | Integer       | No.x subscribe `Qos`.                                           |
| bridge_name.sub_properties             | Object        | MQTT V5 Property of Subscription (see table below)                              |
| bridge_name.max_send_queue_len         | Integer       | Maximum number of message send queue length                              |
| bridge_name.max_recv_queue_len         | Integer       | Maximum number of message receive queue length                 |

**Example**: 

```bash
$ curl -i --basic -u admin:public -X PUT 'http://localhost:8081/api/v4/bridges/emqx' -d '{
    "emqx": {
        "name": "emqx",
        "enable": true,
        "parallel": 8,
        "server": "mqtt-tcp://broker.emqx.io:1883",
        "proto_ver": 4,
        "clientid": "hello3",
        "clean_start": true,
        "username": "emqx",
        "password": "emqx123",
        "keepalive": 60,
        "forwards": [
            {
                "remote_topic": "fwd/topic1",
                "local_topic": "local/topic1"
            },
            {
                "remote_topic": "fwd/topic3",
                "local_topic": "local/topic3"
            }
        ],
        "subscription": [
            {
                "remote_topic": "cmd/topic1",
                "local_topic": "local/topic1",
                "qos": 1
            },
            {
                "remote_topic": "cmd/topic3",
                "local_topic": "local/topic3",
                "qos": 2
            }
        ]
    }
}'

{"code":0}

```
Returning 108 may be due to one of the following two reasons:

Incorrect specification of the "name" parameter in the URL.
A naming error in the JSON. For example, in the above example, the "emqx" in the JSON does not match the "emqx" name in the URL.
Returning 109 is because the JSON data is invalid.

### PUT /api/v4/bridges/sub/{bridge_name}

Dynamically change the subscription Topics of bridging connection. (works for both TCP & QUIC)

**Path Parameters:**

| Name        | Type   | Required | Description  |
| ----------- | ------ | -------- | ------------ |
| bridge_name | String | True     | bridge node name |

| Name        | Type   | Required | Description  |
| ----------- | ------ | -------- | ------------ |
| code                            | Integer       | 0                                                            |
| data                            | Objects       | bridge node name                                           |
| data.subscription[0].remote_topic | String        | subscription remote_topic                                          |
| data.subscription[0].local_topic  | String        | subscription local_topic                                           |
| data.subscription[0].qos        | Integer       | subscription QoS                                         |
| data.sub_properties             | Object        | Subscription MQTT V5 property                                    |
| data.sub_properties.identifier  | Integer        | Subscription id                          |
| data.sub_properties.user_properties  | Object        | Subscription user property                               |

**Example**: 

Take bridge name = EMQX as an example

```bash
$ curl --location 'http://127.0.0.1:8081/api/v4/bridges/sub/emqx' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic YWRtaW46cHVibGlj' \
--data '{
    "data": {
        "subscription": [
            {
                "remote_topic": "cmd/topic4",
                "local_topic": "topic4",
                "qos": 1
            },
            {
                "remote_topic": "cmd/topic5",
                "local_topic": "topic5",
                "qos": 2
            }
        ],
        "sub_properties": {
            "identifier": 1,
            "user_properties": [
                {
                    "key": "key1",
                    "value": "value1"
                },
                {
                    "key": "key2",
                    "value": "value2"
                }
            ]
        }
    }
}'

{"code":0}

```

### PUT /api/v4/bridges/unsub/{bridge_name}

Dynamically change the subscription Topics of bridging connection. (works for both TCP & QUIC)

**Path Parameters:**

| Name        | Type   | Required | Description  |
| ----------- | ------ | -------- | ------------ |
| bridge_name | String | True     | bridge node name |

**Success Response Body (JSON):**

| Name        | Type   | Required | Description  |
| ----------- | ------ | -------- | ------------ |
| code                            | Integer       | 0                                                            |
| data                            | Objects       | bridge node name                                           |
| data.unsubscription[0].topic      | String        | subscription topic                                          |
| data.unsubscription[0].qos        | Integer       | subscription QoS                                         |
| data.unsub_properties             | Object        | Subscription MQTT V5 property                                    |
| data.unsub_properties.identifier  | Integer        | Subscription id                          |
| data.unsub_properties.user_properties  | Object        | Subscription user property                               |

**Example**: 

```bash
$ curl --location 'http://127.0.0.1:8081/api/v4/bridges/unsub/emqx' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic YWRtaW46cHVibGlj' \
--data '{
    "data": {
        "unsubscription": [
            {
                "topic": "cmd/topic1"
            },
            {
                "topic": "cmd/topic2"
            }
        ],
        "unsub_properties": {
            "user_properties": [
                {
                    "key": "key1",
                    "value": "value1"
                },
                {
                    "key": "key2",
                    "value": "value2"
                }
            ]
        }
    }
}'

{"code":0}

```

## Broker Control

### POST /api/v4/ctrl/{action}

Stop or Restart the EMQX Edge（Usually used after the configuration is modified).

**Path Parameters:**

| Name     | Type   | Required | Description                             |
| -------- | ------ | -------- | --------------------------------------- |
| clientid | String | True     | Possible values are  `stop`,  `restart` |

**Success Response Body (JSON):**

| Name | Type    | Description |
| ---- | ------- | ----------- |
| code | Integer | 0           |

**Examples:**

```bash
$ curl -i --basic -u admin:public -X POST 'http://localhost:8081/api/v4/ctrl/restart'

{"code":0}
```
