Skip to content

Steps and triggers

A conversion is an ordered list of steps. Each step is a trigger plus its configuration, and a session passes a step when it matches. The engine applies steps in order as filters on one query, so step 3’s count is “sessions that matched steps 1, 2 and 3”.

A three-step funnel as the API sees it
{
"steps": [
{ "name": "Everyone", "trigger_type": "all_traffic", "trigger_config": { "type": "allTraffic" } },
{ "name": "Saw pricing", "trigger_type": "page_view", "trigger_config": { "type": "page", "field": "path", "match": "starts_with", "value": "/pricing" } },
{ "name": "Started a trial", "trigger_type": "event", "trigger_config": { "type": "event", "name": "trial_started", "valueMatch": "exists" } }
]
}

The dashboard builder writes this for you. The shapes matter when you use the API.

TriggerMatches a session that…Config
all_traffic All User Trafficexists in the period. No condition.none
entry_page Entry Pagestarted on a matching pagefield: entry_path or entry_url, match, value
page_view Page Visitviewed a matching page at any pointfield: path or url, match, value
event Event Firedfired a named event, optionally with a value conditionname, valueMatch, value
form_submit Form Submitsubmitted one of your formssnipFormId
short_link Short Linkarrived through a short link or any link in a groupscope: link or group, value: the id
acquisition Acquisitionhas acquisition cost, value or currency setfield: value, cost or currency_code, match, value

entry_page and page_view share the same match modes:

matchExample valueMatches
containspricing/pricing, /app/pricing-2
exact/pricing/pricing only
starts_with/blog/every blog post
regex^/docs/[a-z]+$one level under /docs/

Match against the path unless you need the host or query string, in which case switch the field to URL.

valueMatch decides whether the event’s value matters:

valueMatchMeaning
existsThe event fired. The value is ignored (the value input is hidden).
equalsValue equals value
gte / lteAt least / at most value
gt / ltGreater / less than value

The numeric operators read the event’s numeric value, so signals('purchase', 4999) can be matched with gte 1000. Event values are whatever you passed as the second argument to signals(); money should be integer cents.

The numeric fields (value, cost) accept exists, equals, gte, lte, gt, lt. The keyword field (currency_code) accepts exists and equals. Most sessions carry no acquisition data at all, so exists on value is the common “this session produced revenue” step.

Steps are cumulative filters: a funnel with steps A, B, C reports C as “matched A and B and C”. Each step carries an is_required flag that defaults to true and is accepted by the API; the engine currently applies every step in order regardless of the flag, so there is no optional-step behaviour to rely on yet.

A funnel measures the people who entered it. The first step defines that group, so it has more effect on your conversion rate than any step after it.

Narrow entry. Starting on a specific page or event asks a precise question: of the people who reached the pricing page, how many bought. The rate is high and useful for judging that one journey, but it says nothing about everyone who never got that far.

Wide entry. Starting with All User Traffic counts every session in the period with no other condition. The rate is much lower, and it is the honest business number: of everyone who showed up, how many did the thing you care about.

A useful default:

  1. All User Traffic as the entry step, to scope every visitor.
  2. The intent moment next: reaching a key page, starting a form.
  3. The outcome last: the purchase, the submission, the signup.

That shape gives you both readings at once: the overall rate from top to bottom, and the drop-off between each pair of steps showing where people leave.

A conversion with one step has no funnel. Its “sessions” count is the sessions matching that step and the rate is 100%. Use it when you only want a count and a value, for example “orders placed” linked to an ad platform for ROAS.

Steps can be replaced at any time, including on an active conversion. Because nothing is stored per conversion, the new definition applies retroactively to every period: the funnel you see tomorrow for last month is the new funnel. If you want to keep the old reading, pause the old conversion and create a new one.