Features

Destination Filters

Destination filters allow tenants to selectively receive only events that match specific criteria. Instead of receiving all events for subscribed topics, a destination can define filters to route events based on their properties.

Overview

When an event is published, Outpost evaluates each destination's filter against the event. A destination receives an event only if:

  1. The destination is enabled
  2. The event's topic matches one of the destination's subscribed topics
  3. The event matches the destination's filter (or no filter is defined)

Filters are optional. Destinations without filters receive all events matching their subscribed topics.

Event Structure

Events have five top-level properties that can be filtered:

PropertyDescription
idThe event ID
topicThe event topic
timeEvent timestamp (RFC 3339 format)
metadataAdditional event information
dataThe event payload

Your filter should specify one or more of these at the top level:

{ "topic": "order.created", "data": { "status": "paid" }, "metadata": { "source": "api" } }
json

Exact Match

Specify the field path and value to match:

{ "data": { "status": "paid" } }
json

Multiple conditions are combined with AND logic:

{ "data": { "status": "paid", "currency": "usd" } }
json

Nested objects are supported:

{ "data": { "customer": { "tier": "premium" } } }
json

Arrays

Arrays match if they contain the specified value:

{ "data": { "tags": "urgent" } }
json

This matches events like: { "tags": ["urgent", "support"] }

Operators

Use operators for complex matching.

Comparison Operators

OperatorDescription
$eqEquals
$neqNot equals
$gtGreater than
$gteGreater or equal
$ltLess than
$lteLess or equal

Match orders over $100:

{ "data": { "amount": { "$gte": 100 } } }
json

Multiple operators on the same field are combined with AND:

{ "data": { "amount": { "$gte": 100, "$lt": 500 } } }
json

Membership Operators

OperatorDescription
$inValue in array, or substring match
$ninValue not in array

Match specific statuses:

{ "data": { "status": { "$in": ["pending", "processing", "completed"] } } }
json

String Operators

OperatorDescription
$startsWithString starts with
$endsWithString ends with

Match emails ending with a domain:

{ "data": { "email": { "$endsWith": "@example.com" } } }
json

Field Existence Operator

OperatorDescription
$existField exists (true) or doesn't (false)

Check if a field exists:

{ "data": { "discount_code": { "$exist": true } } }
json

Check if a field doesn't exist:

{ "data": { "deleted_at": { "$exist": false } } }
json

Logical Operators

$or - Match any condition

{ "$or": [ { "data": { "status": "paid" } }, { "data": { "status": "shipped" } } ] }
json

$and - Match all conditions (explicit)

While multiple conditions are implicitly ANDed, $and is useful when you need to apply multiple conditions that can't be nested together:

{ "$and": [ { "data": { "status": "active" } }, { "data": { "amount": { "$gte": 100 } } } ] }
json

$not - Negate a condition

{ "data": { "status": { "$not": { "$in": ["cancelled", "refunded"] } } } }
json

Common Examples

Filter by Metadata

Route events based on source:

{ "metadata": { "source": "api" } }
json

Filter by Time Range

Match events within a specific time window:

{ "time": { "$gte": "2025-01-01T00:00:00Z", "$lt": "2025-02-01T00:00:00Z" } }
json

Filter by Numeric Value

Process only high-value orders:

{ "data": { "amount": { "$gte": 1000 } } }
json

API Usage

Filters are set when creating or updating a destination via the filter field:

curl --location 'https://<OUTPOST_API_URL>/api/v1/<TENANT_ID>/destinations' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer <API_KEY>' \ --data '{ "type": "webhook", "topics": ["orders"], "config": { "url": "https://example.test/webhooks" }, "filter": { "data": { "status": { "$in": ["paid", "shipped"] } } } }'
sh

To remove a filter from a destination, set the filter field to an empty object:

curl --location --request PATCH 'https://<OUTPOST_API_URL>/api/v1/<TENANT_ID>/destinations/<DESTINATION_ID>' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer <API_KEY>' \ --data '{ "filter": {} }'
sh

Portal Configuration

To enable destination filters in the tenant portal UI, set the PORTAL_ENABLE_DESTINATION_FILTER environment variable to true.