Query the API
The Semantic Query object — metrics, dimensions, filters, grain — the response shape, the stable error codes, and the discovery endpoints.
Updated
Every consumer — REST, MCP, the console — sends the same object: a Semantic Query. It references one model and some combination of metrics/measures, dimensions, filters, ordering, and a row limit. Never SQL, never a raw table or column name.
Authenticate
Authorization: Bearer <your-api-key>
The token carries workspace identity and mode (governed or explore) only.
The warehouse a query reaches, its row-level security, and its cost limits are
all resolved server-side.
Run a query
curl "$ENGINE/v1/query" \
-H "Authorization: Bearer $DATAHASHI_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": ["avg_order_value"],
"dimensions": ["Customer.region"],
"filters": [{ "dimension": "Order.status", "op": "eq", "value": "completed" }],
"order": ["Customer.region"],
"limit": 100
}'
Request fields
| Field | Notes |
|---|---|
model | Optional; the workspace’s default model if omitted |
metrics | Governed selections; available in both modes |
measures | Raw selections; explore mode only |
dimensions | Group-by, with optional grain on a time dimension |
filters | { dimension, op, value } — eq, ne, lt, le, gt, ge, in, not_in, contains, starts_with, ends_with, is_null |
segments | Named filter fragments, ANDed with filters |
view | Optional scoping to a curated model view |
order | Sort spec over the output columns |
limit | Row cap; also bounded by the workspace cost policy |
Response shape
{
"columns": ["region", "avg_order_value"],
"annotation": [
{ "name": "region", "kind": "dimension", "type": "string" },
{ "name": "avg_order_value", "kind": "metric", "type": "number" }
],
"rows": [
["na", 142.50],
["emea", 138.10]
]
}
Dimensions come first, then metrics and measures. An empty result serializes as
"rows": [], not null.
Errors
Errors are { "error": { "code", "message" } } with a stable code:
| HTTP | Code | When |
|---|---|---|
| 400 | bad_request | invalid grain, filter operator, type mismatch, ambiguity, oversized body |
| 401 | unauthenticated | missing or invalid bearer token |
| 403 | forbidden | a governed token referenced raw measures |
| 404 | not_found | unknown metric, measure, dimension, or model |
| 429 | over_budget | the query exceeds the workspace cost policy |
| 503 | overloaded | engine capacity exceeded |
| 500 | internal | an unexpected server error |
Discovery
Three endpoints let a consumer learn the vocabulary before it queries:
GET /v1/models— the workspace’s semantic model namesGET /v1/catalog?model=— metrics, dimensions, and curated views (plus raw measures in explore mode)GET /v1/describe?model=&name=— the definition and grain of one metric, dimension, or measure
All three take the same bearer token, and all three are also exposed as MCP tools.
Metering
Every query records what it scanned against the principal that asked.
GET /v1/tenants/{id}/usage/summary?from=… returns the total over any window —
one number, no per-warehouse billing archaeology.