Skip to main content
A trigger decides who enters an automation. Filters narrow that entry. Branches decide where they go once inside. These are three different mechanisms with three different rule sets — this page covers all of them.

On-chain triggers

Ten on-chain trigger types are available. Nine are presets: they’re the generic onchain_event trigger with event names and filters pre-filled for a specific business moment. Each accepts these fields:
string
required
Chain slug — eth-mainnet, base-mainnet, arb-mainnet, optimism-mainnet, matic-mainnet, or solana-mainnet.
string
The contract to watch. Leave empty to match the event on any contract.
string
Single event name. Defaults to Transfer on the generic trigger.
string[]
Match any of several event names. Presets fill this in for you.
string
Match by EVM event signature hash instead of by name.
string
Solana program to watch.
string
Solana instruction to match.
string
Narrow to a standard: erc20, erc721, erc1155, erc4626, governance, defi, spl-token, solana-nft, solana-dex, anchor.
Filter[]
Payload conditions — see below.
Matching is a strict AND across everything you configure. Any field you leave unset is a wildcard, but any field you do set must agree with the incoming event or the automation won’t fire.
topic0 and programId are matched strictly. If you configure either one and an incoming event doesn’t carry it, the event is rejected rather than falling back to name matching. Set them only when you’re sure your event source populates them.

Payload filters

Filters test values inside the event payload. Each filter is a path, an operator, and usually a value.
path is a dot-path into the payload, so nested values work: "path": "token.symbol". All filters on a trigger must pass. Comparisons are case-insensitive and whitespace-trimmed, so wallet address casing never matters.
These five operators are the complete set. An unrecognized operator — gte, gt, lt — is silently dropped, and the filter simply stops applying. That makes the automation fire more often than you intended rather than erroring, so double-check operator spelling. For numeric thresholds, filter downstream with a branch node instead.

Lifecycle triggers

Three non-chain triggers are available.

segment_entered

Fires when a contact enters a segment.
string
required
The segment to watch.

email_opened

Fires when a recipient opens a campaign email.
string
Restrict to a single campaign. Omit to match any.

health_threshold

Fires when a contact’s health score crosses a line.
string
gte or lte. Defaults to gte.
number
The threshold. Defaults to 50.
These three triggers fire when an event is posted to the ingest API — the platform does not currently emit them on its own. If you want a segment-entry automation to run, your system needs to call the ingest endpoint when membership changes. See Contract-Based Flows for the API.

Entry rules and deduplication

Each matched event creates one entry — one contact moving through the flow. Entries are deduplicated by a key derived from the automation and the event’s sourceEventId. A duplicate returns duplicate: true and does not re-enter. When you don’t supply a sourceEventId, one is derived for you:
Two consequences worth planning around:
  • A contact can enter a segment_entered automation only once, ever. Removing and re-adding them to the segment will not re-trigger it. For repeatable entry, send an explicit sourceEventId that varies per occurrence.
  • On-chain events without a txHash are never deduplicated — the key falls back to random bytes, so retries create duplicate entries. Always send txHash.

Branch conditions

A branch node routes an entry down different paths. Conditions here test the rolling context — values accumulated as the entry moves through the flow — not the original event payload.
Rules are evaluated in order and the first match wins. If nothing matches, the entry follows defaultTarget, and failing that, the first outgoing edge. Two differences from trigger filters are easy to trip over:
  • Branch fields are flat keys on the context — walletAddress, email, contactId, tags, lastEmail. Dot-paths are not traversed here.
  • gte and lte work in branches but not in trigger filters; in works in trigger filters but not in branches.
The context starts as { email, walletAddress, contactId } and accumulates lastEmail, lastInapp, lastWebhook, lastCampaignDispatch, and tags as nodes execute.
Publishing requires a branch node to have at least two outgoing edges. Draw the edges in the builder even when you’ve selected targets by node id, or validation will reject the graph with INVALID_BRANCH_CONFIG.