Query efficiently
Query parameters let you narrow records and reduce the amount of information returned. Availability is resource- and field-specific: a field being visible does not mean it supports filtering or sorting.
Filter records
MyCRM uses expressions in the filter parameter. Literal values are enclosed in single quotes, including numbers and booleans; the null keyword is unquoted. Date-only examples use yyyy-MM-dd; use the documented format for timestamp fields.
| Intent | Example expression |
|---|---|
| Equal | equals(hasMarketingConsent,'true') |
| Greater than | greaterThan(id,'1001') |
| At least | greaterOrEqual(updated,'2026-01-01') |
| Less than / at most | lessThan(value,'25000') / lessOrEqual(value,'25000') |
| Contains / starts / ends | contains(email,'example.com') / startsWith(firstName,'Al') / endsWith(lastName,'son') |
| Any value in a set | any(firstName,'Alex','Sam') |
| Has related records | has(contactAddress) |
| Negate | not(equals(firstName,'Alex')) |
| Match either | or(equals(firstName,'Alex'),equals(preferredName,'Alex')) |
| Match both | and(equals(hasMarketingConsent,'true'),greaterThan(id,'1001')) |
These expressions illustrate the grammar. Use them only with fields and relationships supported by the target resource. URL-encode query values through your HTTP client's query builder. Avoid constructing expressions directly from untrusted input.
For apostrophes, null comparisons, combined conditions and field capabilities, see build filters correctly.
Sort records
sort=id sorts ascending; sort=-id sorts descending. Comma-separated fields can express multiple sort criteria where supported. MyCRM's usual default is ascending ID. Sorting on other fields can increase request cost. When supported, a unique tie-breaker such as sort=lastName,firstName,id makes the ordering explicit when several contacts share a name. It does not freeze the underlying data while you page.
Page through records
Use page[size] and page[number]. The reviewed configuration uses a default page size of 10, a maximum of 100, and page numbers starting at 1. Set the page size explicitly when predictable batching matters.
GET /jsonapi/contacts?page[size]=50&page[number]=2
Deep numbered pages become more expensive. For a supported ID filter, a batch after the last processed ID can use:
GET /jsonapi/contacts?sort=id&page[size]=100&filter=greaterThan(id,'1001')
Persist the largest processed ID after the batch succeeds. This traverses IDs; it does not detect updates to earlier IDs or guarantee a fixed snapshot. See synchronisation.
Select fields
GET /jsonapi/contacts/1001?fields[contacts]=firstName,email,contactAddress&include=contactAddress&fields[contact-address]=addressType,formattedAddress
fields[...] uses the resource type, not the relationship name. Include contactAddress in the contact fieldset to preserve the link to the included addresses. Attributes and relationships omitted by a fieldset should not be treated as deleted.
With curl, use --globoff when URLs contain square brackets. In application code, let your client encode brackets, spaces and quotes.
Fieldsets apply by resource type across the document, including matching resources in included. Choose the address fields separately from the contact fields. Keep any relationship names you need for linkage in the parent fieldset.
Build the query in small steps
Start with the smallest working read. Add a filter, confirm the records, then add ordering and paging. Finally select fields and include the connected data you need. If a request fails after one change, inspect that parameter before broadening the request.
The client patterns guide combines these controls in a complete curl example.
Read request costs before choosing a high-volume query pattern.