Skip to Content

Triggers

A trigger is what starts a Helix run — the product calls this the automation’s stimulus. Every automation has one, and you can change it at any time. There are three ways to start a run today.

On demand

Run the automation by hand whenever you need it — from its page in the app, or as part of testing. On-demand is the default while you’re building, and stays useful for automations you run occasionally or want to kick off yourself.

On a schedule

Run the automation on a recurring timetable using standard cron syntax. Nightly, hourly, “weekdays at 9 AM” (0 9 * * 1-5), the first of the month — whatever cadence the job needs. A built-in helper offers common presets so you don’t have to memorize cron. This is how you drive recurring processes like monthly reporting or first-of-the-month billing runs.

For simple time-based agent runs outside of Helix, see Schedules.

From a webhook

Start a run when an external system calls in. Helix gives the automation a secure webhook URL; when a request arrives, the run begins and the incoming payload is available to your steps. Use this to react to events from other tools — a GitHub push or pull request, a form backend, a payment processor, or any service that can send an HTTP request.

Filtering which requests start a run

Not every request to the webhook URL should necessarily start a run — a GitHub webhook fires for every push and PR event, but you might only want to react to pushes to your main branch, or PRs being opened. A filter lets you say which requests actually trigger a run; everything else is received and discarded.

A filter is a simple condition checked against the payload:

<path> <operator> <value>
  • path is a field in the incoming payload — action, ref, repository.full_name, and so on.
  • operator is one of a small set of comparisons: exists, contains, ==, and similar.
  • value must be a literal — a fixed string, number, or boolean you write into the filter. It can’t be a reference to another field in the payload; you’re comparing the field against a fixed value, not two fields against each other.

Two things trip people up when writing a filter:

Paths are not prefixed with payload.. The filter evaluates directly against the payload’s own top-level fields, so write action == "opened" — not payload.action == "opened". A path with a payload. prefix simply won’t match anything.

The right-hand side is always a literal. ref == "refs/heads/main" is a valid filter; you can’t write something like ref == repository.default_branch to compare two fields against each other.

A GitHub PR-opened filter, for example, is just action == "opened"; a push-to-main filter is ref == "refs/heads/main".

Passing data into a run

However a run starts, its stimulus — the incoming payload, or the values you provide on demand — is available to your steps. A step can read fields straight from the stimulus, so a webhook body or a form submission flows directly into the pipeline.

Note: a wait step can also pause for an “event” mid-run — that’s a different thing from the stimulus that starts a run in the first place. See Wait steps for that distinction.

Coming soon: connector-event triggers, which start a run automatically when something happens in one of your connected tools — a new record, an inbound message, a completed signature. Until then, use a webhook to bridge external events into an automation.

See also: Building an Automation, Step Types, Schedules, Triggers

Last updated on