Berserk Docs

Query HTTP API

REST endpoints for query execution, database/table discovery, and Grafana compatibility

The query service exposes an HTTP API on port 9510 (configurable via QUERY_BIND).

Execute Query

Execute a KQL query and return results as JSON tables.

EndpointPOST /query
Content-Typeapplication/json

Request

FieldTypeRequiredDescription
querystringyesKQL query to execute
databaseobjectyesTarget database. Exactly one of {"id": "<uuid>"} or {"name": "<db>"}. Mirrors the gRPC berserk.DatabaseRef oneof.
sincestringnoStart of time range (alias: from). ISO 8601 or relative expression like 1h
untilstringnoEnd of time range (alias: to). ISO 8601 or relative expression
timezonestringnoTimezone for relative expressions (default: UTC)
curl -X POST http://localhost:9510/query \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "my_table | take 10",
    "database": {"name": "default"},
    "since": "1h"
  }'

Response

{
  "Tables": [
    {
      "name": "PrimaryResult",
      "columns": [
        { "column_name": "timestamp", "column_type": "datetime" },
        { "column_name": "message", "column_type": "string" }
      ],
      "rows": [
        ["2026-03-12T10:00:00Z", "hello world"]
      ]
    },
    {
      "name": "@Warnings",
      "columns": [...],
      "rows": []
    }
  ]
}

The response always includes:

  • PrimaryResult — the query result table
  • @Warnings — execution warnings (empty if none)
  • @ExtendedProperties — visualization metadata (only present when the query uses render)

Query Plan

Return the logical plan for a query without executing it (s-expression format).

EndpointPOST /plan
Content-Typeapplication/json

Request

Same request body as /query.

curl -X POST http://localhost:9510/plan \
  -H 'Content-Type: application/json' \
  -d '{"query": "my_table | count"}'

Response

{
  "plan_sexp": "(count (scan \"my_table\"))"
}

Databases

List every database the query service can see, with each database's tables nested. A single round-trip surfaces everything the UI needs to populate database/table pickers and feed the editor's LSP with table-name completions.

EndpointGET /v1/databases
curl http://localhost:9510/v1/databases

Response

{
  "databases": [
    {
      "id": "0190ed30-0000-7000-8000-000000000000",
      "name": "default",
      "tables": [
        {
          "id": "0199ad12-7000-7000-8000-000000000000",
          "name": "my_table",
          "kind": "table",
          "schema": [
            { "name": "timestamp", "data_type": "datetime" },
            { "name": "message", "data_type": "string" }
          ]
        }
      ]
    }
  ]
}

The schema returned for each table is the standard segment schema ($raw, timestamp, ingest_time, start_time, end_time). Per-row dynamic attributes inside $raw are discovered via the fieldstats operator at query time, not via this endpoint.

Kusto REST Endpoint

Grafana-compatible endpoint that accepts the Kusto query format.

EndpointPOST /v1/rest/query
Content-Typeapplication/json

Request

FieldTypeRequiredDescription
cslstringyesKQL query string
curl -X POST http://localhost:9510/v1/rest/query \
  -H 'Content-Type: application/json' \
  -d '{"csl": "my_table | take 10"}'

Response

Returns tables in Microsoft Kusto format with TableName, Columns (with ColumnName, DataType, ColumnType), and Rows.

Timeline Query

Transform a query into a timeline aggregation query that groups events by severity over time.

EndpointPOST /timeline-query
Content-Typeapplication/json

Request

FieldTypeRequiredDescription
querystringyesOriginal KQL query to transform

Error Handling

All endpoints return errors in RFC 7807 problem details format:

{
  "type": "https://api.bzrk.dev/problems/query-error",
  "message": "Unknown table 'foo'",
  "code": "UnknownTable",
  "error_details": {}
}
Status CodeMeaning
200Success
400Query syntax or analysis error
500Internal server error

On this page