# LitmusEdge 4.0.x API Documentation/DataHub - LE, LEM, LUNS API Docs

## DataHub Prometheus Metrics

**GET** `{{edgeUrl}}/stats/metrics`

# DataHub Prometheus Metrics

Returns host-level metrics for the edge device in the [Prometheus exposition format](https://prometheus.io/docs/instrumenting/exposition_formats/). Suitable for direct Prometheus scraping or ad-hoc inspection.

## Endpoint

```http
GET {{edgeUrl}}/stats/metrics
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.

## Parameters

None.

## Response

`200 OK` -- `text/plain; version=0.0.4`. Each metric is preceded by `# HELP` and `# TYPE` lines, then one line per labelled series. See the folder description for the full metric reference.

### Metric reference

| Metric                       | Type     | Labels         | Description                                            |
|------------------------------|----------|----------------|--------------------------------------------------------|
| `node_cpu_idle`              | gauge    | -              | Percent CPU time idle.                                 |
| `node_cpu_system`            | gauge    | -              | Percent CPU time in kernel mode.                       |
| `node_cpu_user`              | gauge    | -              | Percent CPU time in user mode.                         |
| `node_memory_used`           | gauge    | -              | Percent RAM in use.                                    |
| `node_nats_in_msgs`          | gauge    | -              | Cumulative NATS messages received by the device.       |
| `node_network_receive`       | counter  | `name=<iface>` | Bytes received on the interface since service start.   |
| `node_network_transmit`      | counter  | `name=<iface>` | Bytes transmitted on the interface since service start.|
| `node_storage_available`     | gauge    | `name=<mount>` | Available KB on the mountpoint.                        |
| `node_storage_size`          | gauge    | `name=<mount>` | Total KB on the mountpoint.                            |
| `node_storage_used`          | gauge    | `name=<mount>` | Used KB on the mountpoint.                             |

### Example response (truncated)

```text
# HELP node_cpu_idle
# TYPE node_cpu_idle gauge
node_cpu_idle 90.77242094654251

# HELP node_cpu_system
# TYPE node_cpu_system gauge
node_cpu_system 3.784344219881847

# HELP node_cpu_user
# TYPE node_cpu_user gauge
node_cpu_user 5.443234836593142

# HELP node_memory_used
# TYPE node_memory_used gauge
node_memory_used 20.15496389734451

# HELP node_nats_in_msgs
# TYPE node_nats_in_msgs gauge
node_nats_in_msgs 1.05415912e+08

# HELP node_network_receive
# TYPE node_network_receive counter
node_network_receive{name="docker0"} 1.62779761077e+11
node_network_receive{name="eth0"} 4.7081310056e+10
node_network_receive{name="lo"} 6.82276687829e+11

# HELP node_network_transmit
# TYPE node_network_transmit counter
node_network_transmit{name="docker0"} 4.0711565138e+10
node_network_transmit{name="eth0"} 8.627412486e+09

# HELP node_storage_available
# TYPE node_storage_available gauge
node_storage_available{name="/"}     315788
node_storage_available{name="/var"}  2.00132136e+08

# HELP node_storage_size
# TYPE node_storage_size gauge
node_storage_size{name="/"}    2.874152e+06
node_storage_size{name="/var"} 2.2916288e+08

# HELP node_storage_used
# TYPE node_storage_used gauge
node_storage_used{name="/"}    2.384696e+06
node_storage_used{name="/var"} 2.7965784e+07
```

## Useful PromQL recipes

```promql
# CPU busy percent (system + user)
node_cpu_system + node_cpu_user

# Network throughput, all interfaces, bps over 5m
sum by (name) (rate(node_network_receive[5m]) * 8)

# Storage used percent per mount
100 * node_storage_used / node_storage_size

# Alert: less than 10% storage free
(node_storage_available / node_storage_size) * 100 < 10
```

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Response

**Status**: 200 OK

```plain
# HELP node_cpu_idle 
# TYPE node_cpu_idle gauge
node_cpu_idle 90.77242094654251
# HELP node_cpu_system 
# TYPE node_cpu_system gauge
node_cpu_system 3.784344219881847
# HELP node_cpu_user 
# TYPE node_cpu_user gauge
node_cpu_user 5.443234836593142
# HELP node_memory_used 
# TYPE node_memory_used gauge
node_memory_used 20.15496389734451
# HELP node_nats_in_msgs 
# TYPE node_nats_in_msgs gauge
node_nats_in_msgs 1.05415912e+08
# HELP node_network_receive 
# TYPE node_network_receive counter
node_network_receive{name="docker0"} 1.62779761077e+11
node_network_receive{name="emwg0"} 1.890480016e+09
node_network_receive{name="eth0"} 4.7081310056e+10
node_network_receive{name="lo"} 6.82276687829e+11
node_network_receive{name="sit0"} 0
node_network_receive{name="veth2298211"} 7.5335735e+08
node_network_receive{name="veth2b4e34d"} 1.263569924e+09
node_network_receive{name="veth38d99f0"} 0
node_network_receive{name="veth3a43086"} 1.347649906e+09
node_network_receive{name="veth491add8"} 0
node_network_receive{name="veth8742c66"} 0
node_network_receive{name="veth9764d41"} 1.59776211428e+11
node_network_receive{name="vethb99baa7"} 0
node_network_receive{name="wlan0"} 0
# HELP node_network_transmit 
# TYPE node_network_transmit counter
node_network_transmit{name="docker0"} 4.0711565138e+10
node_network_transmit{name="emwg0"} 4.5071758e+09
node_network_transmit{name="eth0"} 8.627412486e+09
node_network_transmit{name="lo"} 6.82276687829e+11
node_network_transmit{name="sit0"} 0
node_network_transmit{name="veth2298211"} 7.29919042e+08
node_network_transmit{name="veth2b4e34d"} 4.79400296e+08
node_network_transmit{name="veth38d99f0"} 55851
node_network_transmit{name="veth3a43086"} 3.519432629e+09
node_network_transmit{name="veth491add8"} 0
node_network_transmit{name="veth8742c66"} 55781
node_network_transmit{name="veth9764d41"} 3.5982957856e+10
node_network_transmit{name="vethb99baa7"} 56615
node_network_transmit{name="wlan0"} 0
# HELP node_storage_available 
# TYPE node_storage_available gauge
node_storage_available{name="/"} 315788
node_storage_available{name="/var"} 2.00132136e+08
# HELP node_storage_size 
# TYPE node_storage_size gauge
node_storage_size{name="/"} 2.874152e+06
node_storage_size{name="/var"} 2.2916288e+08
# HELP node_storage_used 
# TYPE node_storage_used gauge
node_storage_used{name="/"} 2.384696e+06
node_storage_used{name="/var"} 2.7965784e+07

```

---

## Timeseries DB Info

**GET** `{{edgeUrl}}/stats/tsdb`

# Timeseries DB Info

Returns which time-series DB source the device is currently using and whether persistence is enabled. The same information is shown in the LE UI's **Data Hub** page header.

## Endpoint

```http
GET {{edgeUrl}}/stats/tsdb
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.

## Parameters

None.

## Response

`200 OK` -- `application/json`

| Field          | Type      | Description                                                                                          |
|----------------|-----------|------------------------------------------------------------------------------------------------------|
| `source`       | string    | Active source: `internal` (device-hosted InfluxDB) or `external` (remote DB).                        |
| `is_enabled`   | boolean   | `true` when persistence to the TSDB is on. When `false`, DeviceHub publishes to topics but does not write to the TSDB. |

```json
{
  "source": "internal",
  "is_enabled": true
}
```

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Response

**Status**: 200 OK

```json
{
    "source": "internal",
    "is_enabled": true
}
```

---

## Set Timeseries DB State

**PUT** `{{edgeUrl}}/stats/tsdb/state/{state}`

# Set Timeseries DB State

Enables or disables persistence to the active time-series DB. While disabled, DeviceHub continues to publish tag values to topics but does **not** write them to the TSDB -- so dashboards driven by the TSDB will stop seeing new data even though live consumers (MQTT, Integrations) keep receiving updates.

## Endpoint

``` http
PUT {{edgeUrl}}/stats/tsdb/state/{state}

 ```

`{state}` is part of the path -- pass `enable` to turn persistence on, `disable` to turn it off. The path parameter is not URL-encoded.

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.

## Parameters

| Location | Name | Required | Description |
| --- | --- | --- | --- |
| Path | `{state}` | Yes | `enable` or `disable` (lowercase). |

No request body.

## Response

`200 OK` on success. The change applies immediately; the next call to `Timeseries DB Info` will reflect the new `is_enabled`.

## Errors

| HTTP status | When it happens |
| --- | --- |
| `400 Bad Request` | Missing or malformed query/body parameter. |
| `401 Unauthorized` | Missing or invalid credentials. |
| `403 Forbidden` | Token lacks permission for this operation. |
| `404 Not Found` | Target entity does not exist. |
| `5xx` | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.

---

## Set active DB source

**PUT** `{{edgeUrl}}/stats/tsdb/dbsource/{{db_source_type}}`

# Set active DB source

Configures the active time-series DB source (internal or external) and persists its connection settings. Switching the source does **not** migrate existing measurements -- they remain under the previous source.

For internal Influx v1.x, only `db_uri`/`db_vendor`/`name`/`description` are typically relevant. For external Influx v2.x, fill in `db_influx2_auth_token` and `db_influx2_org_name` plus the bucket name in `name`.

## Endpoint

```http
PUT {{edgeUrl}}/stats/tsdb/dbsource/{{db_source_type}}
Content-Type: application/json
```

`{{db_source_type}}` is `internal` or `external`. Use `Get DB Vendors` to enumerate the valid `db_vendor` values for the body.

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.

## Path parameters

| Location | Name                  | Required | Description                                  |
|----------|-----------------------|----------|----------------------------------------------|
| Path     | `{{db_source_type}}`  | Yes      | `internal` or `external`.                    |

## Request body

```json
{
  "db_vendor": "influx_v2.x",
  "name": "DB Name",
  "description": "Short description",
  "db_uri": "DB connection string",
  "db_username": "InfluxDB 1.x - DB Username",
  "db_password": "InfluxDB 1.x - DB Password",
  "db_influx2_auth_token": "InfluxDB 2.x - Auth Token",
  "db_influx2_org_name": "InfluxDB 2.x - Org Name"
}
```

| Field                     | Type   | Required | Description                                                                                          |
|---------------------------|--------|----------|------------------------------------------------------------------------------------------------------|
| `db_vendor`               | string | Yes      | Vendor key from `Get DB Vendors` (e.g. `influx_v1.x`, `influx_v2.x`).                                |
| `name`                    | string | Yes      | Database name (Influx 1.x) or bucket name (Influx 2.x).                                              |
| `description`             | string | No       | Free-form description.                                                                               |
| `db_uri`                  | string | Yes      | Connection URL (e.g. `http://10.17.8.50:8086`).                                                      |
| `db_username`             | string | mixed    | Required for Influx 1.x credentials. Ignored for Influx 2.x token auth.                              |
| `db_password`             | string | mixed    | Required for Influx 1.x credentials.                                                                 |
| `db_influx2_auth_token`   | string | mixed    | Required for Influx 2.x token auth.                                                                  |
| `db_influx2_org_name`     | string | mixed    | Influx 2.x organization name.                                                                        |

## Response

`200 OK` on success. The new source is active immediately. Run `Test DB Connection` to confirm the connection works.

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Request Body

```json
{
    "db_influx2_auth_token": "InfluxDB 2.x - Auth Token",
    "db_influx2_org_name": "InfluxDB 2.x - Org Name",
    "db_password": "InfluxDB 2.x - DB Password",
    "db_uri": "DB connection string",
    "db_username": "InfluxDB 1.x - DB Username",
    "db_vendor": "vendor",
    "description": "Short description",
    "name": "DB Name"
}
```

---

## Get DB Vendors

**GET** `{{edgeUrl}}/stats/tsdb/dbvendors`

# Get DB Vendors

Returns the list of supported time-series DB vendor keys. Use this to populate a vendor picker in custom admin UIs, or to validate the `db_vendor` value before calling `Set active DB source`.

## Endpoint

```http
GET {{edgeUrl}}/stats/tsdb/dbvendors
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.

## Parameters

None.

## Response

`200 OK` -- `application/json`. Array of vendor objects.

| Field   | Type   | Description                                                              |
|---------|--------|--------------------------------------------------------------------------|
| `value` | string | Vendor key. Pass this as `db_vendor` in `Set active DB source`.          |
| `label` | string | Human-readable label suitable for a UI picker.                           |

```json
[
  { "value": "influx_v1.x", "label": "InfluxDB v1.x" },
  { "value": "influx_v2.x", "label": "InfluxDB v2.x" }
]
```

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Response

**Status**: 200 OK

```json
[
    {
        "value": "influx_v1.x",
        "label": "InfluxDB v1.x"
    },
    {
        "value": "influx_v2.x",
        "label": "InfluxDB v2.x"
    }
]
```

---

## Test DB Connection

**GET** `{{edgeUrl}}/stats/tsdb/dbsource/{{db_source_type}}/test`

# Test DB Connection

Performs a connection test against the configured DB source and returns whether it succeeded along with the upstream version banner. Use this after `Set active DB source` to confirm credentials are valid before flipping `Set Timeseries DB State` to `enable`.

## Endpoint

```http
GET {{edgeUrl}}/stats/tsdb/dbsource/{{db_source_type}}/test
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.

## Path parameters

| Location | Name                  | Required | Description                                  |
|----------|-----------------------|----------|----------------------------------------------|
| Path     | `{{db_source_type}}`  | Yes      | `internal` or `external`.                    |

## Response

`200 OK` -- `application/json`

| Field           | Type      | Description                                                                                          |
|-----------------|-----------|------------------------------------------------------------------------------------------------------|
| `is_connected`  | boolean   | `true` if the connection succeeded; `false` otherwise.                                               |
| `response`      | string    | Upstream's version banner (e.g. `InfluxDB v1.7.7`) on success, or an error string on failure.        |

```json
{
  "is_connected": true,
  "response": "InfluxDB v1.7.7"
}
```

A `false` `is_connected` does not return a non-`200` status -- inspect `response` for the error string.

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Response

**Status**: 200 OK

```json
{
    "is_connected": true,
    "response": "InfluxDB v1.7.7"
}
```

---

## List DBs

**GET** `{{edgeUrl}}/stats/db`

# List DBs

Lists every database on the active time-series source along with each database's on-disk size (bytes) and the names of its measurements. DeviceHub creates measurements named `<DeviceName>.<DeviceID>` by default; analytics components contribute measurements like `Anomaly`, `OEEData`, `EnergyMonitoring`, etc.

## Endpoint

```http
GET {{edgeUrl}}/stats/db
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.

## Parameters

None.

## Response

`200 OK` -- `application/json`. Array of database objects.

| Field            | Type       | Description                                                                                |
|------------------|------------|--------------------------------------------------------------------------------------------|
| `name`           | string     | Database name (or bucket for Influx 2.x).                                                  |
| `size`           | integer    | On-disk size in **bytes**.                                                                 |
| `measurements`   | string[]   | Measurement (table) names inside the database.                                             |

```json
[
  {
    "name": "tsdata",
    "size": 69788326,
    "measurements": [
      "Anomaly",
      "OEEData",
      "P1_L1_Machine1_1_OPC.7C24EDB3-D95C-4097-ADFE-EA7228175ACD",
      "P2_L2_Machine1_1_OPC.538054E8-2349-4AD0-8C87-830C9A06B118",
      "classification"
    ]
  }
]
```

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Response

**Status**: 200 OK

```Text
[
    {
        "name": "tsdata",
        "size": 69788326,
        "measurements": [
            "Anomaly",
            "DTR",
            "EnergyMonitoring",
            "OEEData",
            "P1_L1_Machine1_1_OPC.7C24EDB3-D95C-4097-ADFE-EA7228175ACD",
            "P1_L1_Machine2_1_MB.16FC5E6A-345A-4257-A939-9E13F5C416F1",
            "P1_L1_Machine3_1_S7.024F0542-540E-4556-8445-13F5158A9E67",
            "P1_L2_Machine2_1_MB.0A99BA31-89B9-45B3-822B-3A94CDDAB411",
            "P1_L2_Machine3_1_S7.55C2503D-A9A1-4F0E-A538-EA74E98187ED",
            "P2_L1_Machine1_1_OPC.F96584F6-DD85-4B7D-9053-53C68C67D290",
            "P2_L1_Machine2_1_MB.7BF01228-1B5C-4EFE-9E3C-8E01E2F7F2F6",
            "P2_L1_Machine3_1_S7.94D8E47F-9307-47F7-9F8E-B47AE6B90695",
            "P2_L2_Machine1_1_OPC.538054E8-2349-4AD0-8C87-830C9A06B118",
            "P2_L2_Machine2_1_MB.CEEEF257-0DB8-4F0C-9C0F-B17301B7A673",
            "P2_L2_Machine3_1_S7.C27E0DAC-B863-489F-8A19-F526EE6FE2D2",
            "SR",
            "XMR",
            "classification"
        ]
    }
]
```

---

## Create Database

**POST** `{{edgeUrl}}/stats/db`

# Create Database

Creates a new database on the active time-series source. Useful for isolating analytics outputs (e.g. classification, OEE) from device tag data, or as part of a multi-tenant setup.

The database is created with default retention. To configure retention policies, use the InfluxDB CLI or HTTP API directly -- LE does not expose retention management.

## Endpoint

```http
POST {{edgeUrl}}/stats/db
Content-Type: application/json
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.

## Request body

```json
{
  "dbName": "apiTest"
}
```

| Field    | Type   | Required | Description                                              |
|----------|--------|----------|----------------------------------------------------------|
| `dbName` | string | Yes      | Name of the database to create. Must be unique.          |

## Response

`200 OK` on success.

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Request Body

```json
{
    "dbName": "apiTest"
}
```

### Response

**Status**: 204 No Content

---

## Delete Measurement

**DELETE** `{{edgeUrl}}/stats/db/{{db_name}}/measurements/{{db_measurement}}`

# Delete Measurement

Deletes a single measurement (table) inside a database. **Destructive and immediate** -- every point in the measurement is removed. Use this to drop a device's persisted history without dropping the whole database.

## Endpoint

```http
DELETE {{edgeUrl}}/stats/db/{{db_name}}/measurements/{{db_measurement}}
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.

## Path parameters

| Location | Name                  | Required | Description                                              |
|----------|-----------------------|----------|----------------------------------------------------------|
| Path     | `{{db_name}}`         | Yes      | Database name.                                           |
| Path     | `{{db_measurement}}`  | Yes      | Measurement name. URL-encode if it contains special characters. |

No request body.

## Response

`200 OK` on success.

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

### Recovering after a bad delete

There is no undo -- once a measurement is dropped, the data is gone. For DeviceHub-backed measurements, new points will start accumulating again on the next poll, but historical data is not recoverable without a backup. Consider exporting from the TSDB before bulk deletes.

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


---

## Delete Database

**DELETE** `{{edgeUrl}}/stats/db/{{db_name}}`

# Delete Database

Deletes an entire database. **Destructive and immediate** -- every measurement and every point inside the database is removed.

Do not delete the default `tsdata` database unless you intend to wipe all DeviceHub-persisted history; some LE components assume `tsdata` exists and will fail to write until it is recreated.

## Endpoint

```http
DELETE {{edgeUrl}}/stats/db/{{db_name}}
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.

## Path parameters

| Location | Name          | Required | Description                                  |
|----------|---------------|----------|----------------------------------------------|
| Path     | `{{db_name}}` | Yes      | Database name to delete.                     |

No request body.

## Response

`200 OK` on success.

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


---

## List DB Users

**GET** `{{edgeUrl}}/stats/users`

# List DB Users

Lists every database user currently provisioned on the active TSDB source, along with their per-database grants. These are **DB-level credentials** used by external clients that read or write the TSDB directly -- not LE API users.

## Endpoint

```http
GET {{edgeUrl}}/stats/users
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.

## Parameters

None.

## Response

`200 OK` -- `application/json`. Array of user objects.

| Field                       | Type            | Description                                                                                          |
|-----------------------------|-----------------|------------------------------------------------------------------------------------------------------|
| `name`                      | string          | DB user name.                                                                                        |
| `grants`                    | object[]        | One entry per database the user has privileges on.                                                   |
| `grants[].database`         | string          | Database name.                                                                                       |
| `grants[].privileges`       | string          | Privilege level: `READ`, `WRITE`, `ALL`, `NO PRIVILEGES`.                                            |

```json
[
  {
    "name": "observer",
    "grants": [
      { "database": "le_stats", "privileges": "READ" },
      { "database": "tsdata",   "privileges": "READ" }
    ]
  }
]
```

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Response

**Status**: 200 OK

```Text
[
    {
        "name": "observer",
        "grants": [
            {
                "database": "le_stats",
                "privileges": "READ"
            },
            {
                "database": "tsdata",
                "privileges": "READ"
            }
        ]
    }
]
```

---

## Create User

**POST** `{{edgeUrl}}/stats/users`

# Create User

Creates a new database user with one or more `(database, privileges)` grants. The user is created on the active TSDB source -- to provision on a different source, switch with `Set active DB source` first.

## Endpoint

```http
POST {{edgeUrl}}/stats/users
Content-Type: application/json
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.

## Request body

```json
{
  "name": "apiTest",
  "password": "****",
  "grants": [
    { "database": "tsdata", "privileges": "READ" }
  ]
}
```

| Field                   | Type     | Required | Description                                                                                |
|-------------------------|----------|----------|--------------------------------------------------------------------------------------------|
| `name`                  | string   | Yes      | User name. Must be unique on the source.                                                   |
| `password`              | string   | Yes      | User password. Sent in clear text -- ensure the request is over HTTPS.                     |
| `grants`                | object[] | Yes      | Initial privileges. Can be empty `[]` to create the user without grants; use `Grant Privileges to User` later. |
| `grants[].database`     | string   | Yes      | Database name. Must exist; otherwise the call fails.                                       |
| `grants[].privileges`   | string   | Yes      | Privilege: `READ`, `WRITE`, `ALL`, `NO PRIVILEGES`.                                        |

## Response

`200 OK` on success.

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Request Body

```json
{
    "grants": [
        {
            "database": "tsdata",
            "privileges": "READ"
        }
    ],
    "name": "apiTest",
    "password": "****"
}
```

### Response

**Status**: 204 No Content

---

## Grant Privileges to User

**PUT** `{{edgeUrl}}/stats/users/{{db_username}}/grant_privileges`

# Grant Privileges to User

Adds or changes a user's privileges on a single database. The mutation is **per-database**; to grant privileges across multiple databases, call this endpoint once per database.

## Endpoint

```http
PUT {{edgeUrl}}/stats/users/{{db_username}}/grant_privileges
Content-Type: application/json
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.

## Path parameters

| Location | Name             | Required | Description                                  |
|----------|------------------|----------|----------------------------------------------|
| Path     | `{{db_username}}`| Yes      | User name to update.                         |

## Request body

```json
{
  "database": "tsdata",
  "privileges": "READ"
}
```

| Field          | Type     | Required | Description                                                       |
|----------------|----------|----------|-------------------------------------------------------------------|
| `database`     | string   | Yes      | Database name to grant on.                                        |
| `privileges`   | string   | Yes      | Privilege level: `WRITE`, `READ`, `ALL`, `NO PRIVILEGES`.         |

## Response

`200 OK` on success. The new grant is visible on the next call to `List DB Users`.

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Request Body

```json
{
    "database": "tsdata",
    "privileges":"Enum WRITE, READ, ALL, NO PRIVILEGES"
}
```

### Response

**Status**: 204 No Content

---

## Revoke Privileges from User

**PUT** `{{edgeUrl}}/stats/users/{{db_username}}/revoke_privileges`

# Revoke Privileges from User

Removes a previously granted privilege from a user on a specific database. Pass the exact privilege value to revoke -- this is not a bulk operation.

## Endpoint

```http
PUT {{edgeUrl}}/stats/users/{{db_username}}/revoke_privileges
Content-Type: application/json
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.

## Path parameters

| Location | Name             | Required | Description                                  |
|----------|------------------|----------|----------------------------------------------|
| Path     | `{{db_username}}`| Yes      | User name to update.                         |

## Request body

```json
{
  "database": "tsdata",
  "privileges": "WRITE"
}
```

| Field          | Type     | Required | Description                                              |
|----------------|----------|----------|----------------------------------------------------------|
| `database`     | string   | Yes      | Database name.                                           |
| `privileges`   | string   | Yes      | Privilege to remove: `WRITE`, `READ`, `ALL`.             |

## Response

`200 OK` on success.

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

### Privilege model

In Influx 1.x, granting `READ` and `WRITE` separately is equivalent to granting `ALL`. Revoking `WRITE` from a user with `ALL` leaves them with `READ`. To remove all access on a database in one call, revoke `ALL`.

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Request Body

```json
{
    "database": "tsdata",
    "privileges": "WRITE"
}
```

### Response

**Status**: 204 No Content

---

## Reset User Password

**PUT** `{{edgeUrl}}/stats/users/{{db_username}}/password`

# Reset User Password

Sets a new password for an existing DB user. The previous password is discarded immediately. Issuing this call while a client is mid-query with the old password does not interrupt the in-flight query, but the client's next connection will fail until it picks up the new password.

## Endpoint

```http
PUT {{edgeUrl}}/stats/users/{{db_username}}/password
Content-Type: application/json
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.

## Path parameters

| Location | Name             | Required | Description                                  |
|----------|------------------|----------|----------------------------------------------|
| Path     | `{{db_username}}`| Yes      | User name to update.                         |

## Request body

```json
{
  "password": "newPassword"
}
```

| Field      | Type   | Required | Description                                                            |
|------------|--------|----------|------------------------------------------------------------------------|
| `password` | string | Yes      | New password. Sent in clear text -- ensure the request is over HTTPS. |

## Response

`200 OK` on success.

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


---

## Delete User

**DELETE** `{{edgeUrl}}/stats/users/{{db_username}}/delete`

# Delete User

Permanently deletes a DB user. All of their grants are removed; in-flight queries authenticated as that user will continue to completion, but subsequent connection attempts fail.

## Endpoint

```http
DELETE {{edgeUrl}}/stats/users/{{db_username}}/delete
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.

## Path parameters

| Location | Name             | Required | Description                                  |
|----------|------------------|----------|----------------------------------------------|
| Path     | `{{db_username}}`| Yes      | User name to delete.                         |

No request body.

## Response

`200 OK` on success.

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Response

**Status**: 204 No Content

---

