Skip to main content

Complete Filters Reference Guide

What This Guide Is​

This is your complete reference for filtering records in Apper's API. We'll explain:

  • How Apper's filtering system works (concepts first)
  • Every available operator and when to use it
  • How to build complex queries step-by-step

Who is this for? Developers integrating with Apper who need to search/filter records programmatically.

Prerequisites: You should be familiar with the Apper API Documentation basics (authentication, making requests, etc.).


Filtering 101: Core Concepts​

Before diving into specific operators, let's understand how Apper's filtering system works.

The Basic Filter Structure​

Every filter condition has four parts:

{
"fieldName": "Status", // Which field to check
"operator": "Contains", // How to compare
"values": ["Active"], // What to compare against
"include": true // Include or exclude matches
}
Breaking it down:

  • fieldName: The column/field you're filtering on (must match exactly)
  • operator: The comparison type (contains, greater than, etc.)
  • values: An array of values to compare (even for single values, use an array)

Include = Whether to include (true) or exclude (false) matching records

Understanding AND vs OR Logic​

Apper gives you two ways to combine filters:​

Simple AND Logic: The "where" Array

What this means: "Give me records where Status = Active AND State = California"

All conditions in the where array must be true.

{
"where": [
{ "fieldName": "Status", "operator": "Includes", "values": ["Active"] },
{ "fieldName": "State", "operator": "Includes", "values": ["California"] }
]
}
Complex AND/OR Logic: The "whereGroups" Array

What this means: "Give me records where State = California OR State = Texas"

Use whereGroups when you need OR logic between different fields.

{
"whereGroups": [
{
"operator": "OR",
"subGroups": [
{
"operator": "OR",
"conditions": [
{ "fieldName": "State", "operator": "Includes", "values": ["California"] },
{ "fieldName": "State", "operator": "Includes", "values": ["Texas"] }
]
}
]
}
]
}

Example scenarios:​

What You WantUse This
Active customers in Californiawhere (both conditions must be true)
Customers in California or TexaswhereGroups (either state can match)
Active customers in California or TexasBoth → where for Active, whereGroups for states
The "include" Parameter: Inverting Logic​

Every filter has an optional include parameter:

  • "include": true (default) = Include matching records
  • "include": false = Exclude matching records (adds a NOT)
When to use include: false:​
  • Excluding specific values (easier than listing all other values)
  • Date ranges you want to avoid ("not in the last 30 days")
  • Status exclusions ("everything except Draft and Deleted")

Quick Decision Guide: Which Operator?​

Choose the right operator based on what you're trying to do:

"I want records where the value..."

You Want…OperatorExample
Text Searches
Contains this textContainsName contains "Tech"
Doesn’t contain this textNotContainsEmail doesn’t contain "spam"
Starts with this textStartsWithPhone starts with "+1"
Ends with this textEndsWithWebsite ends with ".com"
Is one of several valuesIncludesStatus in ["Active", "Pending"]
Is none of several valuesExcludesType not in ["Draft", "Archived"]
Numerical Comparisons
Is greater thanGreaterThanAmount > 1000
Is less thanLessThanStock < 10
Is at least (≥)GreaterThanOrEqualToScore ≥ 75
Is at most (≤)LessThanOrEqualToAge ≤ 65
Is between two numbersExactMatch + BetweenPrice between 50 and 100
Date Comparisons
Is in this time periodRelativeMatchCreatedOn in "this month"
Is a specific dateEqualTo or ExactMatchDate = "2025-01-15"
Is before / after a dateLessThan / GreaterThanDueDate < "2025-12-31"

"I need to combine multiple conditions..."

You WantUse ThisExample Logic
All conditions must be truewhere arrayA AND B AND C
Any condition can be trueIncludes or whereGroupsA OR B OR C
Complex nested logicwhereGroups(A AND B) OR (C AND D)

Text Field Filters​

Applies to: Text, Email, Phone, Website, MultilineText, Picklist, Radio, AutoNumber

Text fields are probably the most common thing you'll filter. Here are all the operators and when to use each.

Exact Matching​

