Skip to main content
Pass a filter object to listRecords and paginateRecords. Every condition must match (AND), across fields and within one field.
The SDK sends the filter as the JSON filter query parameter of the Data API list endpoint; the same syntax works over HTTP.

Syntax

Each key is a field key; each value is one of: created_at and updated_at can also be filtered with gt, gte, lt, and lte against an RFC 3339 timestamp with an explicit offset (Z or ±HH:MM) — use them for incremental sync:

Operators

Values are compared as the field’s type: a number or currency field compares numerically (9 < 41), a date field compares YYYY-MM-DD dates, and text comparisons are exact except for contains and starts_with, which ignore case. % and _ in a contains/starts_with value match themselves, not wildcards.

Invalid filters are rejected, never ignored

A filter that cannot be applied exactly as written fails with 422 VALIDATION_FAILED and names the condition in error.param and error.details (for example filter.age). That covers:
  • a key that is not a declared field of the entity,
  • an operator the field’s type does not support (gt on a boolean),
  • a value of the wrong type ({ age: { gt: 'forty' } }), an empty or oversized in list,
  • malformed JSON, or a filter over 8 KB.
A silently dropped condition would return more records than you asked for. On a surface that can hold PHI, that is a disclosure, so the API refuses instead.

Limits

Performance

Filters and sorts on a field declared indexed: true are served by a database index; others scan the entity’s records. Index the fields your app filters or sorts on routinely. See Indexing fields.

OR logic

Conditions are always ANDed. For “status is open OR assignee is me”, make two requests and merge the results, de-duplicating by id. For several values of one field, use in instead.