---
title: REST API
description: This document describes the TDengine REST API.
---

To support the development of various types of applications and platforms, TDengine provides an API that conforms to REST principles; namely REST API. To minimize the learning cost, unlike REST APIs for other database engines, TDengine allows insertion of SQL commands in the BODY of an HTTP POST request, to operate the database. 

:::note
One difference from the native connection is that the REST interface is stateless and so the `USE db_name` command has no effect. All references to table names and super table names need to specify the database name in the prefix. TDengine supports specification of the db_name in RESTful URL. If the database name prefix is not specified in the SQL command, the `db_name` specified in the URL will be used.
:::

## Installation

The REST interface does not rely on any TDengine native library, so the client application does not need to install any TDengine libraries. The client application's development language only needs to support the HTTP protocol. The REST interface is provided by [taosAdapter](../taosadapter), to use REST interface you need to make sure `taosAdapter` is running properly.

## Verification

If the TDengine server is already installed, it can be verified as follows:

The following example is in an Ubuntu environment and uses the `curl` tool to verify that the REST interface is working. Note that the `curl` tool may need to be installed in your environment.

The following example lists all databases on the host h1.tdengine.com. To use it in your environment, replace `h1.tdengine.com` and `6041` (the default port) with the actual running TDengine service FQDN and port number.

```bash
curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" \
  -d "select name, ntables, status from information_schema.ins_databases;" \
  h1.tdengine.com:6041/rest/sql
```

The following return value results indicate that the verification passed.

```json
{
    "code": 0,
    "column_meta": [
        [
            "name",
            "VARCHAR",
            64
        ],
        [
            "ntables",
            "BIGINT",
            8
        ],
        [
            "status",
            "VARCHAR",
            10
        ]
    ],
    "data": [
        [
            "information_schema",
            16,
            "ready"
        ],
        [
            "performance_schema",
            9,
            "ready"
        ]
    ],
    "rows": 2
}
```

## HTTP request URL format

```text
http://<fqdn>:<port>/rest/sql/[db_name][?tz=timezone[&req_id=req_id][&row_with_meta=true]]
```

Parameter Description:

- fqnd: FQDN or IP address of any host in the cluster.
- port: httpPort configuration item in the configuration file, default is 6041.
- db_name: Optional parameter that specifies the default database name for the executed SQL command.
- tz: Optional parameter that specifies the timezone of the returned time, following the IANA Time Zone rules, e.g. `America/New_York`.
- req_id: Optional parameter that specifies the request id for tracing.
- row_with_meta: Optional parameter that specifies whether each row of data carries the column name. The default value is `false`.(Supported starting from version 3.3.2.0)

:::note

URL Encoding. Make sure that parameters are properly encoded. For example, when specifying a timezone you must properly encode special characters. ?tz=Etc/GMT+10 will not work because the + plus symbol is recognized as a space in the url. It's best practice to encode all special characters in a parameter. Instead use ?tz=Etc%2FGMT%2B10 for the parameter.

:::

For example, `http://h1.taos.com:6041/rest/sql/test` is a URL to `h1.taos.com:6041` and sets the default database name to `test`.

TDengine supports both Basic authentication and custom authentication mechanisms, and subsequent versions will provide a standard secure digital signature mechanism for authentication.

- authentication information is shown below:

  ```text
  Authorization: Taosd <TOKEN>
  ```

- Basic authentication information is shown below:

  ```text
  Authorization: Basic <TOKEN>
  ```

The HTTP request's BODY is a complete SQL command, and the data table in the SQL statement should be provided with a database prefix, e.g., `db_name.tb_name`. If the table name does not have a database prefix and the database name is not specified in the URL, the system will response an error because the HTTP module is a simple forwarder and has no awareness of the current DB.

Use `curl` to initiate an HTTP request with a custom authentication method, with the following syntax.

```bash
curl -L -H "Authorization: Basic <TOKEN>" -d "<SQL>" <ip>:<PORT>/rest/sql/[db_name][?tz=timezone[&req_id=req_id]]
```