NotEqualTo​

When to use: You want everything except one specific value.

{
"fieldName": "Status",
"operator": "NotEqualTo",
"values": ["Deleted"]
}
Includes (Multiple Exact Values)​

When to use: You want records matching any of several exact values (OR logic).

{
"fieldName": "Priority",
"operator": "Includes",
"values": ["High", "Critical", "Urgent"]
}

What this means: "Give me records where Priority is High OR Critical OR Urgent"

Excludes (Exclude Multiple Values)​

When to use: You want to exclude several specific values.

{
"fieldName": "Type",
"operator": "Excludes",
"values": ["Draft", "Archived", "Deleted"]
}

What this means: "Give me all records except those with Type = Draft, Archived, or Deleted"

Partial Text Matching​

Contains​

When to use: You're searching for text anywhere in the field (like a search box).

{
"fieldName": "CompanyName",
"operator": "Contains",
"values": ["Tech"]
}
Matches:

  • "TechCorp"
  • "FinTech Solutions"
  • "Advanced Technologies"
  • "tech startup" (case-insensitive)
Doesn't match:

  • "ABC Company"
  • "Global Industries"
NotContains​

When to use: You want to exclude records with certain text.

{
"fieldName": "Email",
"operator": "NotContains",
"values": ["test"]
}

Matches: All emails that don't have "test" anywhere in them

StartsWith​

Field value starts with the specified text.

{
"fieldName": "Phone",
"operator": "StartsWith",
"values": ["+1"]
}

Matches: "+1-555-1234", "+1 (555) 5678"

NotStartsWith​

Field value does not start with the specified text.

{
"fieldName": "OrderNumber",
"operator": "NotStartsWith",
"values": ["TEST"]
}
EndsWith​

Field value ends with the specified text.

{
"fieldName": "Email",
"operator": "EndsWith",
"values": [".edu"]
}

Matches: "example.com", "website.com"

NotEndsWith​

Field value does not end with the specified text.

{
"fieldName": "Website",
"operator": "NotEndsWith",
"values": [".gov"]
}

Alphabetical Comparison​

These operators compare text alphabetically (A→Z ordering).

GreaterThan​

When to use: Alphabetical sorting/filtering.

{
"fieldName": "Name",
"operator": "GreaterThan",
"values": ["M"]
}

Matches: "Nancy", "Oliver", "Zoe" (names starting with letters after M)

ExactMatch with Multiple Values​

Match exact values from a list.

{
"fieldName": "Status",
"operator": "ExactMatch",
"include": true,
"values": ["Active", "Pending"]
}
Exclude specific values:

{
"fieldName": "Type",
"operator": "ExactMatch",
"include": false,
"values": ["Draft", "Archived"]
}

Number Field Filters​

Applies to: Number, Decimal, Currency

Basic Operators​

NotEqualTo​

Not equal to the specified number.

{
"fieldName": "Amount",
"operator": "NotEqualTo",
"values": [0]
}
GreaterThan​

Greater than the specified number.

{
"fieldName": "Price",
"operator": "GreaterThan",
"values": [99.99]
}
LessThan​

Less than the specified number.

{
"fieldName": "Stock",
"operator": "LessThan",
"values": [10]
}
GreaterThanOrEqualTo​

Greater than or equal to the specified number.

{
"fieldName": "Score",
"operator": "GreaterThanOrEqualTo",
"values": [75]
}
LessThanOrEqualTo​

Less than or equal to the specified number.

{
"fieldName": "Age",
"operator": "LessThanOrEqualTo",
"values": [65]
}

Range Filtering with ExactMatch + Between​

For numeric ranges, use the Between subOperator with ExactMatch.

Between Two Values​
{
"fieldName": "Age",
"operator": "ExactMatch",
"subOperator": "Between",
"values": [25 and 40]
}

What this means: Age ≥ 25 AND Age ≤ 40 (inclusive on both ends)

Exclude a Range​
{
"fieldName": "Score",
"operator": "ExactMatch",
"subOperator": "Between",
"include": false,
"values": [0 and 50]
}

