Filtering Webhook Events

Hookdeck supports filtering the webhooks events that are processed and sent to your destination. The two reasons that you want to add filters to a webhook connections are:

  • Manage how you route your webhooks
  • Specify exactly what you want to receive (which also means avoiding "noisy" webhooks)

Filters can be applied to the request's Headers, Body, Query and Path for maximum flexibility and use a JSON filtering syntax.

Set or Update Filters

Filters are defined on a Webhook Connection. You can add, edit, or update your filter within the UI by clicking filter in a Ruleset or Custom Rules.

Create or Update filters

Within the modal, on the left side, you'll have a reference of the last event for that connection, and on the right, a JSON editor to enter your filter.

You can add filters for both the Body, the Headers, the Query, and/or the Path.

Once you have edited your filter, you can select Test Filter to test your filter against the latest event to verify the result is what you intended.

Example filter to receive only 'issues' webhook type from Github

Create or Update filters

Once a filter is active, the filter icon will appear on the connection.

Viewing active filters

You can version control your filters by creating or updating your connection from your server or CD & CI pipeline with the Admin API.

Filter Syntax

Filters support JSON or raw string boolean number and null .

For example, this event would be filtered

// Event request body
false;
// Filters
false;

JSON filter supports matching on any value (string number boolean null), on nested objects, and on arrays.

Simple Primitives

For example, you can also use the filter to events of only a given type.

{
  "type": "order/created",
  "order": {
    "id": 123
  }
}
{
  "type": "order/created"
}

Nested Objects

For example, if you wanted to receive all events where the product inventory is 0, you would:

{
  "product": {
    "title": "A product",
    "inventory": 0
  }
}
{
  "product": {
    "inventory": 0
  }
}

Arrays

Arrays are always matched partially. It's effectively the same as contains

{
  "product": {
    "title": "Gift Card",
    "tags": ["gift", "something"]
  }
}
{
  "product": {
    "tags": "gift"
  }
}

You can also match multiple items (they must all be contained)

{
  "product": {
    "title": "Gift Card",
    "tags": ["gift", "something", "another"]
  }
}
{
  "product": {
    "tags": ["gift", "something"]
  }
}

Or even nested objects

{
  "order": {
    "id": 123,
    "items": [
      {
        "id": 456,
        "title": "My product"
      }
    ]
  }
}
{
  "order": {
    "items": {
      "id": 456
    }
  }
}

To match on a string that is not part of an object structure (for instance to set a filter on a path), simply consider the string to be at the root of your filter:

{
  "$in": "/path"
}

would match:

"/path/test"

Operators

Sometimes you need more than a simple equal matching. Our syntax support different operators to allow for more complex matching strategies.

Operators can be used as an object instead of the matching value.

{
  "product": {
    "title": "A product",
    "inventory": 5
  }
}
{
  "product": {
    "inventory": {
      "$lte": 10
    }
  }
}

All operators

OperatorSupported TypeDescription
$gtenumber, stringGreater than or equal to
$gtnumber, stringGreater than
$ltnumber, stringLess than
$ltenumber, stringLess than or equal to
$eqarray, number, object, stringEqual (or deep equal)
$neqarray, number, object, stringNot Equal (or deep not equal)
$inarray, stringContains
$ninarray, stringDoes not contain
$startsWithstringStarts with text
$orarrayArray of conditions to match
$andarrayArray of conditions to match
$ref<field>Reference a field

$or / $and Operator

$or and $and are a special operator to evaluate match with an array of conditions. For the match to be true, only one of the condition needs to match. The array of condition can contain any other valid schema supported.

For example this payload

{
  "product": {
    "title": "A product",
    "inventory": 5
  }
}

would be matched by

{
  "product": {
    "inventory": {
      "$or": [1, 5]
    }
  }
}

While this one

{
  "hello": "world"
}

wouldn't be matched by

{
  "$or": [
    {  "hello": "johny"}
    {  "hello": "mark"},
  ]
}

References

The reference $ref is a special operator to reference other values in your JSON input when evaluating match. The reference input must be a string representing the value path. For example using this JSON input:

{
  "type": "example",
  "nested_object": {
    "hello": "world",
    "array": [1, 2, 3]
  }
}

The given string would reference those values:

type = "example"

nested_object.hello = "world"

nested_object.array[1] = 1

nested_object.array[$index] = 1, 2 or 3 depending on the current index

The following example would be a match:

{
  "updated_at": "2020-04-20",
  "created_at": "2020-04-20"
}
{
  "updated_at": {
    "$ref": "created_at"
  }
}

You can also reference the current array index instead of a specific index with $index. You can have multiple $index in your reference if you are dealing with nested arrays.

{
  "variants": [
    { "updated_at": "2020-05-20", "created_at": "2020-04-20" },
    { "updated_at": "2020-04-20", "created_at": "2020-04-20" }
  ]
}
{
  "variants": {
    "updated_at": {
      "$ref": "variants[$index].created_at",
    },
  },
};

A reference can also be used in conjuction with other operators

{
  "inventory": 0,
  "old_inventory": 10
}
{
  "inventory": {
    "$lte": { "$ref": "old_inventory" }
  }
}