Using Query APIs
Every saved Query Builder query has an API endpoint that returns matching workflow submission data as JSON.
Endpoint Format
GET /api/query/{query-name}
Example:
GET /api/query/monthly-leave-report
The {query-name} value is the slug generated from the query name when the query was first saved.
Authentication
All query API endpoints require a Bearer token:
Authorization: Bearer your-api-token
The token must belong to a user account configured with guard_name = api and active status. Contact your administrator to obtain an API token.
Any valid API token holder can call the query endpoint regardless of workflow permissions. Treat API tokens as sensitive credentials.
Basic Request
curl -X GET "https://your-domain.com/api/query/monthly-leave-report" \
-H "Authorization: Bearer your-api-token"
Response Format
The API returns a JSON object with matching submissions and optional aggregation results.
{
"value": [
{
"submission_id": 42,
"applicantName": { "value": "Ahmad Razali", "type": "textfield" },
"leaveType": { "value": "Annual", "type": "select" },
"amount": { "value": "5000", "type": "number" }
}
],
"total_matches": 150,
"aggregate": {
"amount": 75000
}
}
| Field | Details |
|---|---|
value | Array of matching submissions |
submission_id | Submission identifier |
value.*.{field}.value | Actual value submitted for the selected field |
value.*.{field}.type | Form component type for the selected field |
total_matches | Total number of submissions matching the filters |
aggregate | Aggregation results, keyed by field name; only present when aggregations are configured |
Overriding Saved Filters
You can replace saved filters for one API request by passing filters URL parameters.
GET /api/query/{name}?filters[fieldKey][operation]=equals&filters[fieldKey][value]=approved
Date range filters use from_to:
GET /api/query/{name}?filters[submittedOn][operation]=from_to&filters[submittedOn][from]=2025-01-01&filters[submittedOn][to]=2025-12-31
Null checks can be sent directly:
GET /api/query/{name}?filters[optionalField]=is_null
When any filters[...] parameter is provided, URL filters replace all saved filters for that request. They do not merge with saved filters.
Saved aggregates still apply unless you also pass aggregates[...] parameters.
Available URL filter operations:
equals
contains
starts_with
ends_with
greater_than
less_than
from_to
is_null
is_not_null
count
count_distinct
Overriding Saved Aggregates
You can replace saved aggregations for one API request by passing aggregates URL parameters.
GET /api/query/{name}?aggregates[amount]=sum&aggregates[rating]=avg
When any aggregates[...] parameter is provided, URL aggregates replace all saved aggregates for that request. They do not merge with saved aggregates.
Saved filters still apply unless you also pass filters[...] parameters.
Available aggregate operations:
sum
avg
min
max
count
count_distinct
Complete Example
curl -X GET "https://your-domain.com/api/query/purchase-report?\
filters[status][operation]=equals&\
filters[status][value]=approved&\
filters[submittedOn][operation]=from_to&\
filters[submittedOn][from]=2025-01-01&\
filters[submittedOn][to]=2025-03-31&\
aggregates[amount]=sum" \
-H "Authorization: Bearer your-api-token"
Unsupported API Options
The current Query Builder API does not support pagination, sorting, field-selection overrides, or file export options.
Do not rely on parameters such as:
page
per_page
sort_by
sort_order
fields
format
The full filtered result set is returned in one response.
Common API Errors
| Status | Meaning | What to Check |
|---|---|---|
| 401 Unauthorized | The request is not authenticated | Bearer header, token value, guard_name = api, and active user status |
| 404 Not Found | The query was not found | Query slug, URL encoding, case sensitivity, or whether the query was deleted |