Filter Expression
When to use it
filterExpression is a recursive boolean tree. Use it when the request needs more than the flat AND-only semantics of the convenience filterobject: for example, "calls or bullish trades", "calls with premium >= $100k or contracts expiring this week", or any composition deeper than a single conjunction.
Two node shapes live in the tree. A terminal node is a single condition: a field, an operation, and one or more values. A compound node groups two or more children under an AND or OR conjunction. The two shapes are mutually exclusive at a single level; mixing terminal and compound fields on the same node is rejected with a validation error.
Terminal filters
A terminal is a leaf in the expression tree: a single field/operation/value condition. Every compound expression eventually grounds out in terminals.
{ "filterExpression": { "field": "TICKER", "operation": "EQUALS", "values": ["AAPL"] } }
fieldis required and must resolve to a filterable field for the endpoint you are calling. See Field Reference for the full inventory.operationis required. Accepts canonical names (EQUALS) or shorthand (=,EQ); see Operations below.values(or its aliasvalue) is required and must be non-empty. Multiple values within a single terminal areOR-semantic.- The two compound fields (
conjunction,filters) must be omitted on a terminal. Mixed shapes are rejected with a validation error.
Compound filters
A compound node combines multiple child filters under a single conjunction. The children list is fully recursive: a compound can contain terminals, other compounds, or any mix.
Flat AND
{ "filterExpression": { "conjunction": "AND", "filters": [ { "field": "TICKER", "operation": "=", "value": "AAPL" }, { "field": "MONEY_TYPE", "operation": "=", "value": "ITM" }, { "field": "CONTRACT_TYPE", "operation": "=", "value": "CALL" } ] } }
Nested AND / OR
{ "filterExpression": { "conjunction": "AND", "filters": [ { "field": "TICKER", "operation": "=", "value": "AAPL" }, { "conjunction": "OR", "filters": [ { "field": "SENTIMENT", "operation": "=", "value": "BULLISH" }, { "field": "TRADE_SIDE", "operation": "=", "value": "AA" } ] } ] } }
conjunctionis required. Values:AND,OR.filtersis required and must contain at least one child. Children can themselves be terminal or compound; the tree is fully recursive.- The three terminal fields (
field,operation,values) must be omitted on a compound node. - Maximum recursion depth is
5. Maximum total terminal filters in the expression is100.
Operations
Six comparison operations are supported. Each one accepts the canonical UPPER_SNAKE_CASE name plus symbolic and abbreviated aliases.
EQUALS:=,==,EQ,EQUAL.DOES_NOT_EQUAL:!=,<>,NEQ,NOT_EQUALS,NOT_EQUAL.GREATER_THAN:>,GT,GREATER.GREATER_THAN_OR_EQUAL_TO:>=,GTE,GE,GREATER_OR_EQUAL.LESS_THAN:<,LT,LESS.LESS_THAN_OR_EQUAL_TO:<=,LTE,LE,LESS_OR_EQUAL.
Multi-value terminals
The canonical field name is values, typed as a collection. The singular value is accepted as an alias, and a scalar is coerced to a one-element collection. Multiple values on a single terminal are OR-semantic: the row matches if any of the listed values is a match.
// All four are equivalent: a single value resolves to a one-element collection. { "field": "TICKER", "operation": "EQUALS", "value": "AAPL" } { "field": "TICKER", "operation": "EQUALS", "values": "AAPL" } { "field": "TICKER", "operation": "EQUALS", "value": ["AAPL"] } { "field": "TICKER", "operation": "EQUALS", "values": ["AAPL"] } // Multi-value with OR semantics (any of the listed values is a match): { "field": "TICKER", "operation": "EQUALS", "values": ["AAPL", "NVDA", "TSLA"] }
Limits
Two structural limits keep the expression tree to a manageable size. Both surface as a validation error when exceeded.
Combining with filter
The convenience filter object and filterExpression can both be present on the same request. They are AND-ed: every row in the response must satisfy filter and satisfy filterExpression.
{ "filter": { "tickers": ["AAPL", "NVDA"] }, "filterExpression": { "conjunction": "OR", "filters": [ { "field": "CONTRACT_TYPE", "operation": "=", "value": "CALL" }, { "field": "SENTIMENT", "operation": "=", "value": "BULLISH" } ] } } // Reads as: (ticker IN [AAPL, NVDA]) AND (calls OR bullish sentiment).
Use filterfor the simple "narrow by ticker / by expiration / by sector" cases: it is shorter to write. Reach for filterExpression when you need OR semantics, nested logic, or a comparison operator other than equality.
Worked example
Putting it together: today's session, three tickers, calls only, premium at or above $100,000, AND (bullish sentiment OR a trade above the ask).
{ "sessionDate": "2026-05-13", "filterExpression": { "conjunction": "AND", "filters": [ { "field": "TICKER", "operation": "=", "values": ["AAPL", "MSFT", "NVDA"] }, { "field": "CONTRACT_TYPE", "operation": "=", "value": "CALL" }, { "field": "PREMIUM", "operation": ">=", "value": "100000" }, { "conjunction": "OR", "filters": [ { "field": "SENTIMENT", "operation": "=", "value": "BULLISH" }, { "field": "TRADE_SIDE", "operation": "=", "value": "AA" } ] } ] } } // Reads as: today's session, AAPL/MSFT/NVDA, calls only, premium >= $100,000, // AND (bullish sentiment OR traded above ask).