Skip to Content
Automations

Variables and templates

Use data from the event and from earlier steps in titles, messages and requests

Last updated on

With variables you make texts that differ from case to case. You write a variable between curly braces and Tillor fills in the real value as soon as the automation runs.

An example of a task title:

Controleer {occupation.terrain.name}

If the occupation ends on terrain 12, the task is called Controleer 12.

Inserting a variable

Above every text field where variables work, there is the Variable button. Click it and you see a list of all available data, grouped by record. Type to search (Search variables) and click a row. Tillor puts the variable at the position of your cursor.

Variable button at the Title field with the list of available variables open

You can also just type a variable yourself. Under the field a grey box shows what the text looks like with sample data, so you can see straight away whether it is right.

Variables work in text fields such as titles, descriptions, subtasks, messages, the id of a customer, invoice or other record, the path or URL of an API request, the body, the payload of a webhook, the name of the webhook event and the values of headers. For the last two the Variable button is missing, but a variable that you type yourself is still filled in. Tillor does not check those two fields for errors and shows no preview for them.

In fields where you choose a piece of data to compare with, you write the variable without curly braces. That applies to Only when, If / else and Until under Wait until (for example invoice.status), to the Field of a Switch and to the Date of a Delay.

Which variables are there

VariableAvailableContent
{occupation.…}, {invoice.…}, {task.…}, {reservation.…} and othersAfter an eventThe fields of the record the event is about. The name of the record is also the start of the variable
{occupation.terrain.name}After an eventFields of the records the record refers to, such as the customer or the terrain. This works one level deep
{triggeredBy.name}, {triggeredBy.id}AlwaysThe colleague who caused the event. Empty if the system did
{invoice.…}With Invoice is overdueThe fields of the overdue invoice and the customer
{reservation.…}, {task.…} and othersWith A date is reachedThe fields of the record whose date was reached, plus the records it refers to
{now}, {today}AlwaysThe moment the step runs, and midnight of that day in the organisation's time zone. Together with a shift (below), {today + 1 day} gives tomorrow
{threadId}, {messageId}With events about inbox messages, such as inbox:message-createdThe id of the conversation and of the message
The fields of the eventAfter Wait for an event, via ReceivedThe data of the event that was waited for. It replaces the data of the same records from the start of the flow
{createdTask.id}, {createdTask.name}After Create taskThe task that was just created
{foundTask.id}, {foundTask.name}, {foundTask.priority}, {foundTask.status}After Find task, via FoundThe task the step found
{updatedTask.id}, {updatedTask.status}After Set task statusThe task whose status was changed
{updatedTask.id}, {updatedTask.priority}After Set task priorityThe task whose priority was changed
{updatedTask.id}After Update taskThe task that was changed
{foundDocument.id}, {foundDocument.name}, {foundDocument.status}, {foundDocument.userMetadata.documentType}, {foundDocument.userMetadata.insuranceExpiryDate}After Find document, via FoundThe document the step found
{updatedDocument.id}After Update documentThe document that was changed
{response.status}, {response.body}, {response.data.…}After API requestThe response to the request
{foundCustomer.…}, {foundInvoice.…}, {foundReservation.…} and othersAfter Look up a record, via FoundThe fields of the record the step found, plus the records it refers to. The name is found plus the record type: foundCustomer, foundReservation, foundOccupation, foundInvoice, foundPayment, foundTerrain, foundTask, foundDocument, foundAccessMethod, foundNfcTag, foundMeter, foundInboxThread or foundInboxMessage
{body.…}, {query.…}, {receivedAt}After Incoming webhookThe JSON body, query parameters and time of receipt of the webhook call
Every target name from Map variablesAfter Map variablesWhat you fill in as the target in that step, for example {invoice.displayId} after invoice ← {foundInvoice}
{item.…}In the steps after For eachThe fields of the item the step is now running for, such as {item.id}
{approvalTask.id}, {approval.decision}, {approval.label}, {approval.note}, {approval.decidedBy.name}After Ask for a decision, via an optionThe task, the chosen option, the name of that option, the note and the colleague who chose
{task.…}, {action.label}, {note}With A task action is chosenThe task, the chosen button and the note filled in with it
{createdComment.id}After Add a commentThe comment that was just posted
{bookedInvoice.displayId}After Book invoice, via DoneThe invoice number of the booked invoice
{paymentLink.url}After Create payment link, via DoneThe link the customer can pay online with
{consumptionInvoice.id}After Invoice consumption, via DoneThe invoice for the meter consumption
{extendInvoice.id}After Draft extension invoiceThe draft invoice that extends the occupation
{createdAccessMethod.id}, {createdAccessMethod.value}After Create access methodThe new access method and its value, such as the code of a QR code or PIN code
{error.message}, {error.step}After an action with Continue when this step fails, via ErrorThe error message and the name of the step that failed

Exactly which fields a record has, you see in the list behind the Variable button. At the trigger there is also the overview Data this event provides.

Only what comes earlier in the flow

A step can only use variables from the trigger that reaches it and from steps that come earlier on the same path. If several triggers reach the same step, only the variables that each of those triggers provides are available. A field from an earlier step counts if each of those triggers also passes that step. If you use a variable that does not exist at that point, Tillor reports [Field]: [variable] is not available at this step. A flow with such a message cannot be enabled.

