# JSON Predicates

Provides a flexible language for expressing custom filtering of your event stream.


## Array matcher {#array-matcher}

Determines if an array contains an object that matches another criteria.


[Jump to examples ↓](#array-matcher-examples)

**One of:**

  - **`array_contains`** `object`

    The JSON Predicate.

  - **`array_contains`** `object`

    The JSON Predicate.

  - **`index`** `number`

    The specified element in the array.

    Format: `integer`


**Used in:**

- [Open an event stream]({{< ref "/developer/rest-api/connect/operations/event-stream/" >}}#openeventstream)

**Examples**

*Example find only push body objects with the campaign category "spring_sale"*

```json
{
  "filters": {
    "types": ["PUSH_BODY"],
    "predicates": {
      "key": "categories",
      "scope": ["body", "campaigns"],
      "value": {
        "array_contains": { "value": {"equals": "spring_sale"} }
      }
    }
  }
}  

```

---

## Equals matcher {#equals-matcher}

Determines if the value matches exactly.


[Jump to examples ↓](#equals-matcher-examples)

- **`equals`** `object`
  **One of:**

  - `boolean`
  - `number`
  - `string`
  - `array<oneOf>`


**Used in:**

- [Open an event stream]({{< ref "/developer/rest-api/connect/operations/event-stream/" >}}#openeventstream)

**Examples**

*Example find SMS delivery errors with equals matcher*

```json
{
  "filters": [
    {
      "device_types": ["sms"],
      "types": ["CUSTOM"],
      "predicates": [
        {
          "and": [
            {
              "key": "interaction_type",
              "scope": ["body"],
              "value": {"equals": "delivery_report"}
            },
            {
              "not": {
                "key": "name",
                "scope": ["body"],
                "value": {"equals": "delivered"}
              }
            }
          ]
        }
      ]
    }
  ]
}

```

---

## JSON Predicate {#json-predicate}

[Standard request filters](/docs/developer/rest-api/connect/schemas/others/#eventsrequestfilters) check specific, predefined fields in your events and remove any events that don't match the criteria for that field. For example, the `device_types` filter always checks the `device_type` sub-field of the device object. In contrast, you can use JSON Predicates to examine any part of an event, providing more flexibility than the standard filters. You can also combine multiple JSON Predicate objects to create complex filtering logic for your event stream.

The simplest JSON Predicate examines a single key and provides a `matcher` object that can be applied to the value at that key. To filter a stream for only [Open events](/docs/developer/rest-api/connect/schemas/events/#open), you could use the standard filter `types`: `filters:{"types": ["OPEN"]}`. However, to achieve this with a JSON Predicate, you would use `filters:{"predicates":{"key":"type", "value": {"equals": "OPEN"}}}`. This checks the value of the top-level key `type` to see if it's exactly "OPEN". It also serves as a foundational step for constructing more intricate filters.

To filter for only Android events, you could use the `device_type` filter, but a JSON Predicate allows for more complex combinations later. Since the device type key doesn't appear at the top level of the event, you'll need to provide a scope, like this `filters:{"predicates":{"scope":["device"], "key":"device_type", "value": {"equals": "ANDROID"}}}`. This configuration targets the `device_type` key within the `device` object, checking if its value is "ANDROID".

You can combine the two filters to see only Opens from Android devices: `filters:{"predicates":{"and":[
    {"scope":["device"], "key":"device_type", "value": {"equals": "ANDROID"}},
    {"key":"type", "value": {"equals": "OPEN"}}
]}}`

We also have matchers other than `equals`. Numeric `at_least` and `at_most` can be combined to create ranges. `version_matches` uses [Ivy syntax](https://ant.apache.org/ivy/history/2.1.0/settings/version-matchers.html) to match version numbers. `is_present` determines if there's any value at a given key. `array_contains` can be combined with another predicate to determine if an array contains an object that matches another criteria.



[Jump to examples ↓](#json-predicate-examples)

**One of:**

- **And** `object`

  - **`and`** `array` <[JSON Predicate]({{< ref "/developer/rest-api/connect/schemas/json-predicates/" >}}#json_predicate)>
- **Or** `object`

  - **`or`** `array` <[JSON Predicate]({{< ref "/developer/rest-api/connect/schemas/json-predicates/" >}}#json_predicate)>
- **Not** `object`

  - **`not`** `object`

    The JSON Predicate.

- **Value** `object`

  - **`key`** `string` **REQUIRED**

    The name of the value being matched.

  - **`scope`** `object`

    The path into a JSON object.

    **One of:**

    - `string`
    - `array<string>`

  - **`value`** `object` **REQUIRED**

    The value you are filtering for in the JSON Predicate.

    **One of:**

    - [Array matcher]({{< ref "/developer/rest-api/connect/schemas/json-predicates/" >}}#array_matcher)

      Determines if an array contains an object that matches another criteria.


    - [Equals matcher]({{< ref "/developer/rest-api/connect/schemas/json-predicates/" >}}#equals_matcher)

      Determines if the value matches exactly.


    - [Numeric matcher]({{< ref "/developer/rest-api/connect/schemas/json-predicates/" >}}#numeric_matcher)

      Determines if a number matches or is within range of the criteria.


    - [Presence matcher]({{< ref "/developer/rest-api/connect/schemas/json-predicates/" >}}#presence_matcher)

      Determines if there is any value for a given key.


    - [Version matcher]({{< ref "/developer/rest-api/connect/schemas/json-predicates/" >}}#version_matcher)

      Determines if version numbers match.




**Used in:**

- [Open an event stream]({{< ref "/developer/rest-api/connect/operations/event-stream/" >}}#openeventstream)

**Examples**

*Example JSON Predicate to filter the stream to only Android Open events*

```json
{
  "filters": {
    "predicates": {
      "and": [
        {
          "scope": ["device"],
          "key": "device_type",
          "value": {"equals": "ANDROID"}
        },
        { "key": "type", "value": {"equals": "OPEN"} }
      ]
    }
  }
}

```

---

## Numeric matcher {#numeric-matcher}

Determines if a number matches or is within range of the criteria.


[Jump to examples ↓](#numeric-matcher-examples)

**One of:**

  - **`at_least`** `number`
  - **`at_most`** `number`
  - **`at_least`** `number`
  - **`at_most`** `number`

**Used in:**

- [Open an event stream]({{< ref "/developer/rest-api/connect/operations/event-stream/" >}}#openeventstream)

**Examples**

*Example find custom events with name "purchase" and a "value" of at least 100*

```json
{
  "filters": [
    {
      "types": ["CUSTOM"],
      "predicates": [
        {
          "and": [
            { "key": "value",
              "scope": ["body"],
              "value": {"at_least": 100}
            },
            {
              "key": "name",
              "scope": ["body"],
              "value": {"equals": "purchase"}
            }
          ]
        }
      ]
    }
  ]
}

```

---

## Presence matcher {#presence-matcher}

Determines if there is any value for a given key.


[Jump to examples ↓](#presence-matcher-examples)

- **`is_present`** `boolean`

  If `true`, the value should be  present. If `false`, the value should not be present.


**Used in:**

- [Open an event stream]({{< ref "/developer/rest-api/connect/operations/event-stream/" >}}#openeventstream)

**Examples**

*Example find only direct open events*

```json
{
  "filters": {
    "types": ["OPEN"],
    "predicates": {
      "key": "triggering_push",
      "scope": ["body"],
      "value": {"is_present": true}
    }
  }
}

```

---

## Version matcher {#version-matcher}

Determines if version numbers match.


[Jump to examples ↓](#version-matcher-examples)

- **`version_matches`** `string`

  The version number string to be matched. Format strings using [Ivy syntax](https://ant.apache.org/ivy/history/2.1.0/settings/version-matchers.html).


**Used in:**

- [Open an event stream]({{< ref "/developer/rest-api/connect/operations/event-stream/" >}}#openeventstream)

**Examples**

*Example find custom events of type "purchase" performed by Android users on app versions between 18.4.1 and 19.2.3*

```json
{
  "filters": [
    {
      "device_types": ["android"],
      "types": ["CUSTOM"],
      "predicates": [
        {
          "and": [
            {
              "key": "app_version",
              "scope": ["device", "attributes"],
              "value": {"version_matches": "[18.4.1,19.2.3]"}
            },
            {
              "key": "name",
              "scope": ["body"],
              "value": {"equals": "purchase"}
            }
          ]
        }
      ]
    }
  ]
}

```

---

