Filter Operators
When building segments, each filter uses an operator to define how the contact's data is compared against your value. Below is a reference of all 22 available operators.
Property Operators
These operators compare a contact field or custom property against a value you provide.
| Operator | Description | Example | Matches |
|---|---|---|---|
| is | Exact match (equals) | product_type is Standard | Contacts whose product type is exactly "Standard" |
| is_not | Does not equal | product_type is_not Unsub | Contacts whose product type is anything except "Unsub" |
| in | Matches any value in a list | product_type in Standard, Premium | Contacts whose product type is either "Standard" or "Premium" |
| not_in | Does not match any value in a list | product_type not_in Unsub, Inactive | Contacts whose product type is neither "Unsub" nor "Inactive" |
| contains | Text includes a substring | email contains @gmail.com | Contacts whose email contains "@gmail.com" |
| not_contains | Text does not include a substring | email not_contains test | Contacts whose email does not contain "test" |
| starts_with | Text begins with a prefix | phone starts_with +65 | Contacts whose phone number starts with "+65" |
| ends_with | Text ends with a suffix | email ends_with @acme.com | Contacts whose email ends with "@acme.com" |
| greater_than | Numeric comparison (strictly greater) | properties.age greater_than 30 | Contacts older than 30 |
| less_than | Numeric comparison (strictly less) | properties.age less_than 25 | Contacts younger than 25 |
| gte | Greater than or equal | properties.order_count gte 5 | Contacts with 5 or more orders |
| lte | Less than or equal | properties.order_count lte 20 | Contacts with 20 or fewer orders |
| between | Within a range (inclusive) | properties.order_count between 5, 20 | Contacts with 5 to 20 orders |
| exists | Field has a value (is not null) | phone exists | Contacts who have a phone number on file |
| not_exists | Field is null or missing | properties.company not_exists | Contacts who have no company set |
| is_empty | Field is null or an empty string | phone is_empty | Contacts whose phone field is missing or blank |
| is_not_empty | Field has a non-empty value | email is_not_empty | Contacts who have an email address that is not blank |
The contains, not_contains, starts_with, and ends_with operators are case-insensitive, so @Gmail.com and @gmail.com will match the same contacts.
exists vs is_not_empty vs is_empty: exists checks that the field is not null (the field has been set at all). is_not_empty checks that the field is neither null nor an empty string. is_empty checks that the field is null OR an empty string. A field can exist but be empty -- use whichever is appropriate for your data.
Date Operators
These operators work specifically with date and timestamp fields like created_at.
| Operator | Description | Example | Matches |
|---|---|---|---|
| date_before | Date is before a specific date | created_at date_before 2026-01-01 | Contacts created before January 1, 2026 |
| date_after | Date is after a specific date | created_at date_after 2026-01-01 | Contacts created after January 1, 2026 |
| date_in_last | Date is within the last N days | created_at date_in_last 30 | Contacts created in the last 30 days |
Use date_in_last for relative time ranges that automatically adjust. "Contacts created in the last 7 days" will always give you the most recent week without needing to update the date value.
Behavioral Operators
These operators check whether a contact has performed (or not performed) specific events.
| Operator | Description | Example | Matches |
|---|---|---|---|
| has_executed | Contact has performed this event at least once | has_executed purchase_complete | Contacts who have completed at least one purchase |
| has_not_executed | Contact has never performed this event | has_not_executed onboarding_complete | Contacts who have never completed onboarding |
Behavioral operators are great for targeting contacts based on actions they have or haven't taken. Combine them with property operators for precise audience targeting.
Operator Compatibility
Not all operators work with all data types. Here's a quick compatibility guide:
| Operator | Text | Numbers | Dates | Boolean |
|---|---|---|---|---|
| is | Yes | Yes | Yes | Yes |
| is_not | Yes | Yes | Yes | Yes |
| in | Yes | Yes | -- | -- |
| not_in | Yes | Yes | -- | -- |
| contains | Yes | -- | -- | -- |
| not_contains | Yes | -- | -- | -- |
| starts_with | Yes | -- | -- | -- |
| ends_with | Yes | -- | -- | -- |
| greater_than | -- | Yes | -- | -- |
| less_than | -- | Yes | -- | -- |
| gte | -- | Yes | -- | -- |
| lte | -- | Yes | -- | -- |
| between | -- | Yes | Yes | -- |
| exists | Yes | Yes | Yes | Yes |
| not_exists | Yes | Yes | Yes | Yes |
| is_empty | Yes | -- | -- | -- |
| is_not_empty | Yes | -- | -- | -- |
| date_before | -- | -- | Yes | -- |
| date_after | -- | -- | Yes | -- |
| date_in_last | -- | -- | Yes | -- |
Tips for Choosing Operators
- Use is / is_not when you know the exact value.
- Use in / not_in when you want to match against multiple possible values at once.
- Use contains / not_contains when you need partial text matching (e.g., email domains).
- Use starts_with / ends_with for prefix or suffix matching (e.g., phone country codes, email domains).
- Use gte / lte when the boundary value should be included (e.g., "age 18 or older"). Use greater_than / less_than when it should not.
- Use exists / not_exists to find contacts with missing data (useful for data quality checks).
- Use is_empty / is_not_empty to distinguish between null fields and blank strings.
- Use date_before / date_after for fixed date ranges and date_in_last for rolling time windows.
- Use has_executed / has_not_executed to create behavioral segments (e.g., "signed up but never purchased").
- Use between for range queries on numbers or dates (e.g., "contacts with 5 to 20 orders").
Looking for the API?
If you prefer to build segment filters programmatically, see the Segments API Reference for the filter DSL format.