or

```bash
curl -L -u username:password -d "<SQL>" <ip>:<PORT>/rest/sql/[db_name][?tz=timezone[&req_id=req_id]]
```

where `TOKEN` is the string after Base64 encoding of `{username}:{password}`, e.g. `root:taosdata` is encoded as `cm9vdDp0YW9zZGF0YQ==`..

## HTTP Return Format

### HTTP Response Code

Starting from `TDengine 3.0.3.0`, `taosAdapter` provides a configuration parameter `httpCodeServerError` to set whether to return a non-200 http status code when the C interface returns an error

| **Description** | **httpCodeServerError false** | **httpCodeServerError true** |
|--------------------|---------------------------- ------|---------------------------------------|
| taos_errno() returns 0 | 200 | 200 |
| taos_errno() returns non-0 | 200 (except authentication error) | 500 (except authentication error and 400/502 error) |
| Parameter error | 400 (only handle HTTP request URL parameter error) | 400 (handle HTTP request URL parameter error and taosd return error) |
| Authentication error | 401 | 401 |
| Interface does not exist | 404 | 404 |
| Cluster unavailable error | 502 | 502 |
| Insufficient system resources | 503 | 503 |

The C error codes that return http code 400 are:

- TSDB_CODE_TSC_SQL_SYNTAX_ERROR ( 0x0216 )
- TSDB_CODE_TSC_LINE_SYNTAX_ERROR (0x021B)
- TSDB_CODE_PAR_SYNTAX_ERROR (0x2600)
- TSDB_CODE_TDB_TIMESTAMP_OUT_OF_RANGE (0x060B)
- TSDB_CODE_TSC_VALUE_OUT_OF_RANGE (0x0224)
- TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE (0x263B)

The error code that returns http code 401 are:

- TSDB_CODE_MND_USER_ALREADY_EXIST (0x0350)
- TSDB_CODE_MND_USER_NOT_EXIST (0x0351)
- TSDB_CODE_MND_INVALID_USER_FORMAT (0x0352)
- TSDB_CODE_MND_INVALID_PASS_FORMAT (0x0353)
- TSDB_CODE_MND_NO_USER_FROM_CONN (0x0354)
- TSDB_CODE_MND_TOO_MANY_USERS (0x0355)
- TSDB_CODE_MND_INVALID_ALTER_OPER (0x0356)
- TSDB_CODE_MND_AUTH_FAILURE (0x0357)

The error code that returns http code 403 are:

- TSDB_CODE_RPC_SOMENODE_NOT_CONNECTED (0x0020)

### HTTP body structure

#### Successful Insert Operation

Example:

```json
{
  "code": 0,
  "column_meta": [["affected_rows", "INT", 4]],
  "data": [[0]],
  "rows": 1
}
```

Description:

- code: (`int`) 0 indicates success.
- column_meta: (`[1][3]any`) Only returns `[["affected_rows", "INT", 4]]`.
- rows: (`int`) Only returns `1`.
- data: (`[][]any`) Returns the number of rows affected.

#### Successful Query Operation

Example:

```json
{
  "code": 0,
  "column_meta": [
    ["ts", "TIMESTAMP", 8],
    ["count", "BIGINT", 8],
    ["endpoint", "VARCHAR", 45],
    ["status_code", "INT", 4],
    ["client_ip", "VARCHAR", 40],
    ["request_method", "VARCHAR", 15],
    ["request_uri", "VARCHAR", 128]
  ],
  "data": [
    [
      "2022-06-29T05:50:55.401Z",
      2,
      "LAPTOP-NNKFTLTG:6041",
      200,
      "172.23.208.1",
      "POST",
      "/rest/sql"
    ],
    [
      "2022-06-29T05:52:16.603Z",
      1,
      "LAPTOP-NNKFTLTG:6041",
      200,
      "172.23.208.1",
      "POST",
      "/rest/sql"
    ],
    [
      "2022-06-29T06:28:14.118Z",
      1,
      "LAPTOP-NNKFTLTG:6041",
      200,
      "172.23.208.1",
      "POST",
      "/rest/sql"
    ],
    [
      "2022-06-29T05:52:16.603Z",
      2,
      "LAPTOP-NNKFTLTG:6041",
      401,
      "172.23.208.1",
      "POST",
      "/rest/sql"
    ]
  ],
  "rows": 4
}
```

