Vettero
Concepts

Variables

Liquid templates and path bindings that pass dynamic data through the workspace.

Variables in Vettero are how you pass dynamic data through the workspace. You use two related patterns for values that change at runtime, plus workspace environment variables for shared config and secrets:

PatternWhat it isHow you write it
Environment variablesWorkspace key/value config and secretsenv.API_KEY
Liquid templatesLiquidJS text rendered against the execution context{{ args.name }}, {% if %}, filters
Path bindingsPoint a builder field at a runtime value instead of a literalargs.email, pipe.value, myVar

Use them whenever a field or template needs values from inputs, session context, upstream steps, or shared secrets — without hardcoding them.

When to use

  • Store API keys and shared config once under Environment Variables and reference them as env.*
  • Render dynamic text with Liquid wherever templates are supported
  • Wire structured builder fields to dynamic data with path bindings
  • Hold intermediate values in a workflow with Set Variables / Update Variables

Write Liquid templates

Vettero renders text fields with LiquidJS — the same templating language used across many surfaces (message bodies, agent Task/Input, chat widgets, email templates, Create Text, calendar/email fields, and other Liquid-enabled block inputs). Editors that support it highlight Liquid and often autocomplete when you type {{.

The runtime resolves variables from the current execution context (the same namespaces as path bindings: args, env, session, pipe, named vars, and so on — what is in scope depends on where the template runs).

Output

Interpolate a value with double curly braces:

Hello {{ args.name }}
Order {{ args.order.id }} — status {{ args.order.status }}
Key: {{ env.API_KEY }}

Missing variables render empty (strict variables are off). Dot paths and array indexes work the same way as elsewhere in Vettero (items.0.title).

Tags

Use {% … %} for control flow, loops, and assignment. Common tags:

TagPurpose
{% if %} / {% elsif %} / {% else %} / {% endif %}Conditional branches
{% unless %} / {% endunless %}Inverse condition
{% case %} / {% when %} / {% else %} / {% endcase %}Switch-style branches
{% for item in collection %} / {% endfor %}Iterate arrays/collections (forloop helpers available)
{% assign name = value %}Set a local template variable
{% capture name %}…{% endcapture %}Capture a string into a variable
{% comment %}…{% endcomment %}Block comments
{% raw %}…{% endraw %}Leave Liquid syntax unparsed

Example:

{% if args.vip %}
Welcome back, {{ args.name }}.
{% else %}
Hello {{ args.name }}.
{% endif %}

{% for item in args.items %}
- {{ item.title }} ({{ item.qty }})
{% endfor %}

Filters

Pipe values through filters with |. Unknown filters fail at render time (strictFilters is on). LiquidJS ships the usual filter set — for example:

{{ args.name | upcase }}
{{ args.name | downcase | strip }}
{{ args.price | plus: 10 }}
{{ args.items | size }}
{{ args.tags | join: ", " }}
{{ args.createdAt | date: "%Y-%m-%d" }}
{{ args.bio | default: "No bio" }}
{{ args.html | escape }}

Chain filters left to right: {{ args.title | strip | truncate: 40 }}.

Includes (email templates)

Workspace email templates can embed another template by key:

{% include "header_partial" %}

That include path is specific to the email-template renderer. Elsewhere, stick to output, tags, and filters against the local context.

WhatsApp template placeholders ({{1}}, {{2}}) are not Liquid — see WhatsApp Templates.

Limits and behavior

  • Rendered against the active context only — do not invent paths that are not in scope.
  • Standard LiquidJS tags and filters are supported; prefer documented LiquidJS syntax over custom dialects.
  • Engine safeguards apply (parse/render/memory limits). Relative file includes are not a general filesystem feature outside email-template include.
  • WhatsApp template placeholders ({{1}}, {{2}}) are Meta-style slots, not Liquid — do not mix them with named Liquid variables.

For the full language reference, see LiquidJS.

Bind fields to variable paths

In workflows, queries, mappings, and many block fields, you choose a literal or a variable path. Paths are dotted strings resolved against the current execution context — for example args.email or items.0.name. Do not wrap path bindings in {{ }}.

Prefix / formMeaning
args.*Inputs for the current agent, workflow, query, event, or callback scope
env.*Workspace environment variables
pipe.value / pipe.*Output of the upstream block on the data pipe
ctx.*Extra context for a single resolve or template render — not loop item/index.
session.*Chat session fields in conversational flows
global.nowBuilt-in current date/time
Bare key (for example myVar)Named variable defined earlier in the same run
res.*Mapped resource output in some mapping UIs

Which namespaces are valid depends on the parent block or resource. Missing paths resolve to empty/undefined.

Array elements use numeric segments: rows.2.status.

Set variables in workflows

In the workflow builder, under basic → context:

BlockWhat it does
Set VariablesCreate named keys in the current (local) scope
Update VariablesChange existing named keys wherever they already live

You can also set starting names on Start and Lambda.

Names must be valid Liquid and JavaScript identifiers: start with a letter or underscore, then only letters, digits, and underscores (total, order_id). Do not use hyphens, dots, spaces, or reserved roots such as args, env, session, pipe, ctx, global, and error.

Downstream steps can read those keys as bare paths (myVar, myVar.items.0.id) or inside Liquid ({{ myVar }}). They stay in the run context; they are not workspace resources like env vars.

Liquid vs path bindings

ContextSyntax
Template / text fieldsFull Liquid: {{ … }}, {% … %}, filters
Structured builder fieldsPath only: args.field, env.KEY (literal vs variable toggle)

Mixing them breaks resolution — a path field whose value is {{ args.field }} will not run as Liquid.

Where variables are used

PlaceHow
Liquid-enabled textMessage bodies, Task/Input, Create Text, chat widgets, email templates, calendar/email fields, and similar
AgentsLiquid in Task/Input; args schema; env.*
WorkflowsPath bindings on blocks; Set / Update Variables; Liquid on text outputs
Queries & mappingsFilters and field bindings as literals or paths
Chat widgetsLiquid HTML templates
FunctionsReceive structured args; bind resources separately
Email templatesLiquid bodies; env.* and {% include %}
Environment variablesCreate and manage env.* keys

Limits

  • Prefer Secret env vars and env.* references for credentials — avoid literals in shared configs. See Environment Variables.
  • pipe.* is the current block’s data pipe. ctx.* is extra context for one resolve/render — not persisted.
  • Liquid templates and path bindings are different surfaces; WhatsApp {{1}} is a third, separate system.
Copyright © 2026