# Function reference

A function is called like this: `{{ name(argument1, argument2) }}`. Arguments are text in quotes, numbers, variables (`$name`) and, in [expressions](https://support.watbot.org/chatbots/templates/expressions), the results of other functions.

Functions marked **simple** work everywhere templates work. The rest work only in message texts, conditions and some block settings — see [Where templates work](https://support.watbot.org/chatbots/templates/where).

## Text

| Function | What it does | Example | Result |
|---|---|---|---|
| `upper(text)` | All letters uppercase | `{{ upper("hello") }}` | `HELLO` |
| `lower(text)` | All letters lowercase | `{{ lower("HELLO") }}` | `hello` |
| `capitalize(text)` | First letter uppercase | `{{ capitalize("anna") }}` | `Anna` |
| `len(text)` | Number of characters | `{{ len("Monday") }}` | `6` |
| `trim(text)` | Removes spaces at both ends | `{{ trim("  yes ") }}` | `yes` |
| `replace(text, what, with)` | Replaces every occurrence | `{{ replace("8-999-000", "-", "") }}` | `8999000` |
| `substr(text, start, length)` | Part of the text; start from 0 | `{{ substr("Monday", 0, 3) }}` | `Mon` |
| `number_format(number, decimals, decimal_separator, thousands_separator)` | A number with separators. Defaults: 0 decimals, comma and space | `{{ number_format(1234.5, 2) }}` | `1 234,50` |
| `urlencode(text)` | Encodes text for a link | `https://site.com/?q={{ urlencode($query) }}` | |
| `randomText(option1, option2, ...)` | One option at random | `{{ randomText("Hi", "Hello") }}` | |
| `strRandom(length, uppercase)` | A random string of letters and digits, up to 1000 characters. Pass `true` as the second argument for uppercase only | `{{ strRandom(8, true) }}` | `K3JD8QWZ` |

All functions in this section are **simple**.

## Math

| Function | What it does | Example | Result |
|---|---|---|---|
| `round(number, decimals)` | Rounding, to a whole number by default | `{{ round(2.567, 2) }}` | `2.57` |
| `ceil(number)` | Round up | `{{ ceil(2.1) }}` | `3` |
| `floor(number)` | Round down | `{{ floor(2.9) }}` | `2` |
| `abs(number)` | Absolute value | `{{ abs(-5) }}` | `5` |
| `sqrt(number)` | Square root | `{{ sqrt(16) }}` | `4` |
| `max(a, b, ...)` | Largest | `{{ max(3, 7, 5) }}` | `7` |
| `min(a, b, ...)` | Smallest | `{{ min(3, 7, 5) }}` | `3` |
| `rand(from, to)` | A random whole number | `{{ rand(1, 100) }}` | |

All functions in this section are **simple**. Addition, subtraction, multiplication, division and powers are written with operators — see [Arithmetic](https://support.watbot.org/chatbots/templates/expressions#arithmetic).

### Deprecated functions

These functions still work, but in new texts use operators — it's shorter and clearer:

| Deprecated function | How to write it now |
|---|---|
| `sum($a, $b)`, `сумма($a, $b)` | `{{ $a + $b }}` |
| `diff($a, $b)`, `разность($a, $b)` | `{{ $a - $b }}` |
| `multiplication($a, $b)`, `произведение($a, $b)` | `{{ $a * $b }}` |
| `div($a, $b)`, `деление($a, $b)` | `{{ $a / $b }}` |
| `pow($a, $b)` | `{{ $a ** $b }}` |

For example, instead of `{{ sum($price, $delivery) }}` write `{{ $price + $delivery }}`.

## Date and time

> [!WARNING]
> Time is calculated in UTC. Add your offset if needed, e.g. Moscow time (UTC+3): `{{ date("H:i", "+3 hours") }}`.

| Function | What it does |
|---|---|
| `date(format, date)` | A date in the given format. Without a date — now. The date can be `"2026-10-02"`, `"+7 days"`, `"next monday"` and so on |
| `time()` | Current time in seconds since 1970 (Unix time) |
| `modifyDateTime(date, date_format, output_format, shift)` | Parses a date from a variable using its format, shifts it and outputs it in another format |
| `modifyUnixTime(unix_time, shift, format)` | Shifts a Unix time; with a format it outputs a date, without one — the new Unix time |

Examples:

```
Today is {{ date("d.m.Y") }}
See you on {{ date("d.m.Y", "+3 days") }}
Your appointment is moved to {{ modifyDateTime($appointment_date, "d.m.Y", "d.m.Y", "+1 day") }}
Access until {{ modifyUnixTime(time(), "+30 days", "d.m.Y") }}
```

Main format characters:

| Character | Meaning | Example |
|---|---|---|
| `d` | day with leading zero | `02` |
| `j` | day without leading zero | `2` |
| `m` | month with leading zero | `10` |
| `n` | month without leading zero | `10` |
| `Y` | year | `2026` |
| `H` | hours, 24-hour format | `14` |
| `i` | minutes | `05` |
| `s` | seconds | `09` |
| `N` | day of the week, 1 is Monday | `5` |

The shift is written in English: `"+1 day"`, `"-2 hours"`, `"+1 month"`, `"next friday"`.

All functions in this section are **simple**.

> [!NOTE]
> Older scenarios sometimes use a question mark placeholder: `{{ date("d.m.Y", "+? days", $days) }}` — `?` is replaced with the next argument. This still works, but in expressions it's easier to join text: `{{ date("d.m.Y", "+" ~ $days ~ " days") }}`.

## Conditions

| Function | What it does |
|---|---|
| `printByCondition(a, operator, b, if_yes, if_no)` | Compares `a` and `b` and outputs one of the options. Operators: `=`, `!=`, `>`, `>=`, `<`, `<=`. If `a` or `b` is empty, outputs `if_no` |
| `printByExistsCondition(value, if_yes, if_no)` | `if_yes` if the value isn't empty, otherwise `if_no` |

```
{{ printByCondition($points, ">=", 100, "The gift is yours!", "Keep collecting") }}
{{ printByExistsCondition($phone_number, "Phone number saved", "Please leave your phone number") }}
```

Both functions are **simple**. In expressions the condition operator is handier: `{{ $points >= 100 ? "The gift is yours!" : "Keep collecting" }}`.

## Contact and bot data

| Function | What it does | Simple |
|---|---|---|
| `var("name")` | A contact variable's value; handy for names with spaces | yes |
| `global("name")` | A global variable's value | yes |
| `printContactTags()` | The contact's tags, comma-separated | yes |
| `printContactVariables()` | All of the contact's text variables as a list "- name: value" | yes |
| `printGlobalVariables()` | All of the bot's global variables as a list "- name: value" | yes |
| `getBalance("currency", "label")` | The contact's account balance in a currency, with its symbol: `getBalance("USD")`. With a second argument — a number and your label: `getBalance("PTS", "points")` → `150 points` | no |
| `getCartAmount()` | The cart total of the legacy "Shopping cart" block | no |

> [!WARNING]
> `printGlobalVariables()` outputs **all** global variables. Don't use it in messages to contacts if your global variables store keys or passwords.

## Variables

These functions write the result to a contact variable and output nothing.

| Function | What it does |
|---|---|
| `setSumVariablesIntoVariable("result", a, b, ...)` | Saves the sum to the `result` variable |
| `setMultiplicationVariablesIntoVariable("result", a, b, ...)` | Saves the product to the `result` variable |

The terms are numbers or variable names in quotes, at least two: `{{ setSumVariablesIntoVariable("result", "price", "delivery", 100) }}`.

For calculations, the "Variable operation" block is more convenient — it supports expressions too.

## Lists

| Function | What it does |
|---|---|
| `getListRow("entry id", "template")` | Outputs one list entry using a template |
| `getListRows("list id", "template", how_many, "sort field", "asc" or "desc", "separator")` | Outputs list entries using a template, 10 by default, at most 50, each on a new line |

In the template, an entry field is written in single curly braces: `{Name}`, `{Price}`. In `getListRows` you can insert a contact variable into the template: `{$city}`.

```
{{ getListRows("6523f0c2a1b2c3d4e5f60718", "{Name} — ${Price}", 5, "Price", "asc") }}
```

The bot reads only lists that belong to its owner.

## Referral program

| Function | What it outputs |
|---|---|
| `getInviteLink()` | The contact's personal referral link (Telegram, MAX) |
| `getDirectInviteLink(scenario_id)` | A direct link to the bot with a referral parameter; with a scenario — a link that starts that scenario |
| `getInviteLinkWithSchema(scenario_id)` | A referral link that starts a scenario |
| `getLinkBySchema(scenario_id)` | A link that starts a scenario, without a referral parameter |
| `getReferrals(how_many, "tag")` | The list of contacts invited by this contact (first level): "1. Name - username", 10 by default, at most 100. With a tag — only those with that tag |
| `getReferralsByDepth(level, how_many, "tag")` | The same for the given level |
| `getReferralsCount("tag")` | The number of invited contacts across all levels |
| `getReferralsCountByDepth(level, "tag")` | The number of invited contacts on the given level; 0 — all levels |
| `getReferrer(level)` | Who invited the contact; 2 — who invited the inviter, and so on |
| `getReferrers(how_many_levels, from_level, "tag")` | The list of inviters up the chain |

The functions in this section are not simple. The deprecated variants with `Telegram` in the name (`getTelegramInviteLink` and others) work the same way.

## Different texts for different messengers

The text inside the function is shown only to contacts from that messenger; everyone else gets an empty spot:

| Function | Messenger |
|---|---|
| `messageToTelegram("text")` | Telegram |
| `messageToViber("text")` | Viber |
| `messageToVK("text")` | VK |
| `messageToWeb("text")` | Website web chat |

```
Message us{{ messageToTelegram(" on Telegram: @example_support") }}{{ messageToWeb(" right in this chat") }}
```

The functions in this section are not simple. In an expression, such a function must stand alone — it can't go inside a condition or another function.
