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

# TDengine

> Client-mode REST API connector for TDengine: SQL over taosAdapter REST, InfluxDB line protocol and OpenTSDB JSON schemaless writes from MQTT, row-object queries, and /-/ping health

Technical Preview

## Overview

A client-mode connector for the [TDengine REST API](https://docs.tdengine.com/developer-guide/connectors-reference/rest-api/) served by [taosAdapter](https://docs.tdengine.com/operations-and-tooling/components/taosadapter/) (default port `6041`). It streams MQTT telemetry into TDengine and runs SQL from MQTT:

| Catalog connector event | Endpoint | Notes |
| - | - | - |
| POST SQL (INSERT, DDL) | `POST /rest/sql/{db}` | Raw SQL in the body (`text/plain`). Returns `{"code":0,"column_meta":…,"data":…,"rows":n}`. |
| POST SELECT (rows as objects) | `POST /rest/sql/{db}?row_with_meta=true` | Same SQL endpoint; each row comes back as a JSON object keyed by column name. |
| POST InfluxDB line write | `POST /influxdb/v1/write?db={db}&precision=ms` | Schemaless InfluxDB line protocol; super tables and columns auto-create. `204` on success. |
| POST OpenTSDB JSON write | `POST /opentsdb/v1/put/json/{db}` | Schemaless OpenTSDB JSON (`metric`, `timestamp`, `value`, `tags`). `204` on success. |
| GET ping | `GET /-/ping` | taosAdapter health, `200` (`503` when memory thresholds are exceeded). |

Default `BASE_ADDRESS` is `http://YOUR_TDENGINE_HOST:6041`. Replace `YOUR_DATABASE` in the endpoints with your database name; the database must already exist (create it once with `CREATE DATABASE IF NOT EXISTS …` through the SQL event). Topics use `data/tdengine/<object>/<verb>`.

> [!WARNING]
>
> **Check `code` in SQL responses.** By default taosAdapter answers `HTTP 200` even when a SQL statement or the login fails (`httpCodeServerError = false`). Success is `"code": 0`; anything else carries the error in `desc`, for example `{"code":855,"desc":"Authentication failure"}`. Schemaless writes do return `500` with a JSON error on failure.

## Auth

taosAdapter uses HTTP Basic authentication. The connector sets `WITH USERNAME` and `WITH PASSWORD GET SECRET "TDENGINE_PASSWORD"`, so store the database password as a Hub secret and never commit it. TDengine also accepts `Authorization: Taosd <token>` (token from `GET /rest/login/<user>/<password>`) and, on TDengine Cloud, a `?token=` query parameter. Change the default `root` / `taosdata` credentials on any real deployment.

## Basic Syntax

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
DEFINE ROUTE TdengineRestApi WITH TYPE REST_API
    ADD REST_API_CONFIG
        WITH BASE_ADDRESS "http://YOUR_TDENGINE_HOST:6041"
        WITH ENABLE_CLIENT "true"
        WITH USE_SSL "false"
        WITH REQUEST_TIMEOUT '60'
        WITH DEFAULT_CONTENT_TYPE "application/json"
        WITH USERNAME "root"
        WITH PASSWORD GET SECRET "TDENGINE_PASSWORD"
        # Smoke: GET /-/ping → 200; POST /rest/sql body "SELECT SERVER_VERSION()" → 200 {"code":0,...}.
    ADD EVENT Ping
        WITH SOURCE_TOPIC "data/tdengine/ping"
        WITH DESTINATION_TOPIC "data/tdengine/ping/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/-/ping"
    ADD EVENT ExecSql
        WITH SOURCE_TOPIC "data/tdengine/sql/exec"
        WITH DESTINATION_TOPIC "data/tdengine/sql/exec/response"
        WITH METHOD "POST"
        WITH ENDPOINT "/rest/sql/YOUR_DATABASE"
        WITH HEADERS
            ADD "Content-Type" "text/plain; charset=utf-8"
        WITH BODY "{payload}"
    ADD EVENT QueryRows
        WITH SOURCE_TOPIC "data/tdengine/query/rows"
        WITH DESTINATION_TOPIC "data/tdengine/query/rows/response"
        WITH METHOD "POST"
        WITH ENDPOINT "/rest/sql/YOUR_DATABASE?row_with_meta=true"
        WITH HEADERS
            ADD "Content-Type" "text/plain; charset=utf-8"
            ADD "Accept" "application/json"
        WITH BODY "{payload}"
    ADD EVENT WriteInfluxLine
        WITH SOURCE_TOPIC "data/tdengine/influx/write"
        WITH DESTINATION_TOPIC "data/tdengine/influx/write/response"
        WITH METHOD "POST"
        WITH ENDPOINT "/influxdb/v1/write?db=YOUR_DATABASE&precision=ms"
        WITH HEADERS
            ADD "Content-Type" "text/plain; charset=utf-8"
        WITH BODY "{payload}"
    ADD EVENT WriteOpenTsdbJson
        WITH SOURCE_TOPIC "data/tdengine/opentsdb/write"
        WITH DESTINATION_TOPIC "data/tdengine/opentsdb/write/response"
        WITH METHOD "POST"
        WITH ENDPOINT "/opentsdb/v1/put/json/YOUR_DATABASE"
        WITH HEADERS
            ADD "Content-Type" "application/json"
        WITH BODY "{payload}"
```

## Example MQTT payloads

**Create a super table and insert a row (topic `data/tdengine/sql/exec`).** The payload is raw SQL text:

```sql theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
CREATE STABLE IF NOT EXISTS factory_smoke (ts TIMESTAMP, temperature DOUBLE) TAGS (site BINARY(32))
```

```sql theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
INSERT INTO smoke_porto USING factory_smoke TAGS ('porto') VALUES (NOW, 21.5)
```

**Stream telemetry as line protocol (topic `data/tdengine/influx/write`):**

```text theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
factory_line,site=porto temperature=22.5 1791234567890
```

**Stream telemetry as OpenTSDB JSON (topic `data/tdengine/opentsdb/write`):**

```json theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{ "metric": "factory_otsdb", "timestamp": 1791234567890, "value": 23.5, "tags": { "site": "porto" } }
```

**Query rows (topic `data/tdengine/query/rows`):**

```sql theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
SELECT site, temperature FROM factory_smoke
```

The response topic receives `{"code":0,"column_meta":[…],"data":[{"site":"porto","temperature":21.5}],"rows":1}`.

> [!TIP]
>
> `value` is a reserved word in TDengine SQL. Name metric columns something like `temperature` or `val` when you create tables by hand. Schemaless OpenTSDB writes store the reading in a `_value` column.

## Testing

The factory smoke ran against a local TDengine OSS 3.3.8.4 (`taosd` plus `taosAdapter`): `GET /-/ping` returned 200, `CREATE STABLE` and `INSERT` through `/rest/sql/coreflux` returned 200 with `code 0`, InfluxDB line and OpenTSDB JSON writes returned 204, and all three rows came back through `/rest/sql/coreflux?row_with_meta=true` (200, `code 0`).

## Related

* [REST API Connectors](/latest/lot-language/routes/rest-api-routes)
* [REST API Apps](/latest/lot-language/routes/rest-api-apps/index)
* [InfluxDB](/latest/lot-language/routes/rest-api-apps/influxdb)
* [QuestDB](/latest/lot-language/routes/rest-api-apps/questdb)


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