powered by

Template syntax

Updated 30 Sep 2026
How workflow templates read trigger data, earlier step outputs, secrets and the current time — including types, missing values and where templates are applied.

Templates put live values into workflow step parameters. Anythink resolves them immediately before each step runs.

text
{{ $anythink.trigger.data.email }}

Syntax

  • A template is an expression inside {{ }}. Spaces inside the braces are ignored.
  • A value can contain several templates and plain text: "Order {{ $anythink.trigger.id }} for {{ $anythink.trigger.data.email }}".
  • When a whole parameter is a single path, the braces are optional: "loop_over": "$anythink.steps.find_orders.data".
  • The only filter is default, which supplies a value when the path doesn't exist:
text
{{ $anythink.trigger.data.nickname | default: "there" }}

Variables

Expression Value
$anythink.trigger.id The id the job started with: the record id for entity events, entity_id for manual and API calls, empty for schedules
$anythink.trigger.data The trigger data. See Triggers and scheduling for what each trigger provides.
$anythink.trigger.data.<field> One field. Paths can go deeper: address.city, items[0].sku.
$anythink.steps.<key> The output of an earlier step with that key
$anythink.steps.<key>.data[0].<field> A field from the first item of a step's data list
$anythink.steps.<key>.data[*].<field> That field from every item, as a list
$anythink.secrets.<name> A project secret, decrypted. Always text.
$anythink.now The current time in UTC, such as 2026-09-14T08:30:00.000Z
<field> with no prefix A field of the current item, inside steps that repeat per item (see below)

Following relationships from trigger data

Trigger data paths follow relationships. If an order has a customer relationship, {{ $anythink.trigger.data.customer.email }} loads the related customer and reads its email. A field named customer_id is followed the same way.

Relationship lookups work on trigger data for entity events, not on step outputs.

The current item

Some steps repeat for each item in a list. Inside them, the item's fields are available without a prefix:

Step Repeats for
Create data, Upsert data Each item in loop_over
Update data with filters Each matched record
Send a push notification Each item of the step referenced with data[*]
json
{
  "entity_name": "invoices",
  "loop_over": "{{ $anythink.steps.due_orders.data }}",
  "payload": "{ \"order_id\": \"{{ id }}\", \"amount\": \"{{ total }}\", \"issued_at\": \"{{ $anythink.now }}\" }"
}

Types

In JSON parameters such as payload and body, a template keeps the value's type when it is the entire JSON value:

json
{ "total": "{{ $anythink.trigger.data.total }}" }     →  { "total": 129.5 }
{ "tags": "{{ $anythink.trigger.data.tags }}" }       →  { "tags": ["gift", "express"] }

When a template is part of longer text, the value is written as text. Lists and objects become compact JSON, and booleans are written True or False:

json
{ "summary": "Total {{ $anythink.trigger.data.total }}" }   →  { "summary": "Total 129.5" }

In parameters that aren't JSON — URLs, header values, filter values, email addresses and ids — the result is plain text.

Note: Write payloads as valid JSON, with each template in quotes. Anythink only escapes values and keeps their types when the payload parses as JSON before templates are filled in. An unquoted template such as { "total": {{ total }} } isn't valid JSON, so a value containing quotes or a new line can break the payload.

Note: Once a JSON payload contains a template, its other numbers are re-read as standard numbers. Very large ids (beyond 2^53) can lose precision. Send them as text.

Missing and empty values

Situation Result
The path, step or list item doesn't exist The template is left as written, braces included
The path doesn't exist and has default The default
The value exists but is null null when the template is the whole JSON value; empty text inside longer text
The secret doesn't exist The step fails with "Failed to retrieve secret with key…"

Unresolved templates stay in the output, so a typo shows up in the saved record or the step log rather than silently producing an empty value. Send an email and Send a push notification refuse to send anything that still contains {{.

A Read data step that returns no records leaves $anythink.steps.<key>.data[0].<field> unresolved, and an unresolved path compares as text in a Condition. To branch on whether anything was found, return a count from Run a script (return { count: $anythink.steps.find_orders.data.length };) and compare that count in the Condition.

Where templates apply

Step Templated Not templated
Read data Filter values Entity, fields, sort, limit, filter fields
Create data, Upsert data payload, loop_over, rls_user_group_id entity_name, match_on
Update data payload, ids, filter values, rls_user_group_id entity_name, rls_mode
Delete data Filter values entity_name
Condition field and value logical_operator
Call an API url, header values, body method, header names, results_path
Send an email to, from, payload, attachment ids template_type
Send a push notification Title, body, image, click action, category, data values, audience ids template_type, buttons
File handler Entity, record id, field, source URL, file name, folder, existing file id operation, link_mode
Integration Text values in inputs, connection_id, credential_field_path provider, operation
Run a script Not templated. Use the $anythink object in the script.

Trigger filters don't use templates.

Next steps

Step types Monitoring and testing