What this means: Exclude scores between 0 and 50 (only show 51+)

Below a Value (Less Than or Equal)​
{
"fieldName": "Price",
"operator": "ExactMatch",
"subOperator": "Between",
"values": ["below 100"]
}

Format: "below {value}"

What this means: Price ≤ 100

Above a Value (Greater Than or Equal)​
{
"fieldName": "Revenue",
"operator": "ExactMatch",
"subOperator": "Between",
"values": ["5000 and above"]
}

Format: "{value} and above"

What this means: Revenue ≥ 5000

Multiple Specific Values​
{
"fieldName": "Quantity",
"operator": "Includes",
"values": ["10", "25", "50", "100"]
}

What this means: Quantity is 10 OR 25 OR 50 OR 100

Text Operators on Numbers (Advanced)​

You can use text operators like Contains on number fields:

{
"fieldName": "Phone",
"operator": "Contains",
"values": [555]
}

Matches: Any phone number containing "555" (e.g., 555-1234, 123-555-7890)

Use case: Searching for partial numbers, area codes, or patterns.


Date & DateTime Field Filters​

Applies to: Date, DateTime

Basic Operators​

GreaterThan​

After the specified date.

{
"fieldName": "StartDate",
"operator": "GreaterThan",
"values": ["2025-01-01"]
}
LessThan​

Before the specified date.

{
"fieldName": "ExpiryDate",
"operator": "LessThan",
"values": ["2025-12-31"]
}

Relative Date Filters​

Relative date filters use natural language for dynamic date ranges.

This/Last/Next Period​
This Week/Month/Quarter/Year:​
{
"fieldName": "CreatedOn",
"operator": "RelativeMatch",
"values": ["this month"]
}

Available values: "this year", "this quarter", "this month", "this week"

Last Period:​
{
"fieldName": "PurchaseDate",
"operator": "RelativeMatch",
"values": ["last quarter"]
}

Available values: "last year", "last quarter", "last month", "last week", "last day", "last hour"

Next Period:​
{
"fieldName": "RenewalDate",
"operator": "RelativeMatch",
"values": ["next month"]
}

Available values: "next year", "next quarter", "next month", "next week", "next day", "next hour"

Exact Date Values​
Today/Yesterday/Tomorrow​
{
"fieldName": "AppointmentDate",
"operator": "RelativeMatch",
"values": ["Today"]
}

Available values: "Today", "Yesterday", "Tomorrow"

Last N Periods​

Records from the last N time units.

{
"fieldName": "LastLogin",
"operator": "RelativeMatch",
"values": ["last 30 day"]
}

Format: "last {number} {period}" where period can be: year, quarter, month, week, day, hour

Examples:

  • "last 30 day" - Last 30 days
  • "last 3 month" - Last 3 months
  • "last 2 year" - Last 2 years
Next N Periods​

Records in the next N time units.

{
"fieldName": "SubscriptionExpiry",
"operator": "RelativeMatch",
"values": ["next 14 day"]
}

Format: "next {number} {period}"

Examples:

  • "next 7 day" - Next 7 days
  • "next 2 week" - Next 2 weeks
  • "next 6 month" - Next 6 months
Before/After N Periods​

Records exactly N periods before or after today

{
"fieldName": "InvoiceDate",
"operator": "RelativeMatch",
"values": ["before 30 day"]
}

Format: "before {number} {period}" or "after {number} {period}"

This N Period​

Records within a specific recent timeframe.

{
"fieldName": "ModifiedOn",
"operator": "RelativeMatch",
"values": ["this 2 week"]
}

Format: "{period}" where period can be: this week, this month, this year.

Same date, different year​

Use case: Annual recurring dates (birthdays, anniversaries)

{
"fieldName": "Birthday",
"operator": "RelativeMatch",
"values": ["same date different year"]
}

If today is January 15, find all January 15 records across all years.

Today of Year:

Use case: Same as "same date different year"

{
"fieldName": "Anniversary",
"operator": "RelativeMatch",
"values": ["Today of year"]
}

Note: Works the same as "same date different year"

Today of Month:

