Docs/Guides/Using the Filter API

Using the filter API

The POST filter API is the most powerful way to query Ptolemy data. This guide covers practical examples for common filtering patterns: combining conditions, EAV field queries, tag filtering, and sorting.

Why POST filter instead of GET?

The GET list endpoints support basic query parameters but are limited to simple equality checks. The POST filter endpoints support:

Nested AND/OR
Combine conditions with arbitrary nesting — any condition can contain sub-conditions.
All operators
Range comparisons (lt, gte), set membership (in), substring (like), and null checks.
EAV field queries
Filter on custom field values using the field. prefix — not possible via GET params.
A single POST /instruments/filter counts as one API call. If you find yourself making multiple GET requests to achieve the same result, switch to the filter endpoint.

Simple equality filter

The simplest filter checks a single field for an exact value:

All equity instruments
{ "type_id": "equity", "limit": 50 }

Top-level convenience fields like type_id are shorthand. You can also express them inside a filter block:

Equivalent using filter block
{ "filter": { "and": [{ "field": "type_id", "op": "eq", "value": "equity" }] } }

Range filter on EAV fields

Use the field. prefix to filter on custom field values. This example finds large-cap equities:

Large-cap equities (market cap > 10bn)
{ "type_id": "equity", "filter": { "and": [ { "field": "field.market_cap", "op": "gt", "value": "10000000000" } ] }, "sort": [{ "field": "field.market_cap", "direction": "desc" }] }

Filter by tag hierarchy

Use tagged_with_descendants to find instruments in a tag tree — this is the most common tag filter pattern:

All instruments in the #equity tree, on ASX or NYSE
{ "filter": { "and": [ { "field": "tags", "op": "tagged_with_descendants", "value": "#equity" }, { "or": [ { "field": "field.exchange", "op": "eq", "value": "ASX" }, { "field": "field.exchange", "op": "eq", "value": "NYSE" } ] } ] } }

Filter by set membership

The in operator matches any value in an array — useful for filtering by a known set of identifiers:

Specific instruments by identifier
{ "filter": { "and": [ { "field": "identifier", "op": "in", "value": ["bhp.ax", "cba.ax", "anz.ax"] } ] } }

Count before fetching

Before paginating through a large result set, use the count endpoint to estimate how many records match your filter. This helps you plan batch sizes and set user expectations.

Count matching records
POST /v1/workspaces/acme-capital/instruments/count { "filter": { "and": [{ "field": "type_id", "op": "eq", "value": "equity" }] } } # Response: { "count": 4820 }

Full-text search

The instruments filter endpoint also supports a q field for full-text search across instrument name and identifier. Combine it with filter conditions for powerful queries:

Full-text search + filter
{ "q": "BHP", "type_id": "equity", "limit": 10 }
Full-text search is case-insensitive and matches substrings. It’s optimised for autocomplete and search-as-you-type patterns. For precise lookups, prefer the identifier equality filter.
PrivacyTermsStatus© 2025 Ptolemy Pty Ltd