Docs/Core Concepts/Filtering Filtering
Most collection endpoints support a POST-based filter API for precise, composable queries. Filters support nested AND/OR conditions, comparison operators, EAV field queries, tag queries, and full-text search.
Filter vs. list endpoints
Every collection has both a simple list endpoint and an advanced filter endpoint:
GET /instruments
Simple list with basic query parameters (?type_id, ?q, ?archived). Good for quick lookups and simple queries.
POST /instruments/filter
Full filter API with nested conditions, multiple operators, and EAV field queries. Use this for anything beyond basic filtering.
Use the filter endpoint instead of making many GET requests with different parameters. A single filter request is more efficient and counts as one API call.
Filter body structure
The filter request body is a JSON object with optional filter, sort, limit, and after keys.
{
"filter": {
"and": [
{ "field": "...", "op": "...", "value": "..." }
],
"or": [/* additional conditions */]
},
"sort": [{ "field": "created_at", "direction": "desc" }],
"limit": 50,
"after": "eyJpZCI6..."
}
Operators
| Operator | Description | Value type |
|---|
eq | Exact match | string, number, boolean, or null |
ne | Not equal | string, number, boolean, or null |
lt | Less than | number or ISO 8601 string |
lte | Less than or equal | number or ISO 8601 string |
gt | Greater than | number or ISO 8601 string |
gte | Greater than or equal | number or ISO 8601 string |
in | Value is in array | array of strings or numbers |
not_in | Value is not in array | array of strings or numbers |
like | Case-insensitive substring match | string (no wildcards needed) |
is_null | Field is null | boolean (true or false) |
is_descendant_of | Tag hierarchy (tags only) | tag path string |
tagged_with_descendants | Instrument has this tag or any descendant | tag UUID or path |
tagged | Instrument has exactly this tag | tag UUID or path |
EAV field queries
For instruments and markets, you can filter on custom field values using the field. prefix:
{
"filter": {
"and": [
{ "field": "field.exchange", "op": "eq", "value": "ASX" },
{ "field": "field.market_cap", "op": "gt", "value": "1000000000" }
]
}
}
Similarly, use the extras. prefix to filter on unstructured extras fields:
{ "field": "extras.bloomberg_figi", "op": "eq", "value": "BBG000BKRN43" }
Nesting AND / OR
Conditions can be nested arbitrarily deep using and and or arrays. A condition node is either a leaf (with field, op, value) or a compound (and/or containing more nodes).
{
"filter": {
"and": [
{ "field": "type_id", "op": "eq", "value": "equity" },
{
"or": [
{ "field": "field.exchange", "op": "eq", "value": "ASX" },
{ "field": "field.exchange", "op": "eq", "value": "NYSE" }
]
}
]
}
}
Sorting
The sort key accepts an array of sort objects. Earlier entries take priority. The direction field accepts asc or desc.
{
"sort": [
{ "field": "field.market_cap", "direction": "desc" },
{ "field": "name", "direction": "asc" }
]
}
Sortable fields include all standard resource fields (name, identifier, created_at, updated_at, archived_at) and all field. prefixed EAV fields. EAV field sorting is performed as string comparison — numeric strings sort lexicographically unless the field’s data_type is number, in which case numeric comparison is used.