Use case: Same as "same day of month""

{
"fieldName": "MonthlyReport",
"operator": "RelativeMatch",
"values": ["Today of month"]
}

Exclude Date Ranges​

Use "include": false to exclude date ranges.

{
"fieldName": "CreatedOn",
"operator": "RelativeMatch",
"include": false,
"values": ["last 30 day"]
}

Excludes records from the last 30 days

Filtering by Date Components with ExactMatch​

Sometimes you want to filter by a specific part of a date (year, month, etc.) without caring about the full date.

Year​
{
"fieldName": "CreatedOn",
"operator": "ExactMatch",
"subOperator": "Year",
"values": ["2024"]
}
Quarter​
{
"fieldName": "SalesDate",
"operator": "ExactMatch",
"subOperator": "Quarter",
"values": ["1 2025"]
}

Format: "{quarter} {year}" where quarter is 1, 2, 3, or 4

Month​
{
"fieldName": "TransactionDate",
"operator": "ExactMatch",
"subOperator": "Month",
"values": ["Jan 2025"]
}

Format: "{month} {year}" where month is Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec

Week​
{
"fieldName": "WeeklyReport",
"operator": "ExactMatch",
"subOperator": "Week",
"values": ["W37 2025"]
}

Format: "{weekNumber} {year}"

Day​
{
"fieldName": "EventDate",
"operator": "ExactMatch",
"subOperator": "Day",
"values": ["15 Jan 2025"]
}

Format: "{day} {month} {year}"

DateTime​
{
"fieldName": "Timestamp",
"operator": "ExactMatch",
"subOperator": "DateTime",
"values": ["01-15-2025 14:30:00"]
}

Format: "{month}-{day}-{year} {time}"


Boolean Field Filters​

Applies to: Boolean (Yes/No, True/False checkboxes)

Boolean filtering is straightforward but has a few syntax options.

ExactMatch​

Filter by true/false values.

True:​
{
"fieldName": "IsActive",
"operator": "ExactMatch",
"values": ["true"]
}
False:​
{
"fieldName": "IsVerified",
"operator": "ExactMatch",
"values": ["false"]
}

Include Null (Empty) Values:

Use case:​
  • When a checkbox hasn't been set yet (null)
  • Optional checkboxes with no default value
  • Including "not set" in your results
{
"fieldName": "IsApproved",
"operator": "ExactMatch",
"values": ["", "true"]
}

Matches both empty/null values AND true values

EqualTo (Alternative Syntax)​

Boolean fields also support numeric notation:

True (1):​
{
"fieldName": "IsActive",
"operator": "EqualTo",
"values": ["1"]
}
False (0):​
{
"fieldName": "IsActive",
"operator": "EqualTo",
"values": ["0"]
}

Picklist & Multi-Select Filters​

Applies to: Picklist, Radio, Multipicklist, Checkbox, Tag

Single Selection Fields (Picklist, Radio)​

Use standard text operators:​
{
"fieldName": "Priority",
"operator": "EqualTo",
"values": ["High"]
}
Multiple options (OR logic):​
{
"fieldName": "Status",
"operator": "Includes",
"values": ["Open", "In Progress", "Pending"]
}

Multi-Select Fields (Multipicklist, Checkbox, Tag)​

Contains (Any Match)​

Records containing ANY of the specified values (OR logic).

{
"fieldName": "Tags",
"operator": "Contains",
"values": ["urgent", "important"]
}

Matches records with "urgent" OR "important" OR both

EqualTo (Exact Match - Single Value)​

Records with exactly one specific value selected.

{
"fieldName": "Categories",
"operator": "EqualTo",
"values": ["Marketing"]
}
EqualTo (All Match - Multiple Values)​

Records containing ALL specified values (AND logic).

{
"fieldName": "Skills",
"operator": "EqualTo",
"values": ["JavaScript", "React", "Node.js"]
}

Only matches records that have all three skills selected

ExactMatch​

Precise match of selected options.

{
"fieldName": "Permissions",
"operator": "ExactMatch",
"values": ["Read", "Write"]
}
NotContains​

