> ## Documentation Index
> Fetch the complete documentation index at: https://docs.jelou.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Buttons

> Displays interactive buttons for the user to select an option

The **Buttons** node sends a message with buttons that the user can tap to choose an option. It is ideal for guiding the conversation along specific paths without the user having to type.

## General configuration

* **Header**: Message title (maximum 60 characters)
* **Content**: Main message that accompanies the buttons (maximum 1,024 characters on WhatsApp, 640 on Facebook/Instagram)
* **Footer**: Additional text below the content (optional)

### Options

Each button has:

* **Option name**: Text visible on the button (maximum 20 characters)
* **Description**: Additional context text (optional, maximum 72 characters)

You can add up to **3 buttons**. To show more options, use the [List](/guides/nodos/lista) node.

### Button types

| Type         | Behavior                                                            |
| :----------- | :------------------------------------------------------------------ |
| **Postback** | Sends a payload to the flow and continues along the connected route |
| **URL**      | Opens a web page in the browser                                     |
| **Phone**    | Initiates a phone call                                              |

### Dynamic options

If the options come from variable data (for example, a list of products from your API), you can enable **dynamic** mode instead of defining them manually.

Configure:

* **Source variable**: The variable that contains the list (for example, `{{$memory.products}}`)
* **Label template**: How each option is displayed (for example, `{{$item.name}} - ${{$item.price}}`)
* **Description template**: Additional text per option (for example, `{{$item.description}}`)

Available predefined templates: Simple list, Products, Available schedules, Branches.

## Variables in messages

You can use variables in the header and content:

```
Header: Hello {{$user.names}}
Content: Choose an option for {{$memory.category}}
```

## Advanced configuration

### Mandatory selection

When enabled, the user **must** tap a button to continue. If they type free text, they will see a customizable error message (maximum 250 characters).

### Response variable

Saves the option the user selected in a memory variable for later use in the flow.

**How to configure it:**

1. Enable the **Save response** toggle.
2. Enter the variable name (for example, `department`).

#### Value saved with static options

When buttons are defined manually, the **payload** of the chosen button is saved as plain text.

Example with these buttons:

| Button            | Payload   |
| :---------------- | :-------- |
| Sales             | `sales`   |
| Technical Support | `support` |
| Billing           | `billing` |

If the user taps **Technical Support**:

```javascript theme={null}
// {{$memory.department}} contains:
const department = "support";
```

#### Value saved with dynamic options

When buttons are generated from a source variable, the **complete object** from the array to which the selected option belongs is saved.

Suppose `{{$memory.departments}}` contains:

```json theme={null}
[
  { "id": "dep1", "name": "Sales", "email": "sales@company.com" },
  { "id": "dep2", "name": "Support", "email": "support@company.com" },
  { "id": "dep3", "name": "Billing", "email": "billing@company.com" }
]
```

If the user taps **Support**, the variable holds the complete object:

```javascript theme={null}
// {{$memory.department}} contains the complete object:
const department = {
  id: "dep2",
  name: "Support",
  email: "support@company.com"
};
```

You can access each property of the object in subsequent nodes:

```javascript theme={null}
// Accessing properties of {{$memory.department}}:
department.name;   // "Support"
department.email;  // "support@company.com"
department.id;     // "dep2"
```

#### Use cases

<AccordionGroup>
  <Accordion title="Route the flow based on the selection (static options)">
    Connect a [Conditional](/guides/nodos/condicional) node and create a branch for each payload:

    ```
    If {{$memory.department}} = "sales"   → Sales branch
    If {{$memory.department}} = "support" → Support branch
    If {{$memory.department}} = "billing" → Billing branch
    ```
  </Accordion>

  <Accordion title="Use data from the selected object (dynamic options)">
    With the complete object saved, you can use it directly in messages or subsequent nodes without additional queries:

    ```
    Text: "I'll connect you with the {{$memory.department.name}} team.
    Write to them at {{$memory.department.email}}"
    ```
  </Accordion>

  <Accordion title="Personalize the AI Agent response">
    Pass the selection as context to the [AI Agent](/guides/nodos/ai-agent) node:

    ```
    The user selected the department: {{$memory.department.name}}.
    Contact email: {{$memory.department.email}}.
    Respond with specific information for that department.
    ```
  </Accordion>

  <Accordion title="Record the choice in a database">
    Use an [API](/guides/nodos/api) or [Datum](/guides/nodos/datum) node to save the selection:

    ```json theme={null}
    {
      "userId": "{{$user.id}}",
      "departmentId": "{{$memory.department.id}}",
      "departmentName": "{{$memory.department.name}}",
      "timestamp": "{{$context.timestamp}}"
    }
    ```
  </Accordion>
</AccordionGroup>

### Single-use button

After the first selection, the buttons are deactivated. You can configure what happens next:

* **Send text**: Displays an informational message
* **Redirect to workflow**: Takes the user to another flow

### Button expires

If the user does not select any button within the time configured in your organization:

* **Send text**: Displays an expiration message
* **Redirect to workflow**: Takes the user to another flow
