FilterRequest

Advanced filtering, sorting, and aggregation request model.

This is the most powerful endpoint in the API, allowing complex queries with:

  • Boolean logic with $and / $or, nestable
  • Comparison operators (eq, ne, gt, gte, lt, lte, in, not_in, contains, ...)
  • Statistical aggregations (count, sum, avg, min, max)
  • Sorting by one field, ascending or descending
  • Full-text search across multiple fields
  • Date range filtering, predefined or from/to
  • Custom field filtering support
  • Filter Conditions – an object keyed by field name. Each key is a field of the entity (camelCase or snake_case, custom fields included) or one of the logical keys $and / $or. Every top-level key must match (they are ANDed).

    The forms a field accepts:

    {
      "status": 1,                                  // equals
      "stage": [3, 4],                              // in the list
      "managedBy": ["u-abc-123", null],             // in the list, or empty
      "closedAt": "not_null",                       // has a value
      "dealValueAmount": {"gte": 50000, "lt": 100000},  // operator object, every operator must match
      "createdAt": {"dateRange": "thisQuarter"}     // date range
    }
    

    Operators (the keys of an operator object):

    • eq, ne – equals / not equals
    • gt, gte, lt, lte – comparisons; min and max are aliases of gte and lte
    • in, not_in, in_or_null – value in / not in a list; in_or_null also matches empty
    • in_nocase – in, ignoring case
    • contains, not_contains – text contains the value (case-sensitive); on a list field, the list has the value as an element
    • contains_nocase, not_contains_nocase – the same, ignoring case
    • between, between_or_null – value is [low, high], both inclusive
    • is_null, not_null – field is empty / has a value (any value, e.g. true)
    • length_eq, length_ne, length_gt, length_gte, length_lt, length_lte – length of a list field
    • dateRange – "thisWeek", "lastWeek", "thisMonth", "lastMonth", "thisQuarter", "lastQuarter", "thisYear", "lastYear", "nextMonth", "nextQuarter", "nextYear", "ytd", or {"fromDate": "2024-01-01", "toDate": "2024-03-31"} (either bound may be left out)

    There is no like, ilike, nin or not – use contains, contains_nocase and not_in. Any other operator is refused with a 400 that lists these. camelCase names (containsNocase, notIn) are read as their snake_case operators.

    $and / $or take a list of filter objects of this same shape, and nest. Inside $or, every condition of every listed object is one alternative, so {"$or": [{"a": 1, "b": 2}]} means a = 1 OR b = 2; to require both together inside an $or, list {"$and": [{"a": 1}, {"b": 2}]} as the alternative.

    {
      "status": 1,
      "dealValueAmount": {"gte": 50000},
      "$or": [
        {"region": ["EMEA", "NA"]},
        {"managedBy": {"eq": "u-abc-123"}}
      ]
    }
    

    Not accepted – the {"field": ..., "operator": ..., "value": ...} form and the and / or / not keys. They are read as filters on fields named field, and, and so on, and are refused with a 400 listing the fields the entity has.

    Integer fields with named values, such as a deal's status, take the number or the name: {"status": "In Progress"} is {"status": 1}.

    This works the same way for deals, companies, leads, people, or any other entity type – only the field names change to match the entity schema.

    Note: filters is required but may be an empty object ({}) if you want to apply no filtering and just use sorting / pagination.

    Properties: 1
  • Statistical Aggregations – Compute summary metrics alongside filtered results.

    Structure:

    {
      "aggregation_name": {
        "field": "field_to_aggregate",
        "operation": "count|sum|avg|min|max|distinct_count"
      }
    }
    

    Supported Operations:

    • count – Count of non-null values
    • sum – Sum of numeric values
    • avg – Average of numeric values
    • min – Minimum value
    • max – Maximum value
    • distinct_count – Count of unique values

    Examples (generic across entities):

    {
      "entity_count": {"field": "id", "operation": "count"},
      "total_value": {"field": "deal_value_amount", "operation": "sum"},
      "avg_amount": {"field": "deal_value_amount", "operation": "avg"},
      "max_amount": {"field": "deal_value_amount", "operation": "max"}
    }
    

    These names are intentionally generic so the same pattern can be applied to deals, companies, leads, people, or any other entity type.

    Grouping: groupBy reports the metrics once per distinct value of a field, each group with its record count. "groupBy": "all" reports them once for the whole set.

    {"aggregations": {"groupBy": {"field": "status"}, "groupLimit": 200}}
    

    groupLimit (optional, 1–1000) returns only the largest groups by record count, ordered largest first, ties in value order. The response then also carries groupsTotal, the number of groups before the limit, and groupsTruncated, true when groups were left out. Totals over the whole set cannot be summed from a limited response; request them with "groupBy": "all", where groupLimit has no effect. Without groupLimit every group is returned.

    Use Cases:

    • Dashboard metrics and KPIs
    • Pipeline / funnel analysis and reporting
    • Performance tracking by owner, team, or stage
    • Data validation and quality checks
    Properties: 1
  • Start date, required when comparePeriod is 'custom' and ignored otherwise.

  • Comparison timeframe. When set, an entity that records point-in-time figures also returns its totals as they stood at the start of this period, over the same filtered set. Omit it and the response is unchanged. MTD, QTD and YTD follow the account's fiscal calendar; last30Days and last12Months count back from today.

    values
    last30Daysmtdqtdytdlast12Monthscustom
  • Full-text Search - Search across multiple fields with flexible matching.

    Structure:

    {
      "term": "search_term",
      "fields": ["field1", "field2", ...],
      "operator": "and|or",
      "case_sensitive": false,
      "exact_match": false
    }
    

    Search Options:

    • term - Text to search for (required)
    • fields - Specific fields to search (optional, defaults to all text fields)
    • operator - How to combine multiple terms (and requires all terms, or requires any term)
    • case_sensitive - Whether search is case-sensitive (default: false)
    • exact_match - Whether to match exact phrases only (default: false)

    Searchable Fields:

    • name - Deal/entity name
    • description - Deal description
    • notes - Associated notes
    • company_name - Associated company name
    • contact_name - Primary contact name
    • tags - Associated tags and labels

    Examples:

    {
      "term": "enterprise software",
      "fields": ["name", "description"],
      "operator": "and",
      "case_sensitive": false
    }
    

    Advanced Search:

    {
      "term": "Acme Corp Q1 2024",
      "fields": ["name", "company_name"],
      "operator": "or",
      "exact_match": false
    }
    

    Use Cases:

    • Find deals by company name
    • Search deal descriptions for keywords
    • Locate deals with specific terms
    • Filter by tags or categories
    Properties: 1
  • Sorting – an object naming one field to sort by. One sort field is supported; a list of sort keys is refused with a 422.

    Structure:

    {"field": "createdAt", "ascending": false}
    
    • field – the field to sort by, camelCase or snake_case (required)
    • ascending – true (the default) for A–Z, 0–9, oldest first; false for Z–A, 9–0, newest first

    There is no direction key – {"field": "createdAt", "direction": "desc"} sorts ascending. Use "ascending": false.

    Common Fields (vary by entity):

    • createdAt – Entity creation date
    • updatedAt – Last modification date
    • dealValueAmount – Deal monetary amount field
    • status – Lifecycle status
    • name – Entity name/title

    When sort is left out, main entities (deals, companies, ...) are ordered by createdAt, oldest first.

    Properties: 1