Exclude records containing specific values.

{
"fieldName": "Tags",
"operator": "NotContains",
"values": ["archived"]
}

Lookup & Reference Field Filters​

Applies to: Lookup, MasterDetail

Lookup fields reference records in other tables. Filter by the ID of the referenced record.

Basic Filtering​

EqualTo​

Records linked to a specific record.

{
"fieldName": "Company",
"operator": "EqualTo",
"values": [123]
}

Where 123 is the ID of the company record

Includes​

Records linked to any of the specified records (OR logic).

{
"fieldName": "AssignedTo",
"operator": "Includes",
"values": [45, 67, 89]
}

Matches records assigned to user 45 OR 67 OR 89

ExactMatch​

Match specific reference IDs

{
"fieldName": "RelatedProject",
"operator": "ExactMatch",
"values": [301, 302]
}

Exclude specific references:

{
"fieldName": "Owner",
"operator": "ExactMatch",
"include": false,
"values": [999]
}

Filtering by Reference Field Properties​

You can filter by properties of the referenced record using subOperators.

Numeric Properties​

Filter by numeric fields in the referenced table:

{
"fieldName": "RelatedAccount",
"operator": "ExactMatch",
"subOperator": "Between",
"values": ["1000 and above"]
}

Where RelatedAccount has a numeric field you're filtering on


Advanced: Complex Logic with WhereGroups​

WhereGroups allow you to build complex queries with nested AND/OR logic.

Structure​

{
"whereGroups": [
{
"operator": "AND",
"subGroups": [
{
"operator": "OR",
"conditions": [
{ /* filter 1 */ },
{ /* filter 2 */ }
]
}
]
}
]
}

Example 1: (A OR B) AND C​

Find active customers in California OR Texas:

{
"where": [
{
"fieldName": "Status",
"operator": "EqualTo",
"values": ["Active"]
}
],
"whereGroups": [
{
"operator": "AND",
"subGroups": [
{
"operator": "OR",
"conditions": [
{
"fieldName": "State",
"operator": "EqualTo",
"values": ["California"]
},
{
"fieldName": "State",
"operator": "EqualTo",
"values": ["Texas"]
}
]
}
]
}
]
}

Logic: Status = Active AND (State = California OR State = Texas)

Example 2: (A AND B) OR (C AND D)​

Find high-value customers OR recent signups:

{
"whereGroups": [
{
"operator": "OR",
"subGroups": [
{
"operator": "AND",
"conditions": [
{
"fieldName": "TotalSpent",
"operator": "GreaterThan",
"values": [10000]
},
{
"fieldName": "Type",
"operator": "EqualTo",
"values": ["Enterprise"]
}
]
},
{
"operator": "AND",
"conditions": [
{
"fieldName": "CreatedOn",
"operator": "RelativeMatch",
"values": ["last 30 day"]
},
{
"fieldName": "Status",
"operator": "EqualTo",
"values": ["Trial"]
}
]
}
]
}
]
}

Logic: (TotalSpent > 10000 AND Type = Enterprise) OR (CreatedOn in last 30 days AND Status = Trial)

Example 3: Complex Multi-Level Logic​

Find qualified leads:

{
"whereGroups": [
{
"operator": "AND",
"subGroups": [
{
"operator": "OR",
"conditions": [
{
"fieldName": "Source",
"operator": "EqualTo",
"values": ["Website"]
},
{
"fieldName": "Source",
"operator": "EqualTo",
"values": ["Referral"]
}
]
},
{
"operator": "AND",
"conditions": [
{
"fieldName": "Score",
"operator": "GreaterThanOrEqualTo",
"values": [75]
},
{
"fieldName": "Budget",
"operator": "ExactMatch",
"subOperator": "Between",
"values": ["5000 and above"]
}
]
}
]
}
]
}

Logic: (Source = Website OR Source = Referral) AND (Score >= 75 AND Budget >= 5000)


Best Practices​

1. Start Simple​

Begin with basic where conditions before moving to complex whereGroups.

