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#
/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.
Sent as the Authorization header. Your key is used only by your browser for this request — it is never sent to Docsbook or stored.
The SQL statement to execute, for example SELECT 1 FORMAT JSON
Default database for this request
Output format when the SQL has no FORMAT clause, for example JSONEachRow
Your own id for the query, usable later with KILL QUERY and in system.query_log
Groups requests into a session so temporary tables and SET persist
Caps the number of rows returned
Query timeout in seconds
Set to 1 to allow a compressed response body
curl -H 'X-ClickHouse-User: default' \
-H 'X-ClickHouse-Key: YOUR_PASSWORD' \
'http://localhost:8123/?query=SELECT%201%20FORMAT%20JSON'{
"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.
Related#
- Integrations overview — native clients and connectors
- Insert data efficiently — batching rules that apply to HTTP inserts too
- Monitor a running server — find the queries your application sends