Language Guide

Understand how to reference data throughout Tines Formulas  

As with Excel or Google Sheets, Formulas consist of multiple components and functions with unique language. Below we define the ways you reference data across Formulas in Tines. Formulas are run using data from previous events, resources, or credentials. 

They must be referenced like so:

# accessing properties


If your reference data has a property with another character, say a space, then use brackets [] to reference that data:

# accessing properties with spaces
my_event["a prop with a space"]

In the following sections we break down different ways to reference data across Tines formulas. The sections are broken into: 

  1. Types to tell the system the structure of the data thus dictating which functions can be applied to the data

  2. Operators to tell the system how to compare data 

  3. Functions are actions you can take on the data 

  4. Lambdas

  5. Tags … 


Types tell the system the structure of the data. In Tines, the formula language includes the below types, which correspond to the types in standard JSON. System types are text, Boolean, null, numbers, arrays, and objects. 


Strings of text. Values must always be wrapped in quotes – both single (‘) or double (“) quotes are accepted. The style does not impact the behavior.

# Double quotes
"this is some text"

# Single quotes
'this is also some text'

Quoted text with a text string is referenced using a backslash (\) at the beginning and end of the quote.

For example: As Einstein said, “Never memorize something that you can look up.” 

It would be referenced like this:

# Escaping text
"As Einstein said \"Never memorize something that you can look up.\""


True/False, or Booleans, are case sensitive. By default, all values are true unless they are FALSE or NULL. There is no coercing.

# true

# false


Null values are written with all caps and are falsy:


# true


Numbers are written in simple notation. They will not include commas.

# number

# decimal

# negative


An array, or collection of variables. You can reference an item within an array using square brackets, [], or create an array using the ARRAY function (learn more about the function here) .

When referencing items in an array, the first item is always position zero, 0. See below:

# my_array =  ["first", "second", "third"]


# "first"


Usually you will interact with objects that come from your event data, however you can also create an object using the OBJECT function (learn about the function here).

# referencing an object
OBJECT("key1", "value1", "key2", "value2")

# {key1: "value1", key2: "value2"}


Operators allow you to compare values or perform basic math on them. Operators must be used together with a function or lambda. Below are a few examples but visit the OPERATOR section for more:

# check if equal
a = b

# check if greater than
body.count > 1

# multiply
body.count * 5


Functions perform defined actions on event data. The functions docs go into detail on all the available functions. To help you use functions in real-time, you can see function descriptions and syntax in the product when you hover over a function. 

Functions are: 

  • Written in UPPERCASE

  • Called using its name followed by parentheses, ()

  • Accept multiple arguments

  • Can be nested

Learn more about functions including function chaining and lazy evaluation in the Functions section.

#written in UPPERCASE

#multiple arguments
MY_FUNCTION(argument1, argument2)


Advanced Formulas Language 

Below we go into more advanced formulas capabilities for power users.


Lambdas are a custom, reusable function that you create using the LAMBDA function. This function is a little different from other functions because you specify the placeholders as the arguments to the function.

LAMBDA(a, b, a + b)

Here a and b are the arguments that will need to be passed when the lambda is called, and a + b is the expression that will be evaluated when the lambda is called.

There are three ways of using lambdas: immediately invoked, with an array, or as a local resource. 

Immediately invoked 

First, they can be immediately invoked i.e. LAMBDA(a, b, a + b)(1, 2). This will create a function to add two numbers and then immediately call it. This might not seem very useful, but it can help avoid repetition in cases where you need to reuse the same calculation in multiple places.

For example, if you wanted to check if the current time is between 9 and 5, you might do something like this:

    DATE("now", "%H") >= 9,
    DATE("now", "%H") < 17,
  "office hours",
  "after hours"

Using a lambda you could avoid this repetition like so:

      current_hour >= 9,
      current_hour < 17,
    "office hours",
    "after hours"
)(DATE("now", "%H"))
With an Array function 

The next way you can use Lambdas is as an argument to the functions MAP_LAMBDAFILTERFIND and REDUCE.

For example, let's imagine we have the following array of data in a field called fruit:

    "name": "apple",
    "in_stock": 0
    "name": "banana",
    "in_stock": 5
    "name": "pear",
    "in_stock": 6

If we wanted to find all the items that are in stock, we could write the following:

FILTER(fruit, LAMBDA(item, item.in_stock > 0))

Or, if we wanted to find the item with the name pear we could do:

FIND(fruit, LAMBDA(item, = "pear"))

Or, if we wanted to extract all the names, we could do this:

MAP_LAMBDA(fruit, LAMBDA(item,

The final way you can use lambdas is to assign them to LOCAL or a RESOURCE and then call them from somewhere else. This can be a great way of defining your reusable bits of functionality.

Here we have created a lambda for defanging URLs and stored it in a RESOURCE. The lambda looks like this:

    |> REPLACE(%, ".", "[.]")
    |> REPLACE(%, "http", "hxxp")

Ensure the lambda in the resource, is defined inside of single value mode:

With this in place, we can use it from any story like so:



Tags are only available in single value mode. You can nest tags inside each other.

There must always be a corresponding end tag for each tag.

if elseif else endif

These tags all work together to allow you to evaluate sections in text mode conditionally.

At its simplest, you can have an if and endif pair:

If this is run with a user named Alice, it will output Hi Alice, but if the user has no name, it will just output Hi.

You can also add an else block to act as a catch-all:

Now, if the user has no name, it will output Hi there.

Finally, you can add more conditions using elseif:

You can add as many additional conditions with elseif as you like.

As mentioned above, formulas do not coerce types, with all but NULL & FALSE being truthy. To check if a value is blank write the following:

for endfor

The for tag allows you to repeat the same code block multiple times for each item in an array.

This will output User names: followed by the names of all the users in the array users.

Within a for tag, there is a special FORLOOP variable available with the following properties:

  • FORLOOP.index0: The zero-based index of the current loop iteration. That is the first time through the loop, this will be 0, the second time 1, and so on.

  • FORLOOP.index: The one-based index of the current loop iteration. That is the first time through the loop, this will be 1, the second time 2, and so on.

  • FORLOOP.first: This will be true the first time through the loop.

  • FORLOOP.last: This will be true the last time through the loop.

For example, if we wanted to output a comma between every name we could do something like this:

Was this helpful?