Filters & expressions

Updated May 02, 2026

Overview

A filter is an ExpressionLanguage expression attached to a destination. When a webhook arrives at the parent endpoint, Splithook evaluates the expression. Only webhooks where the result is true are forwarded to that destination.

Filters are optional. An empty filter means "forward everything".

Variables

Variable Type Description
provider string Auto-detected provider: 'stripe', 'github', 'shopify', 'twilio', 'svix', 'unknown'
event_type string Auto-detected event type, e.g. 'charge.failed', 'push', 'unknown'
method string HTTP method, always 'POST' in practice
headers map All request headers, keys lowercased
body map Parsed JSON body. Nested access via dot notation.

body is null-safe: accessing a missing key returns null rather than throwing.

Operators

Comparison

body.amount > 1000
body.status == 'active'
body.livemode != false
body.data.object.amount >= 5000

Boolean logic

provider == 'stripe' and body.livemode
event_type == 'charge.failed' or event_type == 'charge.refunded'
not body.test_mode

Membership

body.status in ['failed', 'errored', 'blocked']
event_type not in ['ping', 'test']

Regex

body.type matches '^charge\.'
event_type matches '^(payment_intent|charge)\.'
headers['x-github-event'] matches 'pull_request'

Null checks

body.metadata != null
body.data.object.dispute == null

String operations

body.email ends with '@acme.com'
body.description starts with 'Invoice'

Practical examples

Only Stripe production events:

provider == 'stripe' and body.livemode == true

Only failed charges over €50:

body.type == 'charge.failed' and body.amount > 5000

GitHub push events to main:

event_type == 'push' and body.ref == 'refs/heads/main'

Shopify paid orders:

event_type == 'orders/paid'

Everything except pings:

event_type != 'ping'

Stripe events for a specific customer:

provider == 'stripe' and body.data.object.customer == 'cus_Nf3XsxxxxxxxxxxxxxxS'

Testing a filter

The destination editor runs your filter expression against the last 100 captured webhooks before you save. Matching events are highlighted green, non-matching are dimmed. This turns filter writing from guesswork into a single click.

Error handling

If the filter expression throws at evaluation time (malformed expression, type mismatch), the event is not forwarded to that destination. The error is recorded in the ReplayLog with the message filter_evaluation_failed.

Fix the filter expression in the destination editor and replay the missed events from the Replay Log.

Performance

Filters are evaluated in the async forwarding worker, not on the capture hot path. A slow or complex filter does not affect how quickly your provider gets a 200 OK back from Splithook.