Skip to main content
Most webhook triggers don’t need anything below: describe the condition in plain language and Dust writes the filter for you. This page is only for custom webhooks, which have no connected provider, so Dust can’t generate a filter automatically and you write one yourself.

Most webhooks: describe it in plain language

For a trigger on a built-in source (GitHub, Jira, Linear, Zendesk, Fathom), the trigger sheet has a Run only when (optional) field. Describe the condition in plain English, for example “Pull requests by John on dust repository”, and Dust generates the filter for you. Leave it blank and the trigger runs on every event the source sends.

Custom webhooks: write a filter expression

A custom webhook has no provider, so Dust doesn’t know the shape of its payload and can’t offer the plain-language option. Instead, the trigger sheet has a Filter expression (optional) field. Leave it blank and every request runs the agent; write an expression and only matching requests do.

How it works

An expression is a small rule written as (operator "field.path" value). Field paths use dot notation into the JSON payload the webhook sends, for example "issue.state" or "pull_request.head.ref". For an array of objects, pull one field out of each item with a single wildcard level: "tags.*.name" reads name from every object in tags (deeper paths like "tags.*.sub.name" aren’t supported). Combine rules with and, or, and not:

Operators

Examples

  • Only opened issues: (eq "action" "opened")
  • Opened by a specific person: (and (eq "action" "opened") (eq "sender.login" "alice"))
  • Has a “bug” or “urgent” label: (has-any "issue.labels" ("bug" "urgent"))
  • Not closed (combine not and eq): (not (eq "issue.state" "closed"))
  • Large pull requests: (and (eq "action" "opened") (gt "pull_request.changed_files" 20))

Test before you save

Click Compute stats next to the filter field. Dust looks at the last 24 hours of events this source received and reports how many would have matched your filter. You need at least 10 events in that window for an estimate; with fewer, it shows “not enough data” instead. Use it to confirm your filter catches what you expect before turning the trigger on.

Common mistakes

  • Case matters. "issue.State" is a different field from "issue.state", and (eq "action" "Opened") won’t match a payload where action is "opened".
  • Numeric operators need real numbers. (gt "issue.comments" "10") always returns false if "10" is written as a quoted string; gt, gte, lt, and lte only work when both sides are JSON numbers.
  • Wildcards go one level deep. "tags.*.name" works; "tags.*.sub.name" does not.
  • An empty expression always runs. Leave Filter expression blank and the trigger fires on every event from that source.
  • A missing field just means “false”, not an error. Any check on a field the payload doesn’t have returns false, except (not (exists "field")), which returns true.
  • An empty list in has-all is trivially true. (has-all "issue.labels" ()) returns true, there are no required values left to fail on. has-any with an empty list behaves as you’d expect and returns false.