Description:

- code: `int` 0 indicates success.
- column_meta: (`[][3]any`) Column information. Each column is described with three values: column name (string), column type (string), and type length (int).
- rows: (`int`) The number of rows returned.
- data: (`[][]any`)

The following types may be returned:

- "NULL"
- "BOOL"
- "TINYINT"
- "SMALLINT"
- "INT"
- "BIGINT"
- "FLOAT"
- "DOUBLE"
- "VARCHAR"
- "TIMESTAMP"
- "NCHAR"
- "TINYINT UNSIGNED"
- "SMALLINT UNSIGNED"
- "INT UNSIGNED"
- "BIGINT UNSIGNED"
- "JSON"
- "VARBINARY"
- "GEOMETRY"

`VARBINARY` and `GEOMETRY` types return data as Hex string, example:

Prepare data

```bash
create database demo
use demo
create table t(ts timestamp,c1 varbinary(20),c2 geometry(100))
insert into t values(now,'\x7f8290','point(100 100)')
```

Execute query

```bash
curl --location 'http://<fqdn>:<port>/rest/sql' \
--header 'Content-Type: text/plain' \
--header 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' \
--data 'select * from demo.t'
```

Return results

```json
{
     "code": 0,
     "column_meta": [
         [
             "ts",
             "TIMESTAMP",
             8
         ],
         [
             "c1",
             "VARBINARY",
             20
         ],
         [
             "c2",
             "GEOMETRY",
             100
         ]
     ],
     "data": [
         [
             "2023-11-01T06:28:15.210Z",
             "7f8290",
             "010100000000000000000059400000000000005940"
         ]
     ],
     "rows": 1
}
```

