Skip to main content

Query API

Soltix supports both GET and POST query endpoints. POST is recommended for complex queries with many device IDs or when you prefer JSON bodies over URL parameters.

Endpoints

GET  /v1/databases/:database/collections/:collection/query
POST /v1/databases/:database/collections/:collection/query

Query Parameters

GET — URL Parameters

ParameterTypeRequiredDefaultDescription
start_timestringYesStart of time range (RFC 3339)
end_timestringYesEnd of time range (RFC 3339)
idsstringYesComma-separated device IDs
fieldsstringNoall fieldsComma-separated field names to return
limitintNo0 (no limit)Max data points per device
intervalstringNoAggregation interval: 1m, 5m, 1h, 1d, 1mo, 1y
aggregationstringNosumAggregation function (used with interval)
downsamplingstringNononeDownsampling algorithm
downsampling_thresholdintNo0 (auto)Target point count for downsampling
anomaly_detectionstringNononeAnomaly detection algorithm
anomaly_thresholdfloatNo3.0Sensitivity threshold
anomaly_fieldstringNoall fieldsSpecific field to check for anomalies

POST — JSON Body

{
"start_time": "2026-01-01T00:00:00Z",
"end_time": "2026-01-02T00:00:00Z",
"ids": ["sensor-001", "sensor-002"],
"fields": ["temperature", "humidity"],
"limit": 1000,
"interval": "1h",
"aggregation": "avg",
"downsampling": "lttb",
"downsampling_threshold": 500,
"anomaly_detection": "zscore",
"anomaly_threshold": 2.5,
"anomaly_field": "temperature"
}

Same parameters as GET. ids is an array of strings instead of comma-separated.

Response Format

200 OK

{
"database": "mydb",
"collection": "sensors",
"start_time": "2026-01-01T00:00:00Z",
"end_time": "2026-01-02T00:00:00Z",
"results": [
{
"id": "sensor-001",
"times": [
"2026-01-01T00:00:00Z",
"2026-01-01T01:00:00Z",
"2026-01-01T02:00:00Z"
],
"temperature": [25.5, 26.0, 25.8],
"humidity": [60.2, 61.0, 59.5]
},
{
"id": "sensor-002",
"times": [
"2026-01-01T00:00:00Z",
"2026-01-01T01:00:00Z"
],
"temperature": [22.1, 22.3],
"humidity": [55.0, 54.8]
}
]
}

Results use a columnar format: each device has a times array and parallel arrays for each field. This is more compact than row-based format for time-series data.

Aggregation

When interval is specified, raw data is aggregated into time buckets.

Supported Intervals

IntervalDescriptionMax Time Range
1m1 minute7 days
5m5 minutes7 days
1h1 hour7 days
1d1 day90 days
1mo1 month3 years
1y1 yearNo limit

Supported Functions

FunctionDescription
sumSum of values in each bucket (default)
avgAverage of values
minMinimum value
maxMaximum value
countNumber of data points

Example — Hourly Average

GET /v1/databases/mydb/collections/sensors/query
?start_time=2026-01-01T00:00:00Z
&end_time=2026-01-02T00:00:00Z
&ids=sensor-001
&interval=1h
&aggregation=avg

Downsampling

Reduces the number of data points while preserving the visual shape of the data. Applied after aggregation (if any).

AlgorithmDescription
noneNo downsampling (default)
autoAutomatically selects the best algorithm based on data characteristics
lttbLargest Triangle Three Buckets — best for visual fidelity
minmaxPreserves min and max values per bucket
avgAverage downsampling
m4Min, Max, First, Last per bucket — good for OHLC-style data

Use downsampling_threshold to control the target number of output points. When set to 0, the system determines an appropriate threshold automatically.

Anomaly Detection

Inline anomaly detection can be enabled on any query. Anomalies are returned in a separate anomalies array alongside the results.

AlgorithmDescription
noneDisabled (default)
zscoreZ-Score — flags values beyond N standard deviations
iqrInterquartile Range — flags values outside Q1 - 1.5×IQR to Q3 + 1.5×IQR
moving_avgMoving Average — flags values deviating from a rolling window
autoAutomatically selects the best algorithm based on data distribution

anomaly_threshold controls sensitivity (default: 3.0). Lower values detect more anomalies.

Response with Anomalies

When anomalies are detected, an anomalies array is included in the response:

{
"database": "mydb",
"collection": "sensors",
"start_time": "2026-01-01T00:00:00Z",
"end_time": "2026-01-02T00:00:00Z",
"results": [
{
"id": "sensor-001",
"times": ["2026-01-01T00:00:00Z", "2026-01-01T01:00:00Z", "2026-01-01T02:00:00Z"],
"temperature": [25.5, 26.0, 99.5]
}
],
"anomalies": [
{
"time": "2026-01-01T02:00:00Z",
"device_id": "sensor-001",
"field": "temperature",
"value": 99.5,
"expected": {"min": 20.0, "max": 30.0},
"score": 4.2,
"type": "high",
"algorithm": "zscore"
}
]
}

Post-Processing Pipeline

When multiple features are enabled on a single query, they are applied in this order:

  1. Anomaly detection — runs on the full dataset first
  2. Downsampling — reduces point count
  3. Timezone conversion — adjusts timestamps

Validation Rules

RuleHTTP StatusError Code
Missing ids400INVALID_REQUEST
Missing start_time or end_time400INVALID_REQUEST
Invalid RFC 3339 timestamp400INVALID_REQUEST
end_time before start_time400INVALID_REQUEST
Invalid interval value400INVALID_REQUEST
Time range exceeds interval limit400INVALID_REQUEST
Invalid aggregation function400INVALID_REQUEST
Invalid downsampling algorithm400INVALID_REQUEST
Negative limit400INVALID_REQUEST
Collection not found404COLLECTION_NOT_FOUND
Query execution error500QUERY_FAILED
Invalid POST body400INVALID_JSON

Error Response Format

{
"error": {
"code": "INVALID_REQUEST",
"message": "start_time and end_time are required",
"path": "/v1/databases/mydb/collections/sensors/query"
}
}

cURL Examples

Basic query

curl "http://localhost:8080/v1/databases/mydb/collections/sensors/query?\
start_time=2026-01-01T00:00:00Z&\
end_time=2026-01-02T00:00:00Z&\
ids=sensor-001,sensor-002" \
-H "X-API-Key: your-api-key"

Query with aggregation

curl "http://localhost:8080/v1/databases/mydb/collections/sensors/query?\
start_time=2026-01-01T00:00:00Z&\
end_time=2026-01-02T00:00:00Z&\
ids=sensor-001&\
interval=1h&\
aggregation=avg&\
fields=temperature,humidity" \
-H "X-API-Key: your-api-key"

POST query with anomaly detection

curl -X POST http://localhost:8080/v1/databases/mydb/collections/sensors/query \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"start_time": "2026-01-01T00:00:00Z",
"end_time": "2026-01-02T00:00:00Z",
"ids": ["sensor-001"],
"fields": ["temperature"],
"downsampling": "lttb",
"downsampling_threshold": 500,
"anomaly_detection": "zscore",
"anomaly_threshold": 2.5
}'

Query with limit and specific fields

curl "http://localhost:8080/v1/databases/mydb/collections/sensors/query?\
start_time=2026-01-01T00:00:00Z&\
end_time=2026-01-02T00:00:00Z&\
ids=sensor-001&\
fields=temperature&\
limit=100" \
-H "X-API-Key: your-api-key"