Skip to content

Query API

POST /api/v1/dsl is the only way to query Hexcovery programmatically. You send an OQL statement; the server translates it to ClickHouse SQL with your tenant_id and the platform query limits baked in, runs it, and returns columns + rows as JSON. There is no raw-SQL endpoint — OQL is the whole query surface.

Request

POST /api/v1/dsl
X-API-Key: <key>
Content-Type: application/json

Body:

{
  "query": "SELECT avg(cpu_user_pct) FROM host WHERE host = 'server1' EVERY 1m LAST 1h"
}

The single field is query, a string of OQL. Every query must scope a time window (LAST, BETWEEN, …); the tenant filter is added for you and cannot be removed or widened. See OQL and the syntax reference for the grammar.

Response

A JSON object describing the result shape so a client can render it without guessing:

{
  "output_type": "timeseries",
  "columns": ["t", "avg_cpu_user_pct"],
  "rows": [
    ["2026-06-21T10:00:00Z", 12.4],
    ["2026-06-21T10:01:00Z", 13.1]
  ]
}
Field Type Meaning
output_type string The query's natural shape: timeseries, table, single_value, or bar
columns array of strings Column names, in order
rows array of arrays Each row is an array of values aligned to columns

output_type mirrors how the dashboard auto-picks a visualization, and is a hint you can ignore — columns + rows are the data. Cell values are JSON scalars (string, number, boolean, or null); timestamps are ISO-8601 strings.

Example

curl -X POST https://server/api/v1/dsl \
  -H "X-API-Key: $HEXCOVERY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query":"SELECT avg(cpu_user_pct) FROM host LAST 1h"}'

A single-aggregation query like this returns output_type: "single_value" with one row and one column:

{
  "output_type": "single_value",
  "columns": ["avg_cpu_user_pct"],
  "rows": [[14.7]]
}

Limits and errors

Queries run under per-tenant guardrails — maximum rows, maximum bytes scanned, maximum execution time, and a per-tenant request-rate limit. A query that exceeds a limit or fails to parse returns a non-2xx status with a JSON error body describing the problem; fix the query (narrow the time range, add filters, raise the bucket interval) and retry.