Flow Studio is where you design automated conversation scripts. You arrange blocks on a visual canvas, connect them, publish a version, and the engine runs it.
It lives at Studio → Flows (/admin/flows).
→ New to the vocabulary? Read Core Concepts first — flow, block, intent, execution, wait token.
Flows list
The list (/admin/flows) is your starting point. Each row shows the flow’s status (Draft / Published / Archived), current version, and when it was last updated. A summary at the top reads “X flows · Y published”.
What you can do here:
- Reorder — drag rows to change their order.
- Pin / unpin — keep important flows at the top.
- Quick actions per row — Edit, Settings, Versions, Enable, Disable, Delete.
Create a flow
- Click New flow (
/admin/flows/new).
- Enter a name (required, up to 255 characters) and an optional description.
- Save — this creates a draft at version 1 and opens the canvas.
Flow creation is quota-enforced. If you’ve reached your plan’s limit, archive or delete an unused flow first.
Edit a flow — the visual canvas
Opening a flow (/admin/flows/{id}/edit) loads the canvas — three panes:
- Node palette (left) — drag a block type onto the canvas to add it.
- Canvas (center) — connect a block’s output port to the next block’s input port to define the path. Right-click a node to duplicate, delete, or inspect it; the Delete key removes the selected node.
- Properties panel (right) — the configuration form for the node you’ve selected.
The toolbar holds Save, Publish, Versions, and Settings. Drafts autosave as you work.
Expressions
Most config fields accept expressions — {{ ... }} snippets evaluated at runtime. Autocomplete suggests $node.* (upstream node output), $vars (variables), and $trigger (the data that started the flow). Saving runs inline validation and flags errors on the offending nodes.
Hello {{ $vars.first_name }}, your order {{ $node.lookup.output.order_id }} is on its way.
Conversation variables supplied by the chat client are readable here too. When a session passes a top-level variables object to the chat API, the engine seeds those keys into the conversation scope, and they surface under $vars.* from the first node — {{ $vars.user_email }}, for example. A flow’s own Set variable block (conversation scope) overrides any client-supplied value of the same name. See The widget.
Node types (palette)
Drag any of these from the palette. Plugins can add more — see Connections & plugins.
| Block | Type id | What it does | Key config |
|---|
| Message | ui.message | Send agent text to the user | text, role (agent/user), format (plain/markdown); supports {{ }} |
| Form | ui.form | Ask the user to fill fields; pauses until submit | title, submit_label, and either form_id (a saved Form) or inline fields; outputs values.<field> |
| Condition | logic.condition | Boolean branch with true / false ports | expression |
| Switch | logic.switch | Multi-way branch — one port per case plus default | expression, cases[], default_case_id |
| Set variable | logic.set_variable | Store values as $vars.<name> | variables[], each {name, value, scope}; scope execution (this run) or conversation (persists across resumes) |
| Wait | logic.wait | Pause, then resume | mode (duration/timestamp), duration_ms (default 60000) or target_timestamp |
| Transform | data.transform | Shape data into $node.<id>.output.<key> | output object whose values are {{ }} templates |
| HTTP request | integration.http | Call an external API | connection_ref, method, url (path), headers, body, response_type (json/text), success_codes (default [200]); outputs status, body, headers; optional error branch |
| Send email | integration.email | Send mail via an SMTP connection | connection_ref, to[], subject, body_text, body_html; supports {{ }}; optional error branch |
HTTP request and Send email take their credentials and base URL from a Connection you select (connection_ref) — never paste secrets into a block. See Connections.
Flow settings
Settings (/admin/flows/{id}/settings) control how a flow appears as an action chip in the embedded widget.
| Field | Purpose |
|---|
name, description | Internal identity |
display_label, subtitle | Text shown on the chip |
icon_kind + icon_value | Icon source — none, lucide, url, or svg |
accent_color | Chip accent |
style_variant | solid, outline, or ghost |
is_pinned | Pin the chip |
order_weight | Sort order among chips |
→ For how the chip renders in the chat, see The widget.
Versions
Every save and publish snapshots a version (/admin/flows/{id}/versions). Each entry shows its number, created date, author, and run statistics.
- Diff — compare two versions side by side (
/versions/{a}/diff/{b}).
- Restore — bring a version back as a new draft (
/versions/{n}/restore).
Lifecycle actions
| Action | What happens |
|---|
| Publish | Validates the draft, creates a published version, registers the intent, and enables triggers — the flow becomes runnable by the engine |
| Archive | Withdraws the flow from runtime |
| Enable / Disable | Turns the flow’s triggers on or off |
| Delete | Removes the flow — fails if it’s referenced by other forms or flows |
→ For the runtime journey from publish to execution, see the Flow lifecycle. For how blocks render in the chat, see the Blocks reference.
Permissions
| Action | Permission |
|---|
| View flows, canvas, versions | comerix.flows.view |
| Create / autosave / restore | comerix.flows.manage |
| Reorder the list | comerix.flows.reorder |
| Edit flow settings | comerix.flows.settings |
| Publish / Archive | comerix.flows.publish |
| Enable triggers | comerix.flows.enable |
| Disable triggers | comerix.flows.disable |
| Delete | comerix.flows.delete |
Part of the Comerix Flow admin guide. See also: Forms, Marketplace, Core Concepts.