Event Filters
Filters allow you to control which events are delivered by evaluating conditions against the event's headers and payload body. Filtered events are stored with a filtered status and are not delivered to any destination.
How Filters Work
Filters are configured per endpoint (not per destination). They are evaluated during ingress, before any delivery jobs are created.
Filter Groups
Filters are organized into groups. Each group contains one or more conditions and a logic mode:
- AND — all conditions in the group must match
- OR — at least one condition in the group must match
Group Evaluation
Groups are combined with OR logic: an event passes if any enabled group matches.
If no filter groups are defined for an endpoint, all events pass (no filtering occurs).
Group 1 (AND): condition A AND condition B
Group 2 (OR): condition C OR condition D
Event passes if: (A AND B) OR (C OR D)
Filter Conditions
Each condition evaluates a field from the event against a value using an operator.
Field Paths
| Prefix | Description | Example |
|---|---|---|
header.<name> | Request header (case-insensitive) | header.X-GitHub-Event |
body.<path> | JSON body field (dot-notation) | body.action, body.repository.private |
Nested fields use dot notation: body.pull_request.head.ref
Operators
| Operator | Description | Example |
|---|---|---|
eq | Field equals value | body.action eq "push" |
neq | Field does not equal value | body.action neq "deleted" |
contains | Field contains substring | body.ref contains "main" |
not_contains | Field does not contain substring | body.ref not_contains "test" |
includes | Field equals one of a comma-separated list of values | header.X-GitHub-Event includes "push, create, delete" |
exists | Field exists and is non-empty | header.X-GitHub-Event exists |
not_exists | Field does not exist or is empty | body.draft not_exists |
regex | Field matches regular expression | body.ref regex "refs/heads/(main|develop)" |
Examples
Only accept push events to the main branch
Group (AND):
- header.X-GitHub-Event eq "push"
- body.ref eq "refs/heads/main"
Accept push or pull_request events
Group (AND):
- header.X-GitHub-Event includes "push, pull_request"
Accept push or pull_request events (using OR group)
Group (OR):
- header.X-GitHub-Event eq "push"
- header.X-GitHub-Event eq "pull_request"
Accept all events except draft PRs
Group (AND):
- header.X-GitHub-Event exists
- body.pull_request.draft neq "true"
Complex: accept pushes to main OR non-draft PRs
Group 1 (AND):
- header.X-GitHub-Event eq "push"
- body.ref eq "refs/heads/main"
Group 2 (AND):
- header.X-GitHub-Event eq "pull_request"
- body.pull_request.draft neq "true"
Event passes if it matches Group 1 OR Group 2.
Reusable Filters
In addition to inline filter groups defined directly on a source, you can create named filters at the project level and attach them to multiple sources.
Named filters work exactly like inline filter groups but are managed from the Filters sidebar page and reused across sources without duplicating conditions.
Creating a Named Filter
- Open the Filters section in the sidebar.
- Click Create Filter.
- Enter a name, choose a logic mode (AND or OR) and an action (allow or block).
- Add conditions using the same field paths and operators as inline filters.
- Use the Test panel to verify the filter against an example payload.
Attaching to a Source
- Open a source from the Sources page.
- Expand the Filters section and click Attach Filter.
- Select a named filter from the project's filter list.
- The attached filter appears alongside any inline filter groups. Use the toggle to enable or disable it per source without detaching it.
Evaluation
Named filters (attached and enabled) are evaluated together with the source's inline filter groups. Block groups from all sources are checked first; allow groups are checked next. An event must not match any block group and must match at least one allow group (if any exist) to be delivered.
Filter vs. Destination Event Types
Filters and destination event type lists serve different purposes:
| Feature | Filters | Destination Event Types |
|---|---|---|
| Scope | Per endpoint | Per destination |
| Timing | Before delivery queue | During fan-out |
| Complexity | Field conditions with operators | Simple include list |
| Blocked events | Stored as filtered, visible in event history | Not delivered, no record |
| Use case | Complex conditional logic | Simple event type routing |