Using JSON objects and arrays in segments

Attributes and events contain nested JSON values—arrays, objects, and arrays of objects. You can match nested in segment conditions using JSON dot notation.

 New to JSON?

Check out our introduction to JSON and learn how you can take advantage of JSON in attributes and events.

How it works

You can store complex JSON in attributes or events, like arrays, objects, and arrays of objects. When you create segmentsA group of people who match a series of conditions. People enter and exit the segment automatically when they match or stop matching conditions., filters, or trigger conditions you can use conditions to access nested values or search within arrays for values using JSON dot notation.

You’ll use square brackets to represent an array. If you don’t provide an array index, we’ll match any item in the array (e.g. array[]). If you provide an index, we’ll match a specific position in an array. Arrays are zero-indexed, so array[0] matches the first item in the array. You’ll use dot notation to represent properties nested in objects, like purchase.price to get the price property inside of a purchase object. If purchases were an array of objects, you could use purchases[].price to match a value against any object in the purchases array.

When you create your segment, we don’t know which of your attributes and event properties are arrays, nor do we list properties nested in objects. You’ll need to know how your data is organized to fully take advantage of complex JSON in your segments, filters, etc.

 You can only use JSON customer attributes and event properties in segment conditions

You can’t use nested device attributes, collection properties, or trigger properties (from an incoming webhook or an API-triggered broadcast) in segment conditions.

Example data

On this page, we’ll consider the following sample JSON data representing a complex attribute or event data. We’ll use it to demonstrate segment matches on this page.

{
  "name": "John Smith",
  "address": {"city": "Montreal","province": "QC"}, //simple object
  "purchases": [ //array of objects
    {
      "id": 123,
      "type": "computers",
      "name": "Monitor",
      "price": 25,
      "discount": 10,
      "shipping_address": {"city": "Calgary","province": "AB"},
      "coupons_applied": [
        {
          "coupon_code": "AXXXXX",
          "discount": "10%"
        },
        {
          "coupon_code": "BXXXXX",
          "discount": "15%"
        }
      ]
    },
    {
      "id": 456,
      "type": "computers",
      "name": "Mouse",
      "price": 15,
      "shipping_address": {"city": "Edmonton","province": "AB"}
    }
  ],
  "stores_visited": ["Winnipeg","Toronto","Vancouver"], //simple string array
  "coupons_received": [5,10,20], //simple numeric array
  "children_ages": [1654099180,1654099181,1654099182], //simple timestamp array
  "lottery_tickets": //simple array of simple arrays
     [
        [1,3,5,7,9],
        [1,2,3,5,8]
  ]
}

Using JSON notation segment editor

You’ll use JSON dot notation to reference arrays or nested properties in segments.

Use square brackets to represent an array. If you don’t provide an array index, we’ll match any item in the array (e.g. array[]). If you provide an index, we’ll match a specific position in an array. Arrays are zero-indexed, so array[0] matches the first item in the array.

Using our stores_visited example:

  • stores_visited[] contains Toronto is true
  • stores_visited[0] contains Toronto is false
use an array in a segment condition
use an array in a segment condition

This works with nested arrays and arrays of objects as well. For example if we wanted to create a segment of people who used a specific coupon, we might use purchases[].coupons_applied[].coupon_code. This would search against every object within purchases for an array called coupons_applied, and then for the coupon_code for every object within coupons_applied.

You could limit the search to the first purchase with purchases[0].coupons_applied[].coupon_code.

use an array of objects in a segment condition
use an array of objects in a segment condition

Conditions traverse child properties to find a match

When you search within an object or an array, we’ll traverse the entire value until we find a match. For example, purchases[].coupons_applied[].coupon_code searches for the coupon_code key within any coupons found in purchases.

However, if you know your coupon code values are unique, you could also simply search purchases[] for your coupon code value. We’ll automatically search for a matching value in any child property of the purchases[] array.

Look for a unique value from a top-level array
Look for a unique value from a top-level array

Equals vs contains in an array

In most cases, the equals and contains conditions are functionally identical when you reference an array. Equals searches for a matching value in the array. Contains searches for a value containing the string you provide.

Using our stores_visited example data, these two statements are identical and true:

  • stores_visited[] contains Toronto
  • stores_visited[] equals Toronto

If you don’t use the array operator, contains will work but equals will not. When you don’t use the array operator, we treat the value as a string; the stringified value of stores_visited contains Toronto, but contains more characters than just that word, so it can’t equal Toronto.

  • stores_visited contains Toronto is true
  • stores_visited equals Toronto is false

Use does not exist instead of empty strings

In general, you shouldn’t send attributes or event data properties with empty strings. It’s not necessarily a problem if you do, but we don’t store customer attributesA key-value pair that you associate with a person—like their name, the date they were created in your workspace, etc. Use attributes to target people and personalize messages. with empty values, and you can’t save a segment or filter condition with an empty value.

But, if you do pass us attributes or properties with empty values—like in event data—you can segment or filter against these conditions using the exists or does not exist operators.

use the does not exist condition to check for an empty value
use the does not exist condition to check for an empty value
Copied to clipboard!