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
}
- 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" ArrayWhat 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"] }
]
}
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 Want | Use This |
|---|---|
| Active customers in California | where (both conditions must be true) |
| Customers in California or Texas | whereGroups (either state can match) |
| Active customers in California or Texas | Both → 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… | Operator | Example |
|---|---|---|
| Text Searches | ||
| Contains this text | Contains | Name contains "Tech" |
| Doesn’t contain this text | NotContains | Email doesn’t contain "spam" |
| Starts with this text | StartsWith | Phone starts with "+1" |
| Ends with this text | EndsWith | Website ends with ".com" |
| Is one of several values | Includes | Status in ["Active", "Pending"] |
| Is none of several values | Excludes | Type not in ["Draft", "Archived"] |
| Numerical Comparisons | ||
| Is greater than | GreaterThan | Amount > 1000 |
| Is less than | LessThan | Stock < 10 |
| Is at least (≥) | GreaterThanOrEqualTo | Score ≥ 75 |
| Is at most (≤) | LessThanOrEqualTo | Age ≤ 65 |
| Is between two numbers | ExactMatch + Between | Price between 50 and 100 |
| Date Comparisons | ||
| Is in this time period | RelativeMatch | CreatedOn in "this month" |
| Is a specific date | EqualTo or ExactMatch | Date = "2025-01-15" |
| Is before / after a date | LessThan / GreaterThan | DueDate < "2025-12-31" |
"I need to combine multiple conditions..."
| You Want | Use This | Example Logic |
|---|---|---|
| All conditions must be true | where array | A AND B AND C |
| Any condition can be true | Includes or whereGroups | A OR B OR C |
| Complex nested logic | whereGroups | (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"]
}
- "TechCorp"
- "FinTech Solutions"
- "Advanced Technologies"
- "tech startup" (case-insensitive)
- "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
{
"fieldName": "Status",
"operator": "ExactMatch",
"include": true,
"values": ["Active", "Pending"]
}
{
"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.
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"
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
Containsfor partial matches,EqualTofor exact matches - Dates: Prefer
RelativeMatchfor 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
fieldsarray - 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
| Need | Operator | Example |
|---|---|---|
| Contains text | Contains | Company contains "Tech" |
| Starts with | StartsWith | Phone starts with "+1" |
| Ends with | EndsWith | Email ends with ".com" |
| One of many values | Includes | Status in ["Active", "Pending"] |
| None of these | Excludes | Type not in ["Draft", "Test"] |
Number Operators
| Need | Operator | Example |
|---|---|---|
| Greater than | GreaterThan | Amount > 1000 |
| Less than | LessThan | Stock < 10 |
| Between | ExactMatch + Between | Age between 25 and 40 |
| Below a value | ExactMatch + Between | Price below 100 |
| Above a value | ExactMatch + Between | Sales 5000 and above |
Date Operators
| Need | Operator + Value | Example |
|---|---|---|
| Current period | RelativeMatch | "this month" |
| Last period | RelativeMatch | "last quarter" |
| Next period | RelativeMatch | "next week" |
| Last N days | RelativeMatch | "last 30 day" |
| Specific date | EqualTo | "2025-01-15" |
| Before / after a date | LessThan / GreaterThan | Before "2025-12-31" |
| Specific year | ExactMatch + Year | Year = 2024 |
| Specific month | ExactMatch + Month | Month = Jan 2025 |
Boolean
| Need | Operator + Value | Example |
|---|---|---|
| True | ExactMatch | ["true"] |
| False | ExactMatch | ["false"] |
| True or null | ExactMatch | ["", "true"] |
Multi-Select
| Need | Operator | Logic |
|---|---|---|
| Has any of these | Contains | OR |
| Has all of these | EqualTo (multiple values) | AND |
| Has exactly these | ExactMatch | Exact match only |
| Doesn't have this | NotContains | NOT |
Logic Combinators
| Need | Use | Example |
|---|---|---|
| All must match | where array | A AND B AND C |
| Any can match | Includes or whereGroups | A OR B OR C |
| Complex logic | whereGroups | (A AND B) OR (C AND D) |
| Exclude results | include: false | NOT A |
Support
For questions about filters or help with complex queries:
- Email: [email protected]
Need more help? Reach out to our support team via 24/5 live chat.