- `010100000000000000000059400000000000005940` is [Well-Known Binary (WKB)](https://libgeos.org/specifications/wkb/) format for `point(100 100)`

#### Errors

Example:

```json
{
  "code": 9728,
  "desc": "syntax error near \"1\""
}
```

Description:

- code: (`int`) Error code.
- desc: (`string`): Error code description.

#### Return key-value pair

When the parameter `row_with_meta=true` is specified, the data returned in `data` field will change from array format to object format, where the key of the object is the column name and the value is the data.

insert response example:

```json
{
    "code": 0,
    "column_meta": [
        [
            "affected_rows",
            "INT",
            4
        ]
    ],
    "data": [
        {
            "affected_rows": 1
        }
    ],
    "rows": 1
}
```

query response example:

```json
{
    "code": 0,
    "column_meta": [
        [
            "ts",
            "TIMESTAMP",
            8
        ],
        [
            "current",
            "FLOAT",
            4
        ],
        [
            "voltage",
            "INT",
            4
        ],
        [
            "phase",
            "FLOAT",
            4
        ],
        [
            "groupid",
            "INT",
            4
        ],
        [
            "location",
            "VARCHAR",
            24
        ]
    ],
    "data": [
        {
            "ts": "2017-07-14T02:40:00.000Z",
            "current": -2.498076,
            "voltage": 0,
            "phase": -0.846025,
            "groupid": 8,
            "location": "California.Sunnyvale"
        }
    ],
    "rows": 1
}
```

## Custom Authorization Code

HTTP requests require an authorization code `<TOKEN>` for identification purposes. The administrator usually provides the authorization code, and it can be obtained simply by sending an ``HTTP GET`` request as follows:

```bash
curl http://<fqnd>:<port>/rest/login/<username>/<password>
```

Where `fqdn` is the FQDN or IP address of the TDengine database. `port` is the port number of the TDengine service. `username` is the database username. `password` is the database password. The return value is in `JSON` format, and the meaning of each field is as follows.

- status: flag bit of the request result.
- code: return value code.
- desc: authorization code.

Example of getting authorization code.

```bash
curl http://192.168.0.1:6041/rest/login/root/taosdata
```

Response body:

```json
{
  "code": 0,
  "desc": "/KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04"
}
```

## Usage examples

- query all records from table d1001 of database demo

  ```bash
  curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "select * from demo.d1001" 192.168.0.1:6041/rest/sql
  ```

  Response body:

  ```json
  {
      "code": 0,
      "column_meta": [
          [
              "ts",
              "TIMESTAMP",
              8
          ],
          [
              "current",
              "FLOAT",
              4
          ],
          [
              "voltage",
              "INT",
              4
          ],
          [
              "phase",
              "FLOAT",
              4
          ]
      ],
      "data": [
          [
              "2022-07-30T06:44:40.32Z",
              10.3,
              219,
              0.31
          ],
          [
              "2022-07-30T06:44:41.32Z",
              12.6,
              218,
              0.33
          ]
      ],
      "rows": 2
  }
  ```

- Create database demo:

  ```bash
  curl -L -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -d "create database demo" 192.168.0.1:6041/rest/sql
  ```

  Response body:

  ```json
  {
      "code": 0,
      "column_meta": [
          [
              "affected_rows",
              "INT",
              4
          ]
      ],
      "data": [
          [
              0
          ]
      ],
      "rows": 1
  }
  ```

## REST API between TDengine 2.x and 3.0

### URI

| URI                  | TDengine 2.x         | TDengine 3.0                                         |
| :--------------------| :------------------: | :--------------------------------------------------: |
| /rest/sql            | Supported            | Supported (with different response code and body)    |
| /rest/sqlt           | Supported            | No more supported                                    |
| /rest/sqlutc         | Supported            | No more supported                                    |

### HTTP code

| HTTP code            | TDengine 2.x         | TDengine 3.0 | note                                  |
| :--------------------| :------------------: | :----------: | :-----------------------------------: |
| 200                  | Supported            | Supported    | Success or taosc return error         |
| 400                  | Not supported        | Supported    | Parameter error                       |
| 401                  | Not supported        | Supported    | Authentication failure                |
| 404                  | Supported            | Supported    | URI not exist                         |
| 500                  | Not supported        | Supported    | Internal error                        |
| 503                  | Supported            | Supported    | Insufficient system resources         |

### Response body

#### REST response body return from TDengine 2.x

```JSON
{
  "status": "succ",
  "head": [
    "name",
    "created_time",
    "ntables",
    "vgroups",
    "replica",
    "quorum",
    "days",
    "keep1,keep2,keep(D)",
    "cache(MB)",
    "blocks",
    "minrows",
    "maxrows",
    "wallevel",
    "fsync",
    "comp",
    "precision",
    "status"
  ],
  "data": [
    [
      "log",
      "2020-09-02 17:23:00.039",
      4,
      1,
      1,
      1,
      10,
      "30,30,30",
      1,
      3,
      100,
      4096,
      1,
      3000,
      2,
      "us",
      "ready"
    ]
  ],
  "rows": 1
}
```
```
  "data": [
        [
            "information_schema",
            16,
            "ready"
        ],
        [
            "performance_schema",
            9,
            "ready"
        ]
    ],
```

#### REST response body return from TDengine 3.0

```JSON
{
    "code": 0,
    "column_meta": [
        [
            "name",
            "VARCHAR",
            64
        ],
        [
            "ntables",
            "BIGINT",
            8
        ],
        [
            "status",
            "VARCHAR",
            10
        ]
    ],
    "data": [
        [
            "information_schema",
            16,
            "ready"
        ],
        [
            "performance_schema",
            9,
            "ready"
        ]
    ],
    "rows": 2
}
```

## Reference

[taosAdapter](../taosadapter/)
