Segments: Build Smart Contact Segments
Build smart subsets of your contact list with Keila using contact metadata or custom data.These subsets are called Segments.
You can either use the visual editor to combine conditions, or build more complex segments with the query editor.
 Keila Query Language
The Keila Query Language is inspired by MongoDB’s Query Documents and is fully valid JSON.
The following operators are supported:
match
The simplest operator is the match operator. It matches either exact values or exact elements in an array.
Examples
Match an exact value:
{ "email": "joe@example.com" }
{ "data.age": 30 }
Match an array that contains an exact value:
{ "data.tags": "rocket-scientist" }
$and
The $and operator allows the combination of multiple conditions with a logical AND.
This means that all conditions need to be true in order to have a match.
Example
Match contacts that have both the rocket-scientist and book-enthusiast tag.
Contacts that have only one of the two are not matched.
{
  "$and": [
    { "data.tags": "rocket-scientist" },
    { "data.tags": "book-enthusiast" }
  ]
}
$or
The $or operator allows the combination of multiple conditions with a logical OR.
This means that at least one condition needs to be true in order to have a match.
Example
Match contacts that have at least one of the rocket-scientist and book-enthusiast tags.
Contacts that have both tags are also matched.
{
  "$or": [
    { "data.tags": "rocket-scientist" },
    { "data.tags": "book-enthusiast" }
  ]
}
$not
The $not operator allows the negation of a conditoin.
Example
Match contacts that don’t have the rocket-scientist tag.
{
  "$not": { "data.tags": "rocket-scientist" }
}
$like
The $like operator is similar to the match operator but allows the use of % as
a wildcard.
Examples
Match all contacts with an email address that ends in @keila.io:
{ "email": { "$like": "%@keila.io" } }
Match all contacts with a first name that contains the letter a:
{ "first_name": { "$like": "%a%" } }
$lt, $lte, $gt, $gte
$lt (lesser than), $lte (lesser than or equal to), $gt (greater than), and
$gte (greater than or equal to) are relative comparison operators.
Example
Match all contacts that were added before January 1 2022:
{ "inserted_at": { "$lt": "2022-01-01T00:00:00Z" } }
$empty
The $empty operator checks if a field is empty. The following values are considered empty:
null- empty string (
"") - empty list  (
[]) - empty object  (
{}). - unset values are also considered empty.
 
Examples
Match all contacts that don’t have a first name:
{ "first_name": { "$empty": true } }
Match all contacts that have a custom field:
{ "data.custom_field": { "$empty": false } }
Message-based Segmentation
You can create segments based on how contacts interact with your campaigns using the messages field. This allows you to target contacts who have received, opened, or clicked specific campaigns.
The following filters are available for the messages field:
campaign_id: The ID of the campaign. If omitted, the contact will be included in the segment if any campaign matches the other criteria.opened_at: The date and time the contact opened the campaign.clicked_at: The date and time the contact clicked a link in the campaign.bounced_at: The date and time the contact bounced the campaign.complaint_received_at: The date and time a complaint was received about the campaign.unsubscribed_at: The date and time a contact unsubscribed from the campaign.
Examples
Match contacts who received a specific campaign:
{ "messages": { "campaign_id": "your-campaign-id" } }
Match contacts who opened a campaign:
{
  "messages": {
    "campaign_id": "your-campaign-id",
    "opened_at": { "$empty": false }
  }
}
Match contacts who clicked a link in a campaign:
{
  "messages": {
    "campaign_id": "your-campaign-id",
    "clicked_at": { "$empty": false }
  }
}
Matching contacts who have not interacted with campaigns
If you want to match all contacts who have not interacted with a campaign, including those who have not received it, use the $not operator:
{
  "$not": {
    "messages": {
      "campaign_id": "your-campaign-id",
      "opened_at": { "$empty": false }
    }
  }
}
If you only want to match contacts who haven’t interacted but did receive the campaign, the $empty operator is sufficient:
{
  "messages": {
    "campaign_id": "your-campaign-id",
    "opened_at": { "$empty": true }
  }
}