Skip to main content

HTTP Handler

The Databend HTTP Handler is a REST API that enables you to send SQL queries to Databend and receive results directly via HTTP requests. This is useful for building custom integrations, automation scripts, or when you need direct programmatic access without using a driver.

Recommended Alternatives

For most use cases, we recommend using:

The HTTP API is ideal for scenarios where you need lightweight HTTP-based integration or are building custom tooling.

Quick Start: Connecting to Databend​

Databend Cloud​

When you connect to Databend Cloud, you receive a DSN (Data Source Name) like this:

databend://user:password@tn3ftqihs.gw.aws-us-east-2.default.databend.com:443/default?warehouse=my-warehouse

To use the HTTP API, extract the components as follows:

DSN ComponentDescriptionHTTP API Usage
user:passwordYour credentialsBasic auth: -u "user:password"
tn3ftqihsYour tenant IDPart of the endpoint host
tn3ftqihs.gw...databend.comFull hostEndpoint: https://<host>/v1/query/
warehouse=my-warehouseWarehouse nameHeader: X-DATABEND-WAREHOUSE: my-warehouse
defaultDatabase nameIn request body: "session": {"database": "default"}

Complete example:

curl -u "user:password" \
--request POST \
'https://tn3ftqihs.gw.aws-us-east-2.default.databend.com/v1/query/' \
--header 'Content-Type: application/json' \
--header 'X-DATABEND-WAREHOUSE: my-warehouse' \
--data-raw '{"sql": "SELECT 1"}'

Self-Hosted Databend​

For self-hosted installations, the HTTP handler runs on port 8000 by default:

curl -u root: \
--request POST \
'http://localhost:8000/v1/query/' \
--header 'Content-Type: application/json' \
--data-raw '{"sql": "SELECT 1"}'

API Endpoints​

EndpointMethodDescription
/v1/queryPOSTExecute a SQL query
/v1/query/<query_id>GETGet query status and stats
/v1/query/<query_id>/page/<page_no>GETGet a specific page of results
/v1/query/<query_id>/killGETCancel a running query
/v1/query/<query_id>/finalGETGet final results and close query
/v1/upload_to_stagePUTUpload a file to a stage

Execute Query​

Execute a SQL statement and get results.

Endpoint: POST /v1/query

Request​

curl -u "user:password" \
--request POST \
'https://<endpoint>/v1/query/' \
--header 'Content-Type: application/json' \
--header 'X-DATABEND-WAREHOUSE: <warehouse>' \
--data-raw '{
"sql": "SELECT number, number * 2 AS double FROM numbers(5)",
"pagination": {
"wait_time_secs": 5
}
}'

Response​

{
"id": "b22c5bba-5e78-4e50-87b0-ec3855c757f5",
"session_id": "5643627c-a900-43ac-978f-8c76026d9944",
"session": {},
"schema": [
{"name": "number", "type": "UInt64"},
{"name": "double", "type": "UInt64"}
],
"data": [
["0", "0"],
["1", "2"],
["2", "4"],
["3", "6"],
["4", "8"]
],
"state": "Succeeded",
"error": null,
"stats": {
"scan_progress": {"rows": 5, "bytes": 40},
"write_progress": {"rows": 0, "bytes": 0},
"result_progress": {"rows": 5, "bytes": 80},
"running_time_ms": 12.443044
},
"stats_uri": "/v1/query/b22c5bba-5e78-4e50-87b0-ec3855c757f5",
"final_uri": "/v1/query/b22c5bba-5e78-4e50-87b0-ec3855c757f5/final",
"next_uri": null,
"kill_uri": "/v1/query/b22c5bba-5e78-4e50-87b0-ec3855c757f5/kill"
}

Request Parameters​

FieldTypeRequiredDefaultDescription
sqlstringYes-SQL statement to execute
session_idstringNo-Reuse an existing session
sessionobjectNo-Session configuration (see below)
paginationobjectNo-Pagination settings (see below)

Session Object:

FieldTypeDefaultDescription
databasestring"default"Current database
keep_server_session_secsint0Keep session alive for N seconds
settingsmapQuery settings (values as strings)

Pagination Object:

FieldTypeDefaultDescription
wait_time_secsint1Max seconds to wait for results

Response Fields​

FieldTypeDescription
idstringUnique query ID
session_idstringSession ID for reuse
statestringRunning, Succeeded, or Failed
schemaarrayColumn definitions
dataarrayResult rows as string arrays
errorobjectError details (null if successful)
statsobjectExecution statistics
next_uristringURL for next page (null if complete)
final_uristringURL to finalize and close query
kill_uristringURL to cancel the query

Get Query Status​

Get the current status and statistics of a query without fetching more data.

Endpoint: GET /v1/query/<query_id>

Request​

curl -u "user:password" \
'https://<endpoint>/v1/query/b22c5bba-5e78-4e50-87b0-ec3855c757f5' \
--header 'X-DATABEND-WAREHOUSE: <warehouse>'

Response​

{
"id": "b22c5bba-5e78-4e50-87b0-ec3855c757f5",
"session_id": "5643627c-a900-43ac-978f-8c76026d9944",
"session": {},
"schema": [],
"data": [],
"state": "Succeeded",
"error": null,
"stats": {
"scan_progress": {"rows": 5, "bytes": 40},
"write_progress": {"rows": 0, "bytes": 0},
"result_progress": {"rows": 5, "bytes": 80},
"running_time_ms": 12.443044
},
"next_uri": null
}

Get Next Page​

Fetch the next page of results for a running or completed query.

Endpoint: GET /v1/query/<query_id>/page/<page_no>

Request​

