Skip to main content

Query Endpoints

For Data Analysts

The query endpoints allow you to execute semantic queries against your Olytix Core project.

POST /api/v1/query

Execute a semantic query.

Request

curl -X POST http://localhost:8000/api/v1/query \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": ["orders.total_revenue", "orders.count"],
"dimensions": ["orders.region", "orders.order_date.month"],
"filters": [
{
"dimension": "orders.order_date.year",
"operator": "equals",
"value": 2024
},
{
"dimension": "orders.status",
"operator": "notEquals",
"value": "cancelled"
}
],
"order_by": [
{"field": "orders.total_revenue", "direction": "desc"}
],
"limit": 100,
"offset": 0
}'

Request Body

FieldTypeRequiredDescription
metricsstring[]YesList of metrics to query
dimensionsstring[]NoDimensions to group by
filtersFilter[]NoFilters to apply
order_byOrderBy[]NoSort order
limitnumberNoMax rows (default: 1000)
offsetnumberNoPagination offset
time_rangeTimeRangeNoTime range filter

Filter Object

FieldTypeDescription
dimensionstringDimension to filter
operatorstringFilter operator
valueanyFilter value

Filter Operators

OperatorDescriptionExample Value
equalsExact match"completed"
notEqualsNot equal"cancelled"
containsString contains"ship"
startsWithStarts with"US-"
endsWithEnds with"-2024"
gtGreater than100
gteGreater than or equal100
ltLess than1000
lteLess than or equal1000
betweenRange (inclusive)[10, 100]
inListIn array["A", "B", "C"]
notInListNot in array["X", "Y"]
setIs not null(no value)
notSetIs null(no value)

Response

{
"data": [
{
"orders.region": "NORTH",
"orders.order_date.month": "2024-01",
"orders.total_revenue": 125000.00,
"orders.count": 1523
},
{
"orders.region": "NORTH",
"orders.order_date.month": "2024-02",
"orders.total_revenue": 142000.00,
"orders.count": 1687
}
],
"query": {
"sql": "SELECT region, DATE_TRUNC('month', order_date), SUM(amount), COUNT(*) FROM ...",
"duration_ms": 45
},
"meta": {
"total_rows": 48,
"returned_rows": 48,
"cached": false,
"cache_key": "abc123"
}
}

POST /api/v1/query/sql

Get the generated SQL without executing.

Request

curl -X POST http://localhost:8000/api/v1/query/sql \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": ["orders.total_revenue"],
"dimensions": ["orders.region"]
}'

Response

{
"sql": "SELECT\n UPPER(region) AS \"orders.region\",\n SUM(total_amount) AS \"orders.total_revenue\"\nFROM fct_orders\nGROUP BY UPPER(region)"
}

POST /api/v1/query/async

Start an asynchronous query for large datasets.

Request

curl -X POST http://localhost:8000/api/v1/query/async \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"metrics": ["orders.total_revenue"],
"dimensions": ["orders.customer_id"],
"limit": 1000000
}'

Response

{
"job_id": "job_abc123",
"status": "pending",
"created_at": "2024-01-20T10:30:00Z",
"poll_url": "/api/v1/query/async/job_abc123"
}

GET /api/v1/query/async/{job_id}

Check async query status.

Response (In Progress)

{
"job_id": "job_abc123",
"status": "running",
"progress": 45,
"started_at": "2024-01-20T10:30:01Z"
}

Response (Complete)

{
"job_id": "job_abc123",
"status": "complete",
"completed_at": "2024-01-20T10:30:45Z",
"result_url": "/api/v1/query/async/job_abc123/result",
"row_count": 500000
}

GET /api/v1/query/async/{job_id}/result

Get async query results.

Response

{
"data": [...],
"meta": {
"total_rows": 500000
}
}

Error Responses

400 Bad Request

{
"error": {
"code": "INVALID_QUERY",
"message": "Metric 'invalid_metric' not found",
"details": {
"available_metrics": ["orders.total_revenue", "orders.count"]
}
}
}

408 Request Timeout

{
"error": {
"code": "QUERY_TIMEOUT",
"message": "Query exceeded 30 second timeout",
"suggestion": "Use async query endpoint for large datasets"
}
}

Next Steps