Overview

HTTP interface

The server listens on port 8123 for HTTP. Port 8443 serves HTTPS, and is what ClickHouse Cloud uses.

Check that the server is up#

A GET / with no parameters returns Ok.:

curl 'http://localhost:8123/'
Ok.

For health-check scripts use /ping, and /replicas_status to check replica delay:

curl 'http://localhost:8123/ping'
Ok.

Try a query#

POST/

Send SQL to ClickHouse. Put the statement in the query parameter, or send it as the request body. GET requests are read-only, so any statement that writes data must use POST.

Authorization
Authorizationstring

Sent as the Authorization header. Your key is used only by your browser for this request — it is never sent to Docsbook or stored.

Body
querystringrequired

The SQL statement to execute, for example SELECT 1 FORMAT JSON

databasestring

Default database for this request

default_formatstring

Output format when the SQL has no FORMAT clause, for example JSONEachRow

query_idstring

Your own id for the query, usable later with KILL QUERY and in system.query_log

session_idstring

Groups requests into a session so temporary tables and SET persist

max_result_rowsnumber

Caps the number of rows returned

max_execution_timenumber

Query timeout in seconds

enable_http_compressionboolean

Set to 1 to allow a compressed response body

Example
curl -H 'X-ClickHouse-User: default' \
     -H 'X-ClickHouse-Key: YOUR_PASSWORD' \
     'http://localhost:8123/?query=SELECT%201%20FORMAT%20JSON'
Response
{
	"meta":
	[
		{
			"name": "1",
			"type": "UInt8"
		}
	],
 
	"data":
	[
		{
			"1": 1
		}
	],
 
	"rows": 1,
 
	"statistics":
	{
		"elapsed": 0.000596374,
		"rows_read": 1,
		"bytes_read": 1
	}
}

Three ways to send a query#

Put the statement in the URL, in the body, or split across both:

# 1. Query in the URL — note the URL encoding for the space
curl 'http://localhost:8123/?query=SELECT%201'
 
# 2. Query in the POST body — no length limit
echo 'SELECT 1' | curl 'http://localhost:8123/' --data-binary @-
 
# 3. Statement in the URL, data in the body — the form used for INSERT
echo -ne '10\n11\n12\n' | curl 'http://localhost:8123/?query=INSERT INTO t FORMAT TabSeparated' --data-binary @-

URLs are limited to 1 MiB by default, controlled by http_max_uri_size. Requests using GET are read-only, so send anything that modifies data with POST.

Authentication#

Three equivalent mechanisms:

# HTTP Basic authentication
echo 'SELECT 1' | curl 'http://user:password@localhost:8123/' -d @-
 
# URL parameters
echo 'SELECT 1' | curl 'http://localhost:8123/?user=user&password=password' -d @-
 
# Headers — preferred, keeps credentials out of URLs and access logs
echo 'SELECT 1' | curl -H 'X-ClickHouse-User: user' -H 'X-ClickHouse-Key: password' \
  'http://localhost:8123/' -d @-

Prefer the header form. Credentials in a URL end up in proxy logs and shell history.

Choose an output format#

Add a FORMAT clause to the SQL, or set default_format in the URL:

curl 'http://localhost:8123/?query=SELECT 1, 2, 3 FORMAT JSON'
curl 'http://localhost:8123/?default_format=JSONEachRow&query=SELECT 1, 2, 3'

The X-ClickHouse-Format header does the same as default_format. FORMAT JSON returns the envelope shown above; JSONEachRow emits one bare JSON object per line with no envelope, which suits streaming.

Bind parameters safely#

Do not build SQL by string concatenation. Declare parameters as {name:Type} and pass values as param_<name>:

curl 'http://localhost:8123/?param_id=42&query=SELECT * FROM t WHERE id = {id:UInt64}'
curl -X POST -F 'query=SELECT {p1:UInt8} + {p2:UInt8}' -F "param_p1=3" -F "param_p2=4" \
  'http://localhost:8123/'

Values passed this way are typed and escaped by the server, which closes off SQL injection.

Compression#

Request a compressed response when moving large result sets:

curl -H 'Accept-Encoding: gzip' \
  'http://localhost:8123/?enable_http_compression=1&query=SELECT number FROM numbers(10)' | gunzip -

decompress=1 accepts a compressed request body, and http_zlib_compression_level sets the response level.

Response headers worth reading#

Header Contents
X-ClickHouse-Query-Id The id of the executed query
X-ClickHouse-Summary JSON with read_rows, read_bytes, written_rows, result_rows
X-ClickHouse-Format The format used for the response
X-ClickHouse-Timezone Server timezone
X-ClickHouse-Exception-Code Server error code when a query fails

X-ClickHouse-Summary is the cheapest way to monitor how much data your application's queries actually read:

X-ClickHouse-Summary: {"read_rows":"1","read_bytes":"1","written_rows":"0","result_rows":"0","elapsed_ns":"4505959"}

Sessions#

Add a session_id parameter to keep temporary tables and SET values across requests. Any string works as the id, and session_timeout controls how long an idle session survives.

Any setting can be a URL parameter#

Beyond the documented parameters, any ClickHouse setting can be passed in the URL — max_memory_usage, max_threads, and the rest apply to that request only.

Errors#

A successful query returns 200 with the result in the body. A failure returns 500 with the error description in the body. When an error occurs after data has already been streamed, the response ends with the exception text appended to the partial result — check X-ClickHouse-Exception-Code rather than trusting a 200 with a truncated body.

The built-in web UI#

ClickHouse ships a query interface at http://localhost:8123/play, with progress display, query cancellation, result streaming, and result download in CSV, TSV, JSON, JSONLines, Parquet, or Markdown. Self-managed HTTPS deployments serve it at https://your-host:8443/play.

Updated

Was this page helpful?