> For the complete documentation index, see [llms.txt](https://docs.hackle.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hackle.io/en/crm-marketing/message-personalization/liquid-template-reference.md).

# Advanced Personalization with Liquid

A list of the Liquid filters and tags you can use when sending messages.

This is a list of the Liquid filters and tags you can use in Hackle CRM campaigns. Tags and filters that are not on this list may not work, and in most cases they are converted to an empty string.

## Available Variables

Through the personalization variable modal in the Dashboard, you can reference values that differ for each user.

| Reference format               | Description                                        |
| ------------------------------ | -------------------------------------------------- |
| `{{ user_properties.<key> }}`  | User Property                                      |
| `{{ event_properties.<key> }}` | Event Property                                     |
| `{{ api_properties.<key> }}`   | API Property                                       |
| `{{ identifiers.<type> }}`     | Identifier (available **only on Webhook channel**) |

Example: `Hello {{ user_properties['name'] }}`

## Common Patterns

### Use a default value when the name is missing

Use fallback text when a variable has no value.

```liquid
Hello {{ user_properties.name | default: 'Customer' }}
```

→ `Hello Customer` (when name is missing)

### Thousands separators for numbers

Display points, amounts, and similar values in a readable form.

Variable: point = 15000

```liquid
{{ event_properties.point | number_with_delimiter }}P
```

→ `15,000P`

### Show a date in Korean time and language

Convert to `Asia/Seoul` and print the weekday in Korean.

Variable: ordered\_at = "2026-07-15 23:00:00 UTC"

```liquid
{{ event_properties.ordered_at | date: '%m월 %d일 %A', 'Asia/Seoul', locale: 'ko' }}
```

→ `07월 16일 목요일`

### Replace values that are too long with fallback text

Values longer than the specified length are replaced entirely.

Variable: name = "Bartholomew" (11 characters)

```liquid
Hello {{ user_properties.name | fallback_over_length: 5, 'Customer' }}
```

→ `Hello Customer`

## Quick Reference

### Filters

| Name                    | Description                                                                                      |
| ----------------------- | ------------------------------------------------------------------------------------------------ |
| append                  | Appends another string to the end of a string.                                                   |
| prepend                 | Prepends another string to the beginning of a string.                                            |
| capitalize              | Capitalizes the first character and leaves the rest unchanged.                                   |
| downcase                | Converts all characters to lowercase.                                                            |
| upcase                  | Converts all characters to uppercase.                                                            |
| lstrip                  | Removes whitespace from the left (beginning) of a string.                                        |
| rstrip                  | Removes whitespace from the right (end) of a string.                                             |
| strip                   | Removes whitespace from both ends of a string.                                                   |
| strip\_html             | Removes HTML tags from a string.                                                                 |
| strip\_newlines         | Removes newline characters from a string.                                                        |
| newline\_to\_br         | Replaces newline characters with `<br />` tags.                                                  |
| remove                  | Removes every occurrence of a substring from a string.                                           |
| remove\_first           | Removes only the first occurrence of a substring from a string.                                  |
| replace                 | Replaces every occurrence of a substring with another string.                                    |
| replace\_first          | Replaces only the first occurrence of a substring with another string.                           |
| split                   | Splits a string on a delimiter to build an array.                                                |
| slice                   | Cuts out part of a string by start position and length.                                          |
| truncate                | Shortens a string to the specified length and appends an ellipsis.                               |
| truncatewords           | Shortens a string to the specified number of words and appends an ellipsis.                      |
| escape                  | Escapes HTML special characters in a string.                                                     |
| escape\_once            | Escapes HTML special characters in a string, without re-escaping parts that are already escaped. |
| abs                     | Returns the absolute value of a number.                                                          |
| at\_least               | Returns the specified minimum if the number is smaller than it.                                  |
| at\_most                | Returns the specified maximum if the number is larger than it.                                   |
| ceil                    | Rounds a number up to an integer.                                                                |
| floor                   | Rounds a number down to an integer.                                                              |
| round                   | Rounds a number to the nearest value.                                                            |
| plus                    | Adds numbers.                                                                                    |
| minus                   | Subtracts numbers.                                                                               |
| times                   | Multiplies numbers.                                                                              |
| divided\_by             | Divides numbers.                                                                                 |
| modulo                  | Returns the remainder of a division.                                                             |
| number\_with\_delimiter | Adds thousands separators (commas) to a number.                                                  |
| compact                 | Removes nil values from an array.                                                                |
| concat                  | Concatenates two arrays.                                                                         |
| first                   | Returns the first element of an array.                                                           |
| last                    | Returns the last element of an array.                                                            |
| join                    | Joins the elements of an array with a delimiter to build a string.                               |
| map                     | Extracts only the specified property value from each element to build a new array.               |
| reverse                 | Reverses the order of an array.                                                                  |
| sort                    | Sorts an array (case-sensitive, uppercase first).                                                |
| sort\_natural           | Sorts an array without regard to case.                                                           |
| uniq                    | Removes duplicate values from an array.                                                          |
| where                   | Keeps only the elements that have the specified property value.                                  |
| size                    | Returns the number of elements in an array, or the length of a string.                           |
| date                    | Converts a date/time value into a string in the specified format.                                |
| url\_encode             | URL-encodes a string.                                                                            |
| url\_decode             | Decodes a URL-encoded string back to its original form.                                          |
| url\_escape             | Escapes only the characters in a string that cannot be used in a URL.                            |
| url\_param\_escape      | Escapes a string for use as a URL query parameter value.                                         |
| json\_escape            | Safely escapes a string for use as a JSON string value.                                          |
| json\_parse             | Parses a JSON string into an object that can be accessed in the template.                        |
| as\_json\_string        | Serializes a value into a JSON string.                                                           |
| default                 | Returns a fallback value when the value is empty or falsy.                                       |
| fallback\_over\_length  | Returns fallback text when the string exceeds the specified length.                              |

### Tags

| Name               | Description                                                                     |
| ------------------ | ------------------------------------------------------------------------------- |
| assign             | Assigns a value to a variable.                                                  |
| capture            | Stores the rendered result of a block in a variable.                            |
| if                 | Renders the block only when the condition is true.                              |
| unless             | Renders the block only when the condition is false.                             |
| case / when        | Renders one of several branches depending on a value.                           |
| for                | Iterates over an array or a range, rendering the block repeatedly.              |
| break              | Immediately exits a for loop.                                                   |
| continue           | Skips the current iteration of a for loop and moves on to the next one.         |
| cycle              | Outputs several values in turn, one per iteration.                              |
| comment            | Does not output the content inside the block.                                   |
| raw                | Outputs the content inside the block as-is, without interpreting Liquid syntax. |
| increment          | Increments and outputs a dedicated counter that starts at 0.                    |
| decrement          | Decrements and outputs a dedicated counter that starts at -1.                   |
| connected\_content | Calls an external API and stores the response (JSON) in a template variable.    |
| random             | Generates and outputs a random number.                                          |

## String Filters

### append

Appends another string to the end of a string.

```liquid
{{ 'Spring breeze' | append: ' blows' }}
```

→ `Spring breeze blows`

### prepend

Prepends another string to the beginning of a string.

```liquid
{{ 'petals' | prepend: 'falling ' }}
```

→ `falling petals`

### capitalize

Capitalizes the first character and leaves the rest unchanged.

```liquid
{{ 'spring bloom' | capitalize }}
```

→ `Spring bloom`

### downcase

Converts all characters to lowercase.

```liquid
{{ 'BLOSSOM' | downcase }}
```

→ `blossom`

### upcase

Converts all characters to uppercase.

```liquid
{{ 'petal' | upcase }}
```

→ `PETAL`

### lstrip

Removes whitespace from the left (beginning) of a string.

```liquid
{% assign s = "  sprout  " %}
[{{ s | lstrip }}]
```

→ `[sprout ]`

### rstrip

Removes whitespace from the right (end) of a string.

```liquid
{% assign s = "  sprout  " %}
[{{ s | rstrip }}]
```

→ `[ sprout]`

### strip

Removes whitespace from both ends of a string.

```liquid
{% assign s = "  sprout  " %}
[{{ s | strip }}]
```

→ `[sprout]`

### strip\_html

Removes HTML tags from a string.

```liquid
{{ '<b>Important</b> notice' | strip_html }}
```

→ `Important notice`

### strip\_newlines

Removes newline characters from a string.

```liquid
{% capture ml %}Summer
is here{% endcapture %}
{{ ml | strip_newlines }}
```

→ `Summeris here`

### newline\_to\_br

Replaces newline characters with `<br />` tags.

```liquid
{% capture ml %}When the cicadas sing
summer has arrived{% endcapture %}
{{ ml | newline_to_br }}
```

→ `When the cicadas sing<br />` `summer has arrived`

### remove

Removes every occurrence of a substring from a string.

```liquid
{{ 'summer night summer night' | remove: 'summer ' }}
```

→ `night night`

### remove\_first

Removes only the first occurrence of a substring from a string.

```liquid
{{ 'summer night summer night' | remove_first: 'summer ' }}
```

→ `night summer night`

### replace

Replaces every occurrence of a substring with another string.

```liquid
{{ 'summer sea, summer sea' | replace: 'sea', 'sky' }}
```

→ `summer sky, summer sky`

### replace\_first

Replaces only the first occurrence of a substring with another string.

```liquid
{{ 'rain-rain-rain' | replace_first: 'rain', 'sun' }}
```

→ `sun-rain-rain`

### split

Splits a string on a delimiter to build an array. Because the result is an array, the example uses `join` as well.

```liquid
{{ 'sea,watermelon,shower' | split: ',' | join: ' / ' }}
```

→ `sea / watermelon / shower`

### slice

Cuts out part of a string by start position and length.

Signature: `slice: start[, length]`

{% tabs %}
{% tab title="From the start" %}

```liquid
{{ 'summer sea' | slice: 0, 6 }}
```

→ `summer`
{% endtab %}

{% tab title="From the end (negative)" %}

```liquid
{{ 'summer sea' | slice: -3, 3 }}
```

→ `sea`
{% endtab %}
{% endtabs %}

### truncate

Shortens a string to the specified length and appends an ellipsis.

Signature: `truncate: length[, ellipsis]`

```liquid
{{ 'The autumn sky is high and blue' | truncate: 17 }}
```

→ `The autumn sky...`

Note: the ellipsis counts toward the length — with the default ellipsis (`...`), the visible body is `length - 3` characters, and if you specify your own ellipsis, its length is subtracted instead.

### truncatewords

Shortens a string to the specified number of words and appends an ellipsis.

Signature: `truncatewords: word_count[, ellipsis]`

```liquid
{{ 'Leaves turn red and fall in autumn' | truncatewords: 3 }}
```

→ `Leaves turn red...`

### escape

Escapes HTML special characters in a string.

```liquid
{{ '<a href="x">link</a>' | escape }}
```

→ `&lt;a href=&quot;x&quot;&gt;link&lt;/a&gt;`

### escape\_once

Escapes HTML special characters in a string, without re-escaping parts that are already escaped.

```liquid
{% assign e = "&lt;p&gt; & <p>" %}
{{ e | escape_once }}
```

→ `&lt;p&gt; &amp; &lt;p&gt;`

## Number Filters

### abs

Returns the absolute value of a number.

```liquid
{% assign n = -5 %}
{{ n | abs }}
```

→ `5`

### at\_least

Returns the specified minimum if the number is smaller than it.

```liquid
{{ 3 | at_least: 5 }}
```

→ `5`

### at\_most

Returns the specified maximum if the number is larger than it.

```liquid
{{ 9 | at_most: 5 }}
```

→ `5`

### ceil

Rounds a number up to an integer.

```liquid
{{ 1.2 | ceil }}
```

→ `2`

### floor

Rounds a number down to an integer.

```liquid
{{ 1.8 | floor }}
```

→ `1`

### round

Rounds a number to the nearest value.

Signature: `round: [decimal_places]`

{% tabs %}
{% tab title="Integer rounding" %}

```liquid
{{ 2.7 | round }}
```

→ `3`
{% endtab %}

{% tab title="Decimal places" %}

```liquid
{{ 3.14159 | round: 2 }}
```

→ `3.14`
{% endtab %}
{% endtabs %}

### plus

Adds numbers.

```liquid
{{ 100 | plus: 25 }}
```

→ `125`

### minus

Subtracts numbers.

```liquid
{{ 100 | minus: 25 }}
```

→ `75`

### times

Multiplies numbers.

```liquid
{{ 100 | times: 3 }}
```

→ `300`

### divided\_by

Divides numbers.

{% tabs %}
{% tab title="Integer division" %}

```liquid
{{ 10 | divided_by: 3 }}
```

→ `3`
{% endtab %}

{% tab title="Float division" %}

```liquid
{{ 10 | divided_by: 3.0 }}
```

→ `3.3333333333333335`
{% endtab %}
{% endtabs %}

Note: dividing integers yields an integer quotient (the decimal part is dropped). If you need a decimal result, divide by a float such as `3.0`.

### modulo

Returns the remainder of a division.

```liquid
{{ 10 | modulo: 3 }}
```

→ `1`

### number\_with\_delimiter

Adds thousands separators (commas) to a number.

```liquid
{{ 1234567.89 | number_with_delimiter }}
```

→ `1,234,567.89`

## Array Filters

### compact

Removes nil values from an array.

```liquid
{% assign arr = '["maple", null, "leaf"]' | json_parse %}
{{ arr | compact | join: ',' }}
```

→ `maple,leaf`

### concat

Concatenates two arrays.

```liquid
{% assign a = 'a,b' | split: ',' %}{% assign b = 'c' | split: ',' %}{{ a | concat: b | join: ',' }}
```

→ `a,b,c`

### first

Returns the first element of an array.

```liquid
{% assign fruits = "apple,persimmon,chestnut" | split: "," %}
{{ fruits | first }}
```

→ `apple`

### last

Returns the last element of an array.

```liquid
{% assign fruits = "apple,persimmon,chestnut" | split: "," %}
{{ fruits | last }}
```

→ `chestnut`

### join

Joins the elements of an array with a delimiter to build a string.

```liquid
{% assign fruits = "apple,persimmon,chestnut" | split: "," %}
{{ fruits | join: ', ' }}
```

→ `apple, persimmon, chestnut`

### map

Extracts only the specified property value from each element to build a new array.

```liquid
{% assign blossoms = '[{"name":"maple","color":"red"},{"name":"ginkgo","color":"yellow"}]' | json_parse %}
{{ blossoms | map: 'name' | join: ', ' }}
```

→ `maple, ginkgo`

### reverse

Reverses the order of an array.

```liquid
{% assign fruits = "apple,persimmon,chestnut" | split: "," %}
{{ fruits | reverse | join: ',' }}
```

→ `chestnut,persimmon,apple`

### sort

Sorts an array (case-sensitive, uppercase first).

```liquid
{% assign u = "Banana,apple,Cherry" | split: "," %}
{{ u | sort | join: ',' }}
```

→ `Banana,Cherry,apple`

Note: sort is case-sensitive (uppercase first), while sort\_natural ignores case — the output above shows the difference.

### sort\_natural

Sorts an array without regard to case.

```liquid
{% assign u = "Banana,apple,Cherry" | split: "," %}
{{ u | sort_natural | join: ',' }}
```

→ `apple,Banana,Cherry`

### uniq

Removes duplicate values from an array.

```liquid
{% assign dup = "a,b,a" | split: "," %}
{{ dup | uniq | join: ',' }}
```

→ `a,b`

### where

Keeps only the elements that have the specified property value.

Signature: `where: property[, value]`

```liquid
{% assign blossoms = '[{"name":"camellia","season":"winter"},{"name":"plum blossom","season":"spring"}]' | json_parse %}
{{ blossoms | where: 'season', 'winter' | map: 'name' | join: ',' }}
```

→ `camellia`

### size

Returns the number of elements in an array, or the length of a string.

{% tabs %}
{% tab title="Array" %}

```liquid
{% assign fruits = "tangerine,citron,dried persimmon" | split: "," %}
{{ fruits | size }}
```

→ `3`
{% endtab %}

{% tab title="String" %}

```liquid
{{ 'snowy night' | size }}
```

→ `11`
{% endtab %}
{% endtabs %}

## Date Filters

### date

Converts a date/time value into a string in the specified format.

Signature: `date: format[, timezone][, locale: "language_tag"]`

{% tabs %}
{% tab title="Basic" %}

```liquid
{{ '2026-07-16 10:30:00' | date: '%B %d, %Y %H:%M' }}
```

→ `July 16, 2026 10:30`
{% endtab %}

{% tab title="Time zone" %}

```liquid
{{ '2026-07-15 23:00:00 UTC' | date: '%Y-%m-%d %H:%M', 'Asia/Seoul' }}
```

→ `2026-07-16 08:00`
{% endtab %}

{% tab title="Korean weekday" %}

```liquid
{{ '2026-07-16 10:30:00' | date: '%A', locale: 'ko' }}
```

→ `목요일`
{% endtab %}

{% tab title="Time zone + weekday" %}

```liquid
{{ '2026-07-15 23:00:00 UTC' | date: '%m월 %d일 %A', 'Asia/Seoul', locale: 'ko' }}
```

→ `07월 16일 목요일`
{% endtab %}

{% tab title="epoch" %}

```liquid
{{ 1784165400 | date: '%Y-%m-%d %H:%M', 'Asia/Seoul' }}
```

→ `2026-07-16 10:30`
{% endtab %}
{% endtabs %}

Note:

* An ISO `Z` suffix on a date string is not parsed (`2026-07-16T10:30:00Z` ✗) — use a space-separated zone (`2026-07-16 10:30:00 UTC`) or a format without a zone.
* Numeric input is interpreted in epoch **seconds**.
* timezone supports TZ names (`Asia/Seoul`) and ISO offsets (`+09:00`), but not numeric minute offsets (360).
* An invalid timezone or locale causes only that parameter to be ignored.
* timezone (a positional argument) and `locale:` (a named argument) can be used together, in any order.

## URL Filters

### url\_encode

URL-encodes a string.

```liquid
{{ 'user@example.com' | url_encode }}
```

→ `user%40example.com`

### url\_decode

Decodes a URL-encoded string back to its original form.

```liquid
{{ 'hello+world%21' | url_decode }}
```

→ `hello world!`

### url\_escape

Escapes only the characters in a string that cannot be used in a URL.

```liquid
{{ 'https://example.com/search?q=hello world' | url_escape }}
```

→ `https://example.com/search?q=hello%20world`

### url\_param\_escape

Escapes a string for use as a URL query parameter value.

```liquid
{{ 'query A&B' | url_param_escape }}
```

→ `query+A%26B`

## JSON Filters

### json\_escape

Safely escapes a string for use as a JSON string value.

```liquid
{% assign quote = 'He said "hello"' %}
{{ quote | json_escape }}
```

→ `He said \"hello\"`

### json\_parse

Parses a JSON string into an object that can be accessed in the template.

```liquid
{% assign payload = '{"user":{"name":"Alex","point":1500}}' %}
{% assign d = payload | json_parse %}{{ d.user.name }}'s points: {{ d.user.point }}
```

→ `Alex's points: 1500`

Note: if parsing fails, the result is nil and rendering continues.

### as\_json\_string

Serializes a value into a JSON string.

```liquid
{% assign obj = '{"name":"Alex","point":1500}' | json_parse %}
{{ obj | as_json_string }}
```

→ `{"name":"Alex","point":1500}`

## Other Filters

### default

Returns a fallback value when the value is empty or falsy.

Signature: `default: default_value`

```liquid
Hello {{ nickname | default: 'traveler' }}
```

→ `Hello traveler`

### fallback\_over\_length

Returns fallback text when the string exceeds the specified length.

Signature: `fallback_over_length: max_length, fallback_text`

{% tabs %}
{% tab title="Over the length" %}

```liquid
{{ 'snowflakes' | fallback_over_length: 5, 'traveler' }}
```

→ `traveler`
{% endtab %}

{% tab title="Within the length" %}

```liquid
{{ 'snow' | fallback_over_length: 5, 'traveler' }}
```

→ `snow`
{% endtab %}
{% endtabs %}

Note: length is measured in UTF-16 code units (the same as the `size` filter).

## Tags

### assign

Assigns a value to a variable.

```liquid
{% assign name = 'Hackle' %}Hello {{ name }}
```

→ `Hello Hackle`

### capture

Stores the rendered result of a block in a variable.

```liquid
{% assign name = 'Alex' %}
{% capture greeting %}Welcome, {{ name }}{% endcapture %}{{ greeting }}
```

→ `Welcome, Alex`

### if

Renders the block only when the condition is true.

```liquid
{% assign point = 1500 %}
{% if point >= 1000 %}VIP benefits{% else %}Standard benefits{% endif %}
```

→ `VIP benefits`

### unless

Renders the block only when the condition is false.

```liquid
{% assign subscribed = false %}
{% unless subscribed %}Start your subscription{% endunless %}
```

→ `Start your subscription`

### case / when

Renders one of several branches depending on a value.

```liquid
{% assign grade = 'gold' %}
{% case grade %}{% when 'gold' %}Gold benefits{% when 'silver' %}Silver benefits{% else %}Default benefits{% endcase %}
```

→ `Gold benefits`

### for

Iterates over an array or a range, rendering the block repeatedly.

```liquid
{% assign fruits = "tangerine,citron,dried persimmon" | split: "," %}
{% for f in fruits %}{{ f }} {% endfor %}
```

→ `tangerine citron dried persimmon`

### break

Immediately exits a for loop.

```liquid
{% for i in (1..5) %}{% if i > 3 %}{% break %}{% endif %}{{ i }}{% endfor %}
```

→ `123`

### continue

Skips the current iteration of a for loop and moves on to the next one.

```liquid
{% for i in (1..5) %}{% if i == 3 %}{% continue %}{% endif %}{{ i }}{% endfor %}
```

→ `1245`

### cycle

Outputs several values in turn, one per iteration.

```liquid
{% for i in (1..4) %}{% cycle 'A', 'B' %}{% endfor %}
```

→ `ABAB`

### comment

Does not output the content inside the block.

```liquid
before{% comment %}This content is not rendered{% endcomment %}after
```

→ `beforeafter`

### raw

Outputs the content inside the block as-is, without interpreting Liquid syntax.

```liquid
{% raw %}{{ name }} is not substituted{% endraw %}
```

→ `{{ name }} is not substituted`

### increment

Increments and outputs a dedicated counter that starts at 0.

```liquid
{% increment counter %}-{% increment counter %}-{% increment counter %}
```

→ `0-1-2`

Note: increment starts at 0 and decrement starts at -1, and both use a counter that is separate from `assign` variables.

### decrement

Decrements and outputs a dedicated counter that starts at -1.

```liquid
{% decrement counter %}-{% decrement counter %}
```

→ `-1--2`

## Other Tags

### connected\_content

Calls an external API and stores the response (JSON) in a template variable.

For detailed usage and limits (timeout, response size cap, allowed protocols and addresses, and so on), see [Writing Connected Content](/en/crm-marketing/message-personalization/connected-content.md).

Signature: `{% connected_content <url> [:method <method>] [:body <body>] [:headers <json>] [:save <variable>] %}`

```liquid
{% connected_content https://api.example.com/users/{{ user.id }} :save profile %}
Hi {{ profile.name }}, check out today's recommended products
```

→ `Hi Alex, check out today's recommended products` (assuming the API responded with {"name": "Alex"})

Note: an actual HTTP call is made at render time. The output above is an example based on the assumed response.

### random

Generates and outputs a random number. Pass a positive integer to get a random integer that is 0 or greater and less than that value.

{% tabs %}
{% tab title="Float (0 to 1)" %}

```liquid
{% random %}
```

→ `0.250538241955663` (differs on every run)
{% endtab %}

{% tab title="Integer in a range" %}

```liquid
{% random 10 %}
```

→ `7` (differs on every run)
{% endtab %}

{% tab title="Example: rolling a die" %}
**Rolling a die (1\~6)** — to store the drawn value in a variable and reuse it, capture it with `capture` and convert it to a number with `plus`. `{% random 6 %}` returns 0-5, so `plus: 1` makes it 1-6.

```liquid
{% capture dice %}{% random 6 %}{% endcapture %}{{ dice | plus: 1 }}
```

→ `4` (differs on every run)
{% endtab %}
{% endtabs %}


---

# 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://docs.hackle.io/en/crm-marketing/message-personalization/liquid-template-reference.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.
