data.type). The type code is what the AI flow generator, the API and the runtime use — the label in the UI is just the display name.
How to read this reference
Every node entry shows:
Condition nodes always have 2 outputs:
- Output 1 = condition was true (the Yes path)
- Output 2 = condition was false (the No path)
Wiring rules
The builder enforces four connection rules. If a connection is rejected, one of these is why.only_on — allowed parents
only_on — allowed parents
Some nodes may only be attached below specific node types. For example Component (
component_split_test_component) is only_on: split_test_weight, so it can only hang off a Traffic Distribution node.When resolving the parent, the builder skips pass-through nodes (see middleman below) and compares against the first real parent. Generic condition nodes also match on their base_type of script_rule, which is why nodes restricted to script_rule accept Is From Country, Query Parameter Condition, and the other generated-script conditions too.one_of_type — one of this kind per output
one_of_type — one of this kind per output
When a node is marked
one_of_type, you cannot attach two nodes of the same type to the same output of the parent. The builder removes the second connection and shows “You can’t connect more than one <type> node to this node”.max_per_output — fan-out limit
max_per_output — fan-out limit
Most nodes allow only one connection per output pin. To run several actions from one branch, use a Sequence node (which lets you add extra outputs) or chain the actions one after another.
middleman — pass-through nodes
middleman — pass-through nodes
Nodes marked as pass-through (Tag User, Set Merchant, Set Variable, Has Tag, Wait Seconds, Show/Hide Element, the video checks, Sequence, and the generic conditions) are transparent for
only_on resolution. Inserting one in the middle of a chain does not break a downstream node’s parent requirement.Anything with a script becomes a Script Rule at runtime. Before dispatching a node, the renderer checks for
data.script_rule and, if present, treats the node as a script_rule regardless of its declared type. That is how Query Parameter Condition, Is From Country and every other generated condition actually execute — they are Script Rules with a pre-written script and a friendly form.Node catalogue
“Not declared” means the node definition in the builder does not state where it runs. In practice the renderer handles all three on the server:
product_check inspects the purchased products, and execute_automation mints a token server-side and then hands the actual call to the browser. Treat them as server nodes when ordering a path, and confirm with the Debug Window if a mixed path behaves unexpectedly.Entry & flow control
Loaded (entry point)
Typeentry · 0 in / 1 out · Server + Browser
The start of a flow. data.value holds the ID of the page the flow belongs to.
A page can have more than one entry node. Each one is a separate View in the left rail of the builder, and their order is stored in entry_views_order.
Views are an organisational device for the canvas only. At render time every entry node’s children are collected and run — the renderer does not pick one entry and ignore the rest, and it does not read
entry_views_order. If you need only one branch to run, put the choice behind a condition, not behind separate views.Router
Typerouter · 1 in / 1 out · pass-through
A junction node used to tidy up the canvas. It carries a short code that can be used to build a node-specific URL.
Fields: code (generated).
Sequence
Typesequence · 1 in / 2+ out · Server + Browser · pass-through
Runs the connected branches one after another. Because every other node is limited to one connection per output, Sequence is how you fan out several actions from a single branch — click Add Sequence Output on the node to add more output pins.
Fields: none.
See Sequence Nodes.
Stop Next Events Execution
Typestop_execution · 1 in / 0 out · Server + Browser
Ends processing for this path. Nothing after it runs — and it also discards the browser-side event queue for this request, so triggers that would have shipped to the page are dropped too.
Fields: none.
Conditions (server)
All condition nodes send the flow to Output 1 when true and Output 2 when false.Script Rule
Typescript_rule · 1 in / 2 out · Server · only_on: entry, script_rule
Custom JavaScript that returns a boolean. This is the most flexible condition and the parent type that most generated conditions inherit from.
Fields
only_on restricts Script Rule to sit under an entry node or another Script Rule — but because every generated condition below carries base_type: script_rule, you can also chain a Script Rule under Is From Country, Query Parameter Condition, and the rest.Query Parameter Condition
Typequery_param_condition · 1 in / 2 out · Server · pass-through
A structured builder for URL parameter checks. The node compiles your conditions into a script_rule and stores both — and the renderer executes it as a Script Rule against the query object.
Fields
Operators
logicalOperator is && (AND) or || (OR) and joins a condition to the next one in the list. The legacy values and / or are normalised to && / || on load.
See Query Parameter Conditions.
Generated conditions
These nodes are Script Rules with a fixed script and a friendly form. They all have 1 in / 2 out, run on the server, and are pass-through.
Each of these also stores the compiled script under
script_rule, and that is what the renderer runs.
Timezone options in the picker: America/New_York, America/Chicago, America/Denver, America/Los_Angeles, Europe/London, Europe/Paris, Asia/Tokyo, Australia/Sydney.
Is Whitelisted?
Typeis_whitelisted · 1 in / 2 out · Server + Browser · pass-through
Checks whether the visitor currently counts as whitelisted.
Fields: none.
Has Tag
Typehas_tag · 1 in / 2 out · Server + Browser · pass-through
Checks for a tag set by Tag User (or ef.addTag()).
Fields: value — tag name.
Cloaking.house
Typecloaking_house · 1 in / 2 out · Server + Browser · pass-through
Routes based on a Cloaking.house verdict.
Fields: value, label.
Product Check
Typeproduct_check · 1 in / 2 out
Branches on which product was purchased. It is a parent node: each output must carry one child.
- Product Check: Match Product (
product_check_product,only_on: product_check) —value= product code to match. - Product Check: Match All (
product_check_all,only_on: product_check) — catch-all for everything not matched.
Conditions (browser)
Scroll Check
Typescroll_check · 1 in / 2 out · Browser · pass-through
Has the visitor already scrolled past a point? Desktop and mobile thresholds are configured separately.
Fields: value (desktop pixels from top), percent (desktop % of page), value_mobile, percent_mobile.
Element In View
Typeelement_in_view · 1 in / 2 out · Browser · pass-through
Is an element currently visible in the viewport?
Fields: value (CSS selector), min_percent_visible (0–100).
If Showed CTA
Typeshowed_cta · 1 in / 2 out · Browser · pass-through
Has the video CTA already been shown?
Fields: none.
If Added To Cart
Typeadded_to_cart · 1 in / 2 out · Browser · pass-through · requires products.view
Fields: value — product code.
Video: Is muted
Typevideo_is_muted · 1 in / 2 out · Browser · pass-through · only_on: exit_intent
Checks whether the main video is muted. It can only be attached below an On Exit Intent node.
Fields: none.
Video: Progress Check
Typevideo_progress_check · 1 in / 2 out · Browser · pass-through
Has the video reached a position?
Fields: value (seconds), percent (% of duration).
Triggers (browser)
Triggers wait for something to happen, then continue down their single output.On Exited Page
Typeon_exited_page · 1 in / 1 out · Server
Despite the name, this node is declared as a server-side node in the builder rather than a browser trigger.
Fields: none.
Content & routing actions
Dynamic Content
Typedynamic_container · 1 in / 1 out · Server · requires pages.create or pages.update
Replaces the contents of a <dynamic-container> on the page with a saved component.
Fields
The container dropdown is populated from
GET /api/brands/{brand}/pages/{page}/component-type/dynamic-container; the component dropdown from GET /api/brands/{brand}/components/all?short=true.
Full guide: Dynamic Content.
Load Another Page
Typepage_variant · 1 in / 1 out · Server · requires pages.create or pages.update
Renders a different page’s content at the current URL. No redirect, no URL change.
Fields
The node is skipped in preview mode so you can inspect the original page.
See Page Variants.
Redirect to Page
Typepage · 1 in / 0 out · Server + Browser
Sends the visitor to another page in the brand. The path ends here.
Fields: value (page ID), slug, code.
Redirect to URL
Typeurl_redirect · 1 in / 0 out · Server + Browser
Sends the visitor to any URL. The path ends here.
Fields: value (target URL), keep_query_params (boolean — carry the current query string over; on by default, set it to false to drop it).
The target URL supports two placeholder families, in both brace and percent form: {click_id} and {query.<param>}. A redirect back to the same host as the current request is suppressed so a rule cannot put the page into a loop.
Show Popup
Typeexit_popup · 1 in / 0 out · Browser · requires exitpopups.view
Fields: value — popup ID.
See Exit Popups.
Show Element / Hide Element
Typesshow_element / hide_element · 1 in / 1 out · Browser · pass-through
Fields: value — CSS selector.
Show Video CTA / Hide Video CTA
Typesshow_video_cta / hide_video_cta · 1 in / 1 out · Browser · pass-through
show_video_cta takes scroll_to (boolean) — scroll the page to the CTA when it appears. hide_video_cta has no fields.
Wait Seconds
Typewait_seconds · 1 in / 1 out · Browser · pass-through
Fields: value — seconds to pause before continuing.
Execute Javascript on Client
Typeclient_script · 1 in / 1 out · Browser
Runs a snippet in the page.
Fields: client_script — the JavaScript source.
Session, commerce & security actions
Tag User
Typeadd_tag · 1 in / 1 out · Server + Browser · pass-through
Fields: value (tag name), expiration_minutes (omit or 0 for a session cookie; a positive number expires the tag after that many minutes — 10080 = 7 days).
Whitelist visitor
Typemark_whitelisted · 1 in / 1 out · Server + Browser · pass-through
Fields: value — expiration in minutes. 0 whitelists the visitor permanently.
Both nodes write an encrypted, httpOnly cookie named whtst. Whitelist visitor with value: 0 sets it for ten years; Mark visitor as NOT whitelisted sets a 7-day negative cookie. Within the same request the change takes effect immediately, so Is Whitelisted? placed after either node sees the new value.
Mark visitor as NOT whitelisted
Typemark_not_whitelisted · 1 in / 1 out · Server + Browser · pass-through
Fields: none.
Both feed the Whitelisted / Non-Whitelisted containers — see Content Visibility Control.
Set Merchant
Typeset_merchant · 1 in / 1 out · Server + Browser · pass-through · requires merchants.view
Fields: value (merchant ID), plus merchant_gateway and merchant_account_id, which are filled in automatically from the selected merchant.
Set Merchant, Clear Merchant and Set Checkout Page are ignored once the visitor has purchased in this session. The renderer refuses to move a buyer onto a different processor or checkout mid-flow.
Clear Merchant
Typeclear_merchant · 1 in / 1 out · Server + Browser · pass-through · requires merchants.view
Resets the merchant back to the domain default. Fields: none.
Set Checkout Page
Typeset_checkout_page · 1 in / 1 out · Server · pass-through
Overrides which checkout page this session uses.
Fields: value (page ID), slug.
See Checkout redirect behavior.
Set Checkout Bumps
Typeset_checkout_bumps · 1 in / 1 out · Server · pass-through
Fields: bumps — array of bump objects (title, description, price, added_message, product code).
This node is only offered in Add Node when the page is flagged as a checkout page.
Set Variable
Typeset_variable · 1 in / 1 out · Server + Browser · pass-through
Sets page variables for the rest of the render.
Fields: variables — an object of key/value pairs.
See Page Variables.
Execute Automation on Customer
Typeexecute_automation · 1 in / 1 out · requires automations.view
Fields: automation_id, delay (seconds, optional).
Block Request
Typeblock_request · 1 in / 0 out · Server · pass-through
Fields: value — the message shown to the blocked visitor.
Ban Visitor by IP / Unban Visitor by IP
Typesban_ip / unban_ip · 1 in / 0 out · Server · pass-through
Fields: none.
Split testing
These nodes are covered end to end in Split Testing. Summary:Component Split Test
Typecomponent_split_test · 1 in / 2–5 out · Server · requires split_tests.create or split_tests.update
Splits traffic between components rendered into a <split-test> container on this page.
Fields
On
enforce_exact_split: the flag is stored on the node and carried into the published flow, but the current page renderer does not read it. Component split tests already allocate traffic exactly — a shared counter (Redis-backed, so it holds across workers) drives a smooth weighted rotation rather than a per-visitor dice roll. Leaving the box unchecked does not make allocation random.PUT /api/brands/{brand}/split-tests/{id} once split_test_id exists): duration, sample_size_limit, min_sample_size_per_variant, significance_level, statistical_power, minimum_detectable_effect, multiple_testing_correction, early_stopping_enabled, statistical_method, sequential_testing_interval, primary_metric, winner_selection_criteria, practical_significance_threshold, require_practical_significance, check_guardrail_metrics, guardrail_metrics, goals, enable_automated_winner_selection, automated_decision_threshold, auto_select_winner, winner_selection_confidence.
Split Test
Typesplit_test · 1 in / 2–5 out · Server + Browser · requires split_tests.create or split_tests.update
The non-component split test: splits traffic between whole branches of the flow rather than between components in one container. Each output takes one Traffic Distribution node, and whatever hangs below that weight is the variant — commonly a Load Another Page.
Fields: value (2–5), name, enforce_exact_split (see the note above), split_test_id, winner_node_code.
Unlike Component Split Test,
split_test can run on either side. On the server the branch is chosen from a shared exact-rotation counter; if the test is handed to the browser instead, selection is a weighted random draw stored in the st_res_<split_test_id> cookie.Traffic Distribution
Typesplit_test_weight · 1 in / 1 out · Server + Browser · only_on: component_split_test, split_test
One per variant. Created automatically when you change the parent’s variant count.
Fields
Component
Typecomponent_split_test_component · 1 in / 0 out · Server · only_on: split_test_weight · requires pagecomponents.view
The component rendered for one variant.
Fields: component (component code), baseline (boolean — mark the control).