> For the complete documentation index, see [llms.txt](https://guide.tiledesk.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://guide.tiledesk.com/ai-chatbots-and-automation/actions-explained/json-condition.md).

# JSON Condition

## JSON Condition Action

The JSON Condition action is the **decision point** of your chatbot. It looks at the value of one or more attributes (data collected during the conversation, returned by an API, produced by the AI, etc.) and routes the flow down one of two branches: **MATCH** when the conditions are met, or **Else** when they are not. Think of it as the *if / then / else* of your automation: it lets you personalize the experience, validate user input, branch on a language, a score, the length of an array, and much more — all without writing code.

Like every action, the JSON Condition has two views:

* **Action preview** — the compact card you see on the canvas, which summarizes the conditions and shows the two output connectors (the green **true** branch and the **Else** branch).
* **Action editor** — the panel that opens when you click the action, where you build the conditions.

<figure><img src="/files/LtrFjFpFcjyPoHAMXcgu" alt=""><figcaption></figcaption></figure>

***

### How it works

1. Add the **JSON Condition** action to a block.
2. Build one or more conditions in the editor (see below).
3. Connect the **MATCH** output to the block that should run when the conditions are **true**.
4. Connect the **Else** output to the block that should run when they are **false**.

At runtime the chatbot evaluates the conditions:

* if the result is **true** → it follows the **MATCH** branch;
* if the result is **false** → it follows the **Else** branch.

***

### Building a condition

Each condition is made of three parts, shown in the editor as **Attribute name**, **Condition**, and **Value**.

> *Screenshot: the "Custom Attribute" editor with the Attribute name, Condition and Value fields.*

<figure><img src="/files/XO6jC9d4Lx3pmpBWX7JS" alt=""><figcaption></figcaption></figure>

#### 1. Attribute name

This is the **left side** of the comparison — the attribute whose value you want to check. You can:

* **type it** directly, or
* **pick it** from the attribute list using the `{ }` button (it inserts the attribute for you), then edit it freely.

Click the **ⓘ** icon next to *Attribute name* for a quick reminder of the syntax. You can reference simple attributes, nested properties and array elements:

| You write               | Meaning                                      |
| ----------------------- | -------------------------------------------- |
| `email`                 | a simple attribute                           |
| `user.name`             | a nested property                            |
| `people[0]`             | the **first** element of an array            |
| `people[0].name`        | the *name* of the first element of an array  |
| `kb_json_sources[2].id` | nested properties and array indexes combined |

> **Note** — write the attribute **without** the `{{ }}` braces here: just `user.name`, not `{{user.name}}`.

#### 2. Condition

This is the **operator** — *how* you want to compare the attribute. Operators are grouped by the **type of data** you are working with (Existence, Text, Number, Boolean, Date & Time, Array), so you can pick the right comparison for the value at hand.

There is **no default operator**: when you open a new condition the field is empty and you must choose one. See the full Operators reference below.

> **Tip** — the same value can be compared in different ways. For a chunk count, *“is equal to (number)”* compares it as a number (`5 == 5`), while *“is equal to (text)”* compares it as text (`"5" == "5"`). Choose the operator whose type matches your intent.

#### 3. Value

This is the **right side** of the comparison. Depending on the operator you can:

* type a **fixed value** (a constant) — e.g. `Roma`, `18`, `2026-01-01`; or
* click the `{ }` button to compare against **another attribute** (a variable), e.g. compare `user.city` with `user.preferredCity`.

Some operators are **unary** — they don’t need a value (for example *is empty*, *exists*, *is true*). For those the **Value** field is hidden automatically.

When the condition is complete, press **Apply Condition**. The button stays disabled until you have chosen an attribute, an operator and (when required) a value.

***

### Combining conditions

A single JSON Condition can evaluate **many** conditions together.

#### AND / OR inside a group

Add more rows to combine conditions with the **AND** / **OR** connector that appears between them:

* **AND** → *all* the joined conditions must be true.
* **OR** → *at least one* must be true.

Standard precedence applies: **AND binds tighter than OR**, so `A AND B OR C` is read as `(A AND B) OR C`.

#### Condition groups

Use **Add conditions group** to create separate groups. Each group is evaluated as a unit and the groups are combined with their own AND / OR connector — this lets you express logic like:

```
(country == "IT" AND age >= 18)  OR  (vip == true)
```

***

### Operators reference

Below are all the available operators, grouped by data type, with a concrete example. `x` is the attribute (left side), values in quotes are text, bare numbers are numbers.

#### Existence (no value needed)

| Operator       | Meaning                                             | Example                 |
| -------------- | --------------------------------------------------- | ----------------------- |
| exists         | the attribute is present (even if empty/null)       | `email` exists          |
| does not exist | the attribute is not present                        | `coupon` does not exist |
| is empty       | empty string, empty array/object, or null/undefined | `cart` is empty         |
| is not empty   | has some content                                    | `cart` is not empty     |
| is null        | the value is exactly `null`                         | `middleName` is null    |
| is undefined   | the value is exactly `undefined`                    | `nickname` is undefined |

#### Text (compared as text, case-sensitive)

| Operator               | Example                                |
| ---------------------- | -------------------------------------- |
| is equal to (text)     | `user.city == "Roma"`                  |
| is not equal to (text) | `user.city != "Roma"`                  |
| contains               | `message` contains `"invoice"`         |
| does not contain       | `message` does not contain `"invoice"` |
| starts with            | `lang` starts with `"it"`              |
| does not start with    | `lang` does not start with `"it"`      |
| ends with              | `file` ends with `".pdf"`              |
| does not end with      | `file` does not end with `".pdf"`      |
| matches regex          | `email` matches `"^.+@.+$"`            |
| does not match regex   | `email` does not match `"^.+@.+$"`     |

#### Number (compared as numbers)

| Operator                    | Example          |
| --------------------------- | ---------------- |
| is equal to (number)        | `kb_chunks == 5` |
| is not equal to (number)    | `count != 0`     |
| is greater than             | `age > 18`       |
| is greater than or equal to | `age >= 18`      |
| is less than                | `score < 100`    |
| is less than or equal to    | `score <= 100`   |

#### Boolean (no value needed)

| Operator | Example            |
| -------- | ------------------ |
| is true  | `consent` is true  |
| is false | `consent` is false |

#### Date & Time (value = a date, e.g. `2026-01-01`)

| Operator               | Example                                        |
| ---------------------- | ---------------------------------------------- |
| is equal to (date)     | `createdAt` is equal to `2026-06-15`           |
| is not equal to (date) | `createdAt` is not equal to `2026-06-15`       |
| is after               | `createdAt` is after `2026-01-01`              |
| is before              | `createdAt` is before `2026-01-01`             |
| is after or equal to   | `createdAt` is after or equal to `2026-01-01`  |
| is before or equal to  | `createdAt` is before or equal to `2026-01-01` |

#### Array

| Operator                        | Meaning                                | Example                                      |
| ------------------------------- | -------------------------------------- | -------------------------------------------- |
| contains (array)                | the array contains the element         | `tags` contains `"vip"`                      |
| does not contain (array)        | the array does not contain the element | `tags` does not contain `"vip"`              |
| length equal to                 | number of elements == value            | `people` length equal to `0`                 |
| length not equal to             | number of elements != value            | `people` length not equal to `0`             |
| length greater than             | more than N elements                   | `people` length greater than `0`             |
| length less than                | fewer than N elements                  | `people` length less than `3`                |
| length greater than or equal to | at least N elements                    | `people` length greater than or equal to `1` |
| length less than or equal to    | at most N elements                     | `people` length less than or equal to `5`    |

***

### Concrete examples

#### Example 1 — Route by language

Send Italian users to a dedicated flow.

1. **Attribute name**: `lang`
2. **Condition**: *starts with*
3. **Value**: `it`
4. Connect **MATCH** → Italian welcome block, **Else** → default welcome block.

#### Example 2 — Check the knowledge base returned results

Branch depending on whether the AI retrieved any chunks.

1. **Attribute name**: `kb_chunks`
2. **Condition**: *is greater than* (number)
3. **Value**: `0`
4. **MATCH** → answer from KB, **Else** → fallback “I couldn’t find anything” message.

#### Example 3 — Validate input is an adult

1. **Attribute name**: `user.age`
2. **Condition**: *is greater than or equal to* (number)
3. **Value**: `18`
4. **MATCH** → continue, **Else** → “Sorry, you must be 18+”.

#### Example 4 — The array has at least one element

Useful right after an API call that returns a list.

1. **Attribute name**: `results`
2. **Condition**: *length greater than*
3. **Value**: `0`
4. **MATCH** → show results, **Else** → “No results found”.

#### Example 5 — Required field is filled in

1. **Attribute name**: `user.email`
2. **Condition**: *is not empty* (no value needed)
3. **MATCH** → continue, **Else** → ask for the email again.

#### Example 6 — Multiple conditions with groups

Greet VIPs, or adults from Italy:

* **Group 1**: `country` *is equal to (text)* `IT` **AND** `age` *is greater than or equal to (number)* `18`
* **OR**
* **Group 2**: `vip` *is true*

```
(country == "IT" AND age >= 18) OR (vip == true)
```

#### Example 7 — Compare two attributes

Check that the confirmed city matches the chosen one (the right side is a variable, not a fixed text).

1. **Attribute name**: `user.city`
2. **Condition**: *is equal to (text)*
3. **Value**: click `{ }` and pick `user.preferredCity`
4. **MATCH** → proceed, **Else** → ask the user to confirm.

***

### How conditions are evaluated

A few rules worth knowing, so your conditions behave as expected:

* **Type matters.** The operator decides how both sides are compared. *“is equal to (number)”* compares numbers (`"11"` and `11` are equal), while *“is equal to (text)”* compares text (`"11"` and `11` are equal as the text `"11"`). Pick the operator that matches the data type you want.
* **Text comparisons are case-sensitive.** `"Roma"` is different from `"roma"`. (Older *ignore-case* operators have been removed; legacy chatbots that used them now behave as the case-sensitive equivalent.)
* **A failed comparison is never an error.** If an attribute is missing or a value can’t be converted to the expected type, that single condition is simply treated as **false** — the chatbot won’t crash and will follow the **Else** branch.

***

### Notes

* The **Condition** field has no preset value: you always choose the operator explicitly.
* Write attribute names **without** `{{ }}` braces in the *Attribute name* field.
* The right-side **Value** can be a fixed value or another attribute (pick it with the `{ }` button).
* Need help with the syntax? Use the **ⓘ** icon next to *Attribute name*.

***


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://guide.tiledesk.com/ai-chatbots-and-automation/actions-explained/json-condition.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