2. Use Appropriate Operators​

  • Text searches: Use Contains for partial matches, EqualTo for exact matches
  • Dates: Prefer RelativeMatch for dynamic queries ("this month" vs hardcoded dates)
  • Numbers: Use range operators (Between, GreaterThan, LessThan) for better flexibility

3. Handle Null Values​

Empty values are treated as null. To include/exclude nulls:

{
"fieldName": "Description",
"operator": "ExactMatch",
"values": ["", "value"]
}

4. Test Incrementally​

Build complex filters step-by-step:

  • Test each condition individually
  • Combine with AND logic
  • Add OR logic if needed
  • Add nested groups last

5. Performance Tips​

  • Limit the number of fields returned in the fields array
  • Use pagination for large result sets
  • Index frequently filtered fields in your Apper app

Common Use Cases​

Find Overdue Tasks​

{
"where": [
{
"fieldName": "Status",
"operator": "NotEqualTo",
"values": ["Completed"]
},
{
"fieldName": "DueDate",
"operator": "LessThan",
"values": ["2025-01-15"]
}
]
}

Find New High-Value Customers​

{
"where": [
{
"fieldName": "CreatedOn",
"operator": "RelativeMatch",
"values": ["last 90 day"]
},
{
"fieldName": "TotalPurchases",
"operator": "GreaterThan",
"values": [5000]
}
]
}

Find Expiring Subscriptions​

{
"where": [
{
"fieldName": "ExpiryDate",
"operator": "RelativeMatch",
"values": ["next 30 day"]
},
{
"fieldName": "Status",
"operator": "EqualTo",
"values": ["Active"]
}
]
}

Find Inactive Users​

{
"where": [
{
"fieldName": "LastLoginDate",
"operator": "RelativeMatch",
"include": false,
"values": ["last 90 day"]
}
]
}

Troubleshooting​

Common Issues​

Issue: Filter returns no results
Solution: Check field name spelling (case-sensitive), verify field type matches operator.

Issue: Date filters not working
Solution: Ensure date format matches field type (Date vs DateTime), use ISO 8601 format.

Issue: Lookup filters not matching
Solution: Use record IDs, not display names. Get IDs from the related table first.

Issue: Multiple conditions are not combining correctly
Solution: Remember: where uses AND logic, use whereGroups for OR logic


Quick Reference Cheat Sheet​

Text Operators​

NeedOperatorExample
Contains textContainsCompany contains "Tech"
Starts withStartsWithPhone starts with "+1"
Ends withEndsWithEmail ends with ".com"
One of many valuesIncludesStatus in ["Active", "Pending"]
None of theseExcludesType not in ["Draft", "Test"]

Number Operators​

NeedOperatorExample
Greater thanGreaterThanAmount > 1000
Less thanLessThanStock < 10
BetweenExactMatch + BetweenAge between 25 and 40
Below a valueExactMatch + BetweenPrice below 100
Above a valueExactMatch + BetweenSales 5000 and above

Date Operators​

NeedOperator + ValueExample
Current periodRelativeMatch"this month"
Last periodRelativeMatch"last quarter"
Next periodRelativeMatch"next week"
Last N daysRelativeMatch"last 30 day"
Specific dateEqualTo"2025-01-15"
Before / after a dateLessThan / GreaterThanBefore "2025-12-31"
Specific yearExactMatch + YearYear = 2024
Specific monthExactMatch + MonthMonth = Jan 2025

Boolean​

NeedOperator + ValueExample
TrueExactMatch["true"]
FalseExactMatch["false"]
True or nullExactMatch["", "true"]

Multi-Select​

NeedOperatorLogic
Has any of theseContainsOR
Has all of theseEqualTo (multiple values)AND
Has exactly theseExactMatchExact match only
Doesn't have thisNotContainsNOT

Logic Combinators​

NeedUseExample
All must matchwhere arrayA AND B AND C
Any can matchIncludes or whereGroupsA OR B OR C
Complex logicwhereGroups(A AND B) OR (C AND D)
Exclude resultsinclude: falseNOT A

Support​

For questions about filters or help with complex queries:

Need more help? Reach out to our support team via 24/5 live chat.