Query Filter
Shared syntax for filtering, sorting, paginating and grouping results on index endpoints across every Instasent API. Two equivalent formats: URL query string or a JSON _q parameter.
Every index endpoint that returns a list of resources accepts the same Query Filter syntax. You can express the same query in two equivalent formats: compact URL query string parameters, or a richer JSON _q parameter for conditions that need AND/OR logic.
Pick whichever is cleaner for the case at hand — the server parses both into the same internal structure.
Quickstart
Filter by status:
GET /api/endpoint?status_eq=estimated
Filter with multiple conditions (combined with AND):
GET /api/endpoint?number_eq=34600000000&age_gte=35
URL query string format
The URL format packs filters, sorting, pagination and grouping into a compact set of query parameters. Use it when conditions combine with AND and the query is small enough to read in a URL.
Filters
- Field and operator are joined by an underscore:
field_operator=value. - Multiple filter parameters combine with
&— implicit AND. - Any URL parameter that is not a reserved keyword (
_sort,_start,_limit,_group,_q) is treated as a filter.
?number_eq=34600000000&age_gte=35
Sorting
- Parameter:
_sort. - Fields separated by commas.
- Direction appended with
:—-for descending,+or nothing for ascending (default).
?_sort=name,surname:-
Sorts by name ascending, then surname descending.
Pagination
Parameters _start and _limit. Both must be set or both omitted.
?_start=0&_limit=10
Grouping
For aggregate queries on statistics / reports endpoints.
- Parameter:
_group. - The value is not necessarily an existing field — tokens like
hourly,daily,monthlyare valid.
?_group=daily
Nested fields
Reference nested object fields with * as the path separator.
?age_gte=35&attributes*drink_eq=beer
Filters by age >= 35 AND attributes.drink == "beer".
Date formats
URL parameter values are strings; the server coerces them based on the field type. For date fields, the accepted formats are:
- ISO 8601 —
2019-05-08T10:25:12+02:00 - Microseconds (UTC) —
2019-05-08T10:25:12.715 - Relative —
1 day ago. Valid periods:second,minute,hour,day,month,year.
?createdAt_gte=2019-05-08T10:25:12+02:00
?createdAt_gte=1 day ago
Array values
For operators that accept a list of values, separate items with |.
?age_betweeneq=18|35&name_in=david|daniel|marta
Filters by age between 18 and 35 (inclusive) AND name in ["david", "daniel", "marta"].
JSON _q format
For queries that need AND/OR logic or structured conditions, send a JSON object as the _q URL parameter.
Shape
{
"filter": [
{ "field": "status", "operator": "eq", "value": "estimated" }
],
"paging": { "start": 0, "limit": 20 },
"sort": [["status", "asc"]],
"group": "status"
}Top-level keys:
filter— array of filter conditions.paging—{ start, limit }. Both must be present together.sort— array of[field, direction]tuples. Direction is"asc"or"desc".group— grouping expression (same semantics as_group).
Filter condition
Each entry in filter has three properties:
field— field name, or""when combining sub-conditions.operator— comparison operator (see Operators reference).value— value to compare against. For list operators this is an array.
Combining with AND / OR
Nest sub-conditions with an empty field and operator: "and" | "or":
{
"filter": [
{
"field": "",
"operator": "or",
"value": [
{ "field": "status", "operator": "eq", "value": "draft" },
{ "field": "status", "operator": "eq", "value": "confirmed" }
]
},
{
"field": "deliveredText",
"operator": "eq",
"value": "Your activation code is 4812"
}
]
}Reads as: (status == "draft" OR status == "confirmed") AND deliveredText == "Your activation code is 4812".
Operators reference
Generic
| Operator | Description | Field types |
|---|---|---|
exists | Field is present. Boolean check. | Any |
Comparison
| Operator | Description | Field types |
|---|---|---|
eq | Equals (exact match). | String, number, date, id/ref |
eqi | Equals, case-insensitive. | String |
ne | Not equals. | String, number, date, id/ref |
nei | Not equals, case-insensitive. | String |
Numeric comparison
| Operator | Description | Field types |
|---|---|---|
lt | Less than. | Number, date |
lte | Less than or equal. | Number, date |
gt | Greater than. | Number, date |
gte | Greater than or equal. | Number, date |
List
| Operator | Description | Field types |
|---|---|---|
in | Value is in the list. | String, id/ref |
ini | Value is in the list, case-insensitive. | String |
nin | Value is not in the list. | String, id/ref |
nini | Value is not in the list, case-insensitive. | String |
String
| Operator | Description | Field types |
|---|---|---|
contains | Contains substring. | String |
containsi | Contains substring, case-insensitive. | String |
ncontains | Does not contain substring. | String |
ncontainsi | Does not contain substring, case-insensitive. | String |
starts | Starts with. | String |
startsi | Starts with, case-insensitive. | String |
ends | Ends with. | String |
endsi | Ends with, case-insensitive. | String |
All string operators also accept arrays of values.
Range
| Operator | Description | Bounds |
|---|---|---|
range | Within range [min, max]. | min inclusive, max exclusive |
between | Between [min, max]. | Both exclusive |
betweeneq | Between [min, max], inclusive. | Both inclusive |
Range operators apply to number and date fields only. Value is always a two-element array.
Logical
| Operator | Description |
|---|---|
and | All nested conditions must match. Used with empty field. |
or | At least one nested condition must match. Used with empty field. |
Common patterns
Filtering by status:
GET /api/endpoint?status_eq=estimated
Multiple AND conditions:
GET /api/endpoint?status_eq=confirmed&age_gte=18&age_lte=65
OR between two conditions:
GET /api/endpoint?status_eq=draft&status_eq=confirmed
Date range:
GET /api/endpoint?createdAt_gte=2019-05-08T10:25:12%2B02:00&createdAt_lt=2019-06-08T10:25:12%2B02:00
Relative date:
GET /api/endpoint?createdAt_gte=1 day ago
Value in list:
GET /api/endpoint?name_in=david|daniel|marta
Nested fields:
GET /api/endpoint?attributes*drink_eq=beer
Filter + sort + paginate together:
GET /api/endpoint?status_eq=confirmed&_sort=createdAt:-&_start=0&_limit=20
Complete example
A query that filters by (status == "draft" OR status == "confirmed") AND a specific delivered text, paginated, sorted and grouped:
{
"filter": [
{
"field": "",
"operator": "or",
"value": [
{ "field": "status", "operator": "eq", "value": "draft" },
{ "field": "status", "operator": "eq", "value": "confirmed" }
]
},
{
"field": "deliveredText",
"operator": "eq",
"value": "Your activation code is 4812"
}
],
"paging": { "start": 0, "limit": 20 },
"sort": [["status", "asc"]],
"group": "status"
}