Some records keep extra data in one field, such as the document data in userMetadata. Every key below it is a variable: {document.userMetadata.documentType}, {document.userMetadata.insuranceExpiryDate} or another key. The known keys, such as the type and expiry date of a document, are also in the list and you can compare them as a date. A date without a time, such as 2026-10-07, appears in a message as 07-10-2026.

Variables of For each ({item.…}) only exist in the steps after the For each exit, not after Done. Variables of an exit you did not take do not exist either: {paymentLink.url} is only there if the step ran via Done, and {foundTask.id} only after Found.

For events whose data is not described, Tillor cannot check which variables exist. Then you do not get that message. So check such flows extra carefully with a test run.

A new value replaces the old one

A second API request in the same flow replaces the response of the first. The same goes for createdTask after a second Create task, for foundTask after a second Find task or Look up a record on Task, and for error after a second failed step. So use the data from a response in the step that directly follows it.

How values are filled in

Tillor adapts the notation to the kind of field.

In plain text (titles, descriptions, subtasks):

  • Dates are in your organisation's time zone, for example 05-10-2026. If the time is not exactly midnight, a time is added too, such as 05-10-2026 14:30
  • An empty field gives an empty text
  • A variable that Tillor does not know stays as you wrote it, for example {occupation.terain.name}. A typing mistake is then spotted at once in the task or the message
  • If a linked record is not there, the variable stays empty. An occupation without a reservation therefore gives nothing for {occupation.reservation.displayId}, and an event caused by the system gives nothing for {triggeredBy.name}. If you want different text in that case, put an If / else with is empty in front of it

In JSON (the Payload of a webhook and the Body of an API request):

  • Text is filled in safely. Quotation marks, new lines and other special characters in the value cannot break the JSON
  • Numbers and yes/no values come without quotation marks, so do not put any around them. Text you do put between quotation marks
  • Dates go through as an international date and time, such as 2026-10-05T08:00:00.000Z, so that the receiving system can handle them properly
{
  "reservation": "{reservation.displayId}",
  "adults": {reservation.numberOfAdults}
}

If the JSON is not valid after filling in, for example because a number is empty, the run stops with an error message.

In a path or URL (with an API request):

  • Values are converted so that they fit in an address. A name with a space therefore does not give a broken address
  • Dates go as an international date and time here too
  • What you type yourself stays as you type it. If you want a space in a search term, type %20 yourself

Shifting a date

A shift may follow a date variable: {reservation.checkOut + 1 day}, {today - 2 weeks}, {invoice.dueDate + 3 hours|date}. The units are minutes, hours, days, weeks and months (the singular is fine too). Days and weeks are fixed lengths, so that a validity period stays equally long across summer and winter time; months follow the calendar, so 31 January plus a month is 28 or 29 February. On a value that is not a date the shift does nothing, and a unit that does not exist is an error on the step. Date fields such as Valid until accept the same notation.

Formatting a value

Put a | and a format after the variable, for example {invoice.amountOutstanding|currency}. Without a format an amount appears plain, such as 1295.3. With |currency that becomes € 1.295,30.

FormatExampleResult
currency{invoice.amountOutstanding|currency}€ 1.295,30
currency:USD{invoice.amountOutstanding|currency:USD}US$ 1.295,30
number{invoice.amountOutstanding|number}1.295,3
number:2{invoice.amountOutstanding|number:2}1.295,30 (fixed number of decimals)
date{invoice.dueDate|date}30-06-2026
datetime{invoice.createdAt|datetime}01-06-2026 16:04
time{invoice.createdAt|time}16:04
upper / lower{customer.lastName|upper}VAN DEN BROECKE
  • Numbers and amounts are always in Belgian notation: a full stop for thousands and a comma for decimals
  • Dates and times are in your organisation's time zone
  • If the format cannot read the value, for example |currency on text, the value simply appears without formatting
  • A format that Tillor does not know stays as you wrote it, and the editor shows a message about it
  • In JSON and in a URL the formatted value is filled in as text. So put quotation marks around it in JSON

Using an API response

After an API request you can use fields from the response with {response.data.…}. The response to a search for tasks looks like this, for example:

{
  "items": [
    { "id": "task_1", "priority": "LOW" }
  ]
}

Then {response.data.items.0.id} gives the id of the first task (the first in a list is number 0) and {response.data.items.0.priority} its priority.

Tillor can only offer the fields of a response as a variable if it knows what the response looks like. That can be done in two ways:

  • Let the automation run for real once. Tillor then uses the response of the last run
  • Paste a sample into the Test run tab, in the Sample API response field. That field appears as soon as the flow contains an API request. Below it are Fields in this response. Click a field to have it copied, including curly braces

After that the fields are in the list behind the Variable button and in the list under Field of a Switch.

If you type a path under response.data yourself, it is always accepted, even without a sample. Furthermore:

  • {response.body} contains the first 4000 characters of the response. If the response is longer, the rest is cut off
  • {response.data} is empty if the response is not JSON, or if the response is very large (more than 100,000 characters)
  • For a search without a result, {response.data.items.0.id} does not exist. A Switch on such a field then goes via Default

A sample in the test

In the Test run tab you also fill in the sample data of the event. That way you see in the test run which values Tillor would fill in. See Testing and runs.

What happens next?

  • As soon as the automation runs, Tillor replaces every variable with the real value. A variable that Tillor does not know stays as you wrote it.
  • If a piece of data is empty, the spot stays empty. If you want different text then, put an If / else with is empty in front of it.

Problems?

Was this page helpful?

On this page