Query filters
The structured filter shape used by Find Records, related lists, and metrics. One syntax everywhere.
Shape
[
{ "fieldName": "IsClosed", "operator": "=", "values": ["false"] },
{ "fieldName": "CloseDate", "operator": "<=", "values": ["THIS_QUARTER"] }
]
A list of conditions, combined with AND. There is no OR and no nesting — use IN for alternatives on one field.
| Key | Notes |
|---|---|
fieldName | Field API name on the object being filtered |
operator | See below |
values | Always an array, even for a single value |
In the Studio, the filter builder offers the object’s fields and picklist values. You only write the JSON when calling Find Records programmatically or from an agent.
Operators
| Operator | Meaning | Example |
|---|---|---|
= | Equals | {"fieldName":"StageName","operator":"=","values":["Proposal"]} |
!= | Not equal | {"fieldName":"Type","operator":"!=","values":["Partner"]} |
< | Less than | {"fieldName":"Amount","operator":"<","values":["10000"]} |
<= | At most | {"fieldName":"CloseDate","operator":"<=","values":["THIS_QUARTER"]} |
> | Greater than | {"fieldName":"Amount","operator":">","values":["50000"]} |
>= | At least | {"fieldName":"CreatedDate","operator":">=","values":["LAST_N_DAYS:30"]} |
IN | Any of | {"fieldName":"StageName","operator":"IN","values":["Proposal","Negotiation"]} |
LIKE | Pattern match | {"fieldName":"Name","operator":"LIKE","values":["%Acme%"]} |
IN is the only operator that uses several values. The others use the first.
Date literals
Date and datetime fields accept Salesforce date literals as values:
| Literal | Meaning |
|---|---|
TODAY · YESTERDAY · TOMORROW | |
THIS_WEEK · LAST_WEEK · NEXT_WEEK | |
THIS_MONTH · LAST_MONTH · NEXT_MONTH | |
THIS_QUARTER · LAST_QUARTER · NEXT_QUARTER | |
THIS_YEAR · LAST_YEAR · NEXT_YEAR | |
LAST_N_DAYS:30 | The last 30 days |
NEXT_N_DAYS:90 | The next 90 days |
LAST_N_MONTHS:6 · NEXT_N_MONTHS:3 |
Literals are unquoted inside the value string: "values": ["THIS_QUARTER"]. Absolute dates work too, in ISO form: "values": ["2026-09-30"].
Values are strings
Every value is a string in the JSON, whatever the field’s type. The engine converts based on the field:
| Field type | Write |
|---|---|
| Checkbox | "true" / "false" |
| Number, currency | "50000" — no symbols, no separators |
| Percent | "75" for 75% |
| Date | "2026-09-30" or a literal |
| Picklist | The API value, not the label |
WARNING
Filter picklists on the API value stored in the database, which isn’t always what the UI displays.
Common patterns
Open records
[{"fieldName":"IsClosed","operator":"=","values":["false"]}]
Closing this quarter, still open
[{"fieldName":"IsClosed","operator":"=","values":["false"]},
{"fieldName":"CloseDate","operator":"<=","values":["THIS_QUARTER"]}]
Meaningful deals in late stages
[{"fieldName":"StageName","operator":"IN","values":["Proposal","Negotiation"]},
{"fieldName":"Amount","operator":">=","values":["25000"]}]
Stalled — no activity in 30 days
[{"fieldName":"IsClosed","operator":"=","values":["false"]},
{"fieldName":"LastActivityDate","operator":"<","values":["LAST_N_DAYS:30"]}]
Recently created
[{"fieldName":"CreatedDate","operator":">=","values":["LAST_N_DAYS:7"]}]
Limitations
- No OR across fields. Conditions AND together. Use
INfor alternatives on one field; make two calls or define two related lists for genuinely different conditions. - No nested grouping. No parentheses.
- No cross-object filtering. Filter on fields of the object being queried, not its parents.
- No aggregate conditions. “Accounts with more than five open cases” is a report.
These limits keep agent-written filters cheap to run.
Filters narrow within what the caller can already see — they never widen access. See Security.
The filterable surface
Find Records accepts filters and sortBy only on the entity’s filterable fields. A filter on anything else is refused with the valid set named, so an agent can re-plan instead of silently querying a field the entity never declared askable.
By default a field is filterable when it’s in the curated detailed set. The field picker’s Filter column overrides that per field, in both directions:
- Filter-only — declare a field filterable without returning it anywhere.
IsClosedis the shipped example: agents screen on it, it never spends payload tokens. - Return-but-don’t-filter — keep a field in payloads but stop agents filtering on it: unindexed fields on large objects, or fields where filtering gives a wrong answer.
Get Catalog with an entity’s name lists its filterable fields with their valid picklist values and sampled example values — the agent-facing half of this declaration.
Named filters
A named filter is a named condition on the entity — open, committed — passed by name in Find Records’ filterNames instead of constructed as JSON. The org’s definition of a business concept answers, not the model’s guess at one: “open deals” means whatever the admin wrote down, renewals excluded or not.
Named filters resolve after the filterable check, by name, from the element library — never parsed from caller input — which is why a named filter may use fields that are not individually filterable. They compose by AND, with each other and with filters. The catalog lists each entity’s named filters with their meaning and their pragmatics; an unknown name refuses with the valid set.
Where filters appear
| Where | How |
|---|---|
| Find Records | The filters input, as JSON — and filterNames, named filters by name |
| Related lists | The filter builder, per list |
| Metrics | The filter builder, on the child records |
| Named filters | The filter builder, on the Filters library page |
Entity.find | req.filtersJson · req.filterNames |
Agents learn filterable field names from Get Catalog — see Invocable actions.