Skip to main content
Private beta. This feature is only available to some organizations right now.Request access and we’ll turn webhooks on for your organization and send you the prerelease packages. Webhooks are open source, so they work self-hosted too. APIs may change before general availability.
A filter selects which verified deliveries reach a subscriber. Each subscriber on an endpoint has its own filter, so one delivery can start one task and skip another. A delivery no subscriber takes is recorded with status FILTERED, so you can inspect it in the dashboard.

Add a filter

Set filter on the subscriber. This example accepts Stripe payment-intent events whose amount is at least 10,000:
/trigger/payment-events.ts
The same filter works on a chat.event, a channel connector, and a waiter, where it is checked after the waiter’s match. The filter is checked against the endpoint’s event type. Concrete types catch missing fields and incompatible literals. Fields typed as unknown, including values in Stripe’s default data.object, allow arbitrary non-empty field paths. Operator literals and path structure are still checked. A filter built at runtime (typed as string rather than a string literal) skips the compile-time check, and is validated when the endpoint is deployed.

Narrow a union event

When the endpoint’s event is a union, such as webhooks.stripe<Stripe.Event>(), an event.<field> == '<value>' clause selects the members whose field can hold that value. The rest of that && chain is checked against those members, and the handler’s event has their type:
/trigger/checkouts.ts
  • in [...] selects the members for any listed value, and || gives the union of its branches. Parentheses group branches as usual.
  • !=, not in, numeric comparisons, string operators, and any/all don’t narrow. Neither do null, 'null', or 0, because the server’s == also matches a null field for those values.
  • Without a type clause, a field that only some members have is accepted: an event without it never matches.
  • The narrowed type also applies to the task’s trigger payload, a chat.event action’s event and key, channel connector callbacks, and a waiter’s event. A filter built at runtime doesn’t narrow.

Check the result

Send an event and open its delivery in the dashboard. Each subscriber’s row shows whether it took the event, and a filtered subscriber shows the failed clause and its value. The provider receives the source’s accepted HTTP status (200 by default) either way.
If filter evaluation throws an exception, Trigger.dev routes the event. Filters aren’t a substitute for signature verification or validation inside your handler.

The expression language

A filter is one or more path operator value clauses combined with && and || (use parentheses to group).

Paths

A path reads from one of three namespaces:
  • event.*: the verified, parsed request body, for example event.data.object.amount.
  • header.*: an inbound request header, matched case-insensitively, for example header.x-github-event.
  • webhook.*: endpoint and delivery metadata: source, id, deliveryId, externalRef, and tenantId. The last two depend on the endpoint configuration.
Paths must have non-empty segments. event.data.amount is valid; event., event..amount, and event.amount. are rejected. Session routing keys use the same namespaces in braces ({event.data.object.customer}), and waiter match paths use them as keys ("event.data.object.metadata.orderId").

Operators

Values are strings in single quotes ('created'), numbers (10000), booleans (true), or null. Use a list of these values with in and not in.

Comparing two fields

Equality and comparison operators also accept a field path on the right-hand side:
Filter expression

Matching inside a list

any matches if at least one array element meets the condition. all requires every element to match. The path inside the parentheses is relative to each element:
Filter expression

Spacing

Separate paths, operators, and values with one space. Parentheses may touch what they enclose, as in (event.amount > 0) and any (quantity > 0). Lists and quoted strings may contain spaces (['opened', 'closed'], 'Fix the build'). These forms work with both the TypeScript validator and the deployment parser.

Filter by event type

Use the field or header your provider supplies for its event type. GitHub uses the x-github-event header:
/trigger/github-events.ts

Filtering a session route

A filter works the same way on chat.event: a delivery that doesn’t match never reaches the session.