curl -u "user:password" \
'https://<endpoint>/v1/query/b22c5bba-5e78-4e50-87b0-ec3855c757f5/page/1' \
--header 'X-DATABEND-WAREHOUSE: <warehouse>'

Response​

{
"id": "b22c5bba-5e78-4e50-87b0-ec3855c757f5",
"session_id": "5643627c-a900-43ac-978f-8c76026d9944",
"schema": [
{"name": "number", "type": "UInt64"}
],
"data": [
["5"],
["6"],
["7"],
["8"],
["9"]
],
"state": "Succeeded",
"next_uri": "/v1/query/b22c5bba-5e78-4e50-87b0-ec3855c757f5/page/2"
}

Cancel Query​

Terminate a running query.

Endpoint: GET /v1/query/<query_id>/kill

Request​

curl -u "user:password" \
'https://<endpoint>/v1/query/b22c5bba-5e78-4e50-87b0-ec3855c757f5/kill' \
--header 'X-DATABEND-WAREHOUSE: <warehouse>'

Response​

Returns an empty body with status code 200 on success.


Finalize Query​

Close the query and release server resources. This also returns the final result page if any.

Endpoint: GET /v1/query/<query_id>/final

Request​

curl -u "user:password" \
'https://<endpoint>/v1/query/b22c5bba-5e78-4e50-87b0-ec3855c757f5/final' \
--header 'X-DATABEND-WAREHOUSE: <warehouse>'

Response​

{
"id": "b22c5bba-5e78-4e50-87b0-ec3855c757f5",
"state": "Succeeded",
"data": [],
"error": null,
"stats": {
"running_time_ms": 12.443044
}
}

Upload to Stage​

Upload a file to an internal or external stage.

Endpoint: PUT /v1/upload_to_stage

Request​

curl -u "user:password" \
-H "stage_name:my_stage" \
-F "upload=@./data.csv" \
-XPUT 'https://<endpoint>/v1/upload_to_stage'

Response​

{
"id": "bf44e659-7d2b-4c0f-ae09-693e77258183",
"stage_name": "my_stage",
"state": "SUCCESS",
"files": ["data.csv"]
}

Insert from Stage​

Insert data from a staged file into a table using stage attachment.

Endpoint: POST /v1/query

Request​

curl -u "user:password" \
--request POST \
'https://<endpoint>/v1/query/' \
--header 'Content-Type: application/json' \
--header 'X-DATABEND-WAREHOUSE: <warehouse>' \
--data-raw '{
"sql": "INSERT INTO my_table (id, name, value) VALUES",
"stage_attachment": {
"location": "@my_stage/data.csv",
"file_format_options": {
"type": "CSV",
"skip_header": "1"
},
"copy_options": {
"purge": "true"
}
}
}'

Response​

{
"id": "92182fc6-11b9-461b-8fbd-f82ecaa637ef",
"session_id": "f5caf18a-5dc8-422d-80b7-719a6da76039",
"schema": [],
"data": [],
"state": "Succeeded",
"error": null,
"stats": {
"scan_progress": {"rows": 100, "bytes": 2560},
"write_progress": {"rows": 100, "bytes": 2560},
"running_time_ms": 143.632441
}
}
tip

Use the same FILE_FORMAT and COPY_OPTIONS available in COPY INTO. Set purge: true to delete the source file after successful insert.


Session Examples​

Using Session Settings​

Request:

curl -u "user:password" \
--request POST \
'https://<endpoint>/v1/query/' \
--header 'Content-Type: application/json' \
--header 'X-DATABEND-WAREHOUSE: <warehouse>' \
--data-raw '{
"sql": "SELECT * FROM my_table",
"session": {
"database": "production",
"settings": {
"max_threads": "4",
"max_memory_usage": "10737418240"
}
}
}'

SET Statement​

Request:

{
"sql": "SET max_threads = 8",
"session": {
"database": "default",
"settings": {"max_threads": "4"}
}
}

Response:

{
"id": "abc123",
"state": "Succeeded",
"session": {
"database": "default",
"settings": {"max_threads": "8"}
},
"affect": {
"type": "ChangeSetting",
"key": "max_threads",
"value": "8",
"is_global": false
}
}

USE Statement​

Request:

{
"sql": "USE production",
"session": {
"database": "default"
}
}

Response:

{
"id": "abc123",
"state": "Succeeded",
"session": {
"database": "production"
},
"affect": {
"type": "UseDB",
"name": "production"
}
}

HTTP Status Codes​

CodeDescription
200Success (check error field for query-level errors)
400Invalid request format
404Query or page not found

Client Implementations​


Admin API: Procedure Management​

The following admin API endpoints are available for managing stored procedures. These endpoints are served on the admin API address (configured via admin_api_address) and require management mode.

List All Procedures​

GET /v1/tenants/<tenant>/procedures

Returns a JSON array of all procedures for the given tenant. The response format aligns with the SHOW PROCEDURES SQL command.

Response fields:

FieldDescription
nameThe procedure name
procedure_idThe unique procedure ID
argumentsThe procedure signature with return types
commentUser-provided comment
descriptionDescription (e.g., "user-defined procedure")
created_onCreation timestamp (UTC)

Get Procedure by ID​

GET /v1/tenants/<tenant>/procedures/<procedure_id>

Returns the details of a specific procedure by its numeric ID. Returns 404 if not found.

Get Procedure by Name​

GET /v1/tenants/<tenant>/procedures/<name>?args=<arg_types>

Returns the details of a procedure by name. The args query parameter is a comma-separated list of argument types (e.g., INT32,STRING). Omit args for procedures that take no arguments.

Response fields:

FieldDescription
signatureThe full procedure signature
returnsThe return type
languageThe procedure language (e.g., SQL)
bodyThe procedure body