Get Funnel
Multi-step conversion funnel with per-step user counts, conversion ratios, and median time-to-convert.
funnel_type=closed (default) for ordered, in-window conversions (the default that powers the dashboard) or funnel_type=open to count whoever fired step k regardless of order - open mode also returns a dropped_off_users column.
Set breakdown to a dimension (device, browser, os, location, referrer, or any UTM column) to group each step by first-touch attribution; breakdown_top_n controls how many categories are kept before bucketing the rest as Others.
Defining steps
Thesteps query parameter is a JSON-encoded array of 2–10 step specs. Each step is {type, event, name, filters?: [...]}:
type- event type (eventfor page views,trackfor custom events,transaction,signature,decoded_log).event- the event name to match.name- a unique step id. Use<event>::<index>(e.g."connect::1") so the same event re-used at multiple steps can be told apart in the response.filters- optional[{operand, operator, value}].- Operators:
equalsnotEqualsinnotIngtltgteltestartsWithendsWithincludes
operandmay target a standard event column or a JSON property onproperties.
- Operators:
Example
Authorizations
Workspace API key (e.g. formo_xxx). Create one in the Formo dashboard under Team Settings > API Keys.
Query Parameters
Inclusive ISO date for the start of the funnel window (YYYY-MM-DD). The events scan extends past date_to by window_seconds so a user who fires step 1 just before date_to can still complete the funnel inside their conversion window.
Inclusive ISO date for the end of the start-event window (YYYY-MM-DD).
JSON-encoded array of 2–10 step specs. Each step is {type, event, name, filters?: [{operand, operator, value}]}. type is the event type (e.g. event for page views, track for custom events, transaction, signature, decoded_log). event is the event name. name is the unique step id (use "<event>::<index>" to disambiguate repeated events).
Filter operators: equals, notEquals, in, notIn, gt, lt, gte, lte, startsWith, endsWith, includes. For in/notIn, pass the values as a |-separated string in value (e.g. "ethereum|polygon|base").
Standard columns (rendered via direct column access): origin, device, browser, os, location, referrer, direct, ref, utm_source, utm_medium, utm_campaign, utm_content, utm_term, builder_codes, version, locale, timezone, page_path. Anything else is treated as a JSON property and read from properties via JSONExtractString (or JSONExtractFloat for numeric comparators).
Conversion window length in seconds. Defaults to 1,209,600 (14 days). For closed funnels this is the windowFunnel cap; for both variants the events scan is extended by this amount past date_to.
x >= 1closed (default): ordered, in-window via windowFunnel. open: unordered per-step minIf; emits an extra dropped_off_users column.
closed, open Optional dimension to break each step down by (first-touch attribution). When set, the response gains a breakdown column.
device, browser, os, location, referrer, utm_source, utm_medium, utm_campaign, utm_content, utm_term Top-N breakdown categories to keep (by user count). Remaining categories are bucketed as Others. Defaults to 8.
x >= 1Response
Per-step funnel results
Analytics endpoint response. The data array contains the rows; the exact row shape depends on the endpoint. meta carries column type information for rendering, rows is the row count, and statistics holds query timing metadata.