Filter Syntax

Every filter operator Customermates supports, with examples.

Customermates filters (used by the Model Context Protocol (MCP) tools, the REST API, and the app UI) are arrays of field-operator-value rules. Sixteen operators cover equality, comparison, set membership, range, recency, null checks, and relationship membership.

Where filters apply

  • The list_records MCP tool and the messaging filters on get_messaging_threads and get_activities.
  • entityFilters and dealFilters on widgets.
  • timelineFilters on activity widgets. Activity filters allow at most one rule per field; put OR alternatives in one in value array.
  • Saved views in the UI (converted to the same shape under the hood).

The shape

[
  { "field": "firstName", "operator": "contains", "value": "acme" },
  { "field": "createdAt", "operator": "gte",       "value": "2024-01-01" }
]

Rules are AND-combined. For OR logic, run two queries and merge client-side, or use the in operator when comparing against a list.

Operators

OperatorExpectsWorks onExample value
equalssinglescalars, ids"active"
containssinglestrings"acme"
gtsinglenumbers, dates"2024-01-01"
gtesinglenumbers, dates100
ltsinglenumbers, dates"2024-12-31"
ltesinglenumbers, dates"2024-12-31"
inarrayany["id1", "id2"]
notInarrayany["id1"]
betweenarray of 2numbers, dates["2024-01-01", "2024-12-31"]
inLastDayssingle (integer)dates30
isNullno valueany(none)
isNotNullno valueany(none)
hasNoneno valuerelationship arrays(none)
hasSomeno valuerelationship arrays(none)
hasUnsetno valuemessaging-thread participants(none)
allSetno valuemessaging-thread participants(none)

Date operators

Date fields such as createdAt and updatedAt accept gt, gte, lt, lte, between, and inLastDays. Use inLastDays with an integer number of days for a rolling recency window, for example { "field": "createdAt", "operator": "inLastDays", "value": 7 } for records created in the last week.

Relationship and participant operators

Relationship arrays (organizationIds, dealIds, userIds, contactIds, serviceIds, taskIds) accept in, notIn, hasNone, and hasSome. The participants link-status field on get_messaging_threads uses hasUnset and allSet to filter threads by whether their participants are linked to records.

Field names

The field value is whatever get_record_schema returns under filterableFields for that entity. It includes:

  • Default scalar fields (e.g. createdAt, updatedAt).
  • Relationship arrays (organizationIds, dealIds, userIds, contactIds). Pair these with in, notIn, hasNone, hasSome.
  • Custom column ids. Use the column's UUID as the field.

Always call get_record_schema first if you're not sure what's filterable. The error when a field isn't recognized lists every available field with its allowed operators.

Examples

Contacts in any of three organizations:

{ "field": "organizationIds", "operator": "in", "value": ["org_1","org_2","org_3"] }

Deals created in 2024 whose custom singleSelect column (identified by its UUID) equals a chosen option value:

[
  { "field": "createdAt", "operator": "between", "value": ["2024-01-01","2024-12-31"] },
  { "field": "col_uuid",  "operator": "equals",  "value": "option_value" }
]

Contacts without any organization linked:

{ "field": "organizationIds", "operator": "hasNone" }

Records created in the last 30 days:

{ "field": "createdAt", "operator": "inLastDays", "value": 30 }

Free-text vs filters

list_records also accepts searchTerm, which runs a free-text search against the entity's name fields (firstName + lastName for contacts, name for the rest). If you want "contacts whose name contains acme", that's searchTerm, not a filter rule on firstName. Filter rules on firstName specifically are not supported.

Next