> For the complete documentation index, see [llms.txt](https://support.closer.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://support.closer.app/guide/getting-deeper/forms-configuration.md).

# Forms configuration

## Form model

#### Form DTO fields:

* `id` - \[string] uuid of form
* `orgId` - \[string] uuid of organization
* `locale` - \[string] locale which the form was created for
* `availableForAgents` - \[boolean] determines whether agents can access and send the form
* `name` - \[string] name of the form
* `config` - \[object] configuration of the form's inputs (see input types below)
* `expireInterval` - (optional)\[number] - milliseconds after which the form can no longer be submitted
* `sendInterval` - (optional)\[number] - milliseconds after which the form can be sent again
* `blockIfPreviousUnsubmitted` - \[boolean] - determines whether the form can be sent if previous has not been submitted yet
* `routeOnSubmit` - \[boolean] - determines whether submitting the form should result in opening and assignment of the conversation
* `tagGroupIds` - list\[string] - list of tag group's uuids. Form will be available only in rooms with one of the given `tagGroupIds`. Form with empty `tagGroupIds` is available in any room

## Inputs form

{% hint style="info" %}
Use this form to collect information
{% endhint %}

#### Config (inputs) fields:

* `radioButtonsInputs` - array of objects representing radio buttons input
* `multipleButtonsInputs` - array of objects representing multiple buttons input
* `radioListInputs` - array of objects representing radio list input
* `checkboxListInputs` - array of objects representing checkbox list input
* `textInputs` - array of objects representing text input

### **Buttons (multiple choice)**

`multipleButtonsInputs`

![Mulitple buttons input](/files/lHZEfIyRTCUt98nbVDgh)

<details>

<summary>Click here to see the code</summary>

The input above is represented by the following object:

```json
{
    "index": 0,
    "name": "conversation_expectation",
    "displayName": "I expect the conversation to be:",
    "buttons": [
        {
            "value": "quick",
            "displayName": "Quick"
        },
        {
            "value": "nice",
            "displayName": "Nice & kind"
        },
        {
            "value": "helpful",
            "displayName": "Helpful"
        }
    ]
}
```

</details>

### Buttons (single choice)

`radioButtonsInputs`

![Radio buttons input](/files/kysNpRI7YUWtydJEjUA1)

<details>

<summary>Click here to see the code</summary>

The input above is represented by the following object:

```
{
    "index": 1,
    "name": "device_type",
    "displayName": "I have a problem with my:",
    "buttons": [
        {
            "value": "phone",
            "displayName": "Phone"
        },
        {
            "value": "laptop",
            "displayName": "Laptop"
        },
        {
            "value": "elbow",
            "displayName": "Elbow"
        }
    ]
}
```

</details>

### Radio input with list of options (single choice)

`radioListInputs`

![Radio list input](/files/nUXjNEl6fxr50veLvxSO)

<details>

<summary>Click here to see the code</summary>

The input above is represented by the following object:

```
{
    "index": 2,
    "name": "timeline",
    "displayName": "I have been a customer for:",
    "options": [
        {
            "value": "under_six_months",
            "displayName": "<= 6 months"
        },
        {
            "value": "six_months_to_two_years",
            "displayName": "<= 2 years"
        },
        {
            "value": "longer",
            "displayName": "> 2 years"
        }
    ]
}
```

</details>

### Input with list of options (multiple choice)

`checkboxListInputs`

![Checkbox list input](/files/gUicNn7Ghj9cDYwT1duK)

<details>

<summary>Click here to see the code</summary>

The input above is represented by the following object:

```
{
    "index": 3,
    "name": "favorite_colors",
    "displayName": "Colors I like:",
    "options": [
        {
            "value": "white",
            "displayName": "White"
        },
        {
            "value": "black",
            "displayName": "Black"
        },
        {
            "value": "yellow",
            "displayName": "Yellow"
        }
    ]
}
```

</details>

### Text input

`textInputs`

![Text input](/files/HmaEPEoAW2qDekQucBmj)

<details>

<summary>Click here to see the code</summary>

The input above is represented by the following object:

```
{
    "index": 4,
    "name": "language_name",
    "displayName": "The best programming language is:",
    "placeholder": "Type language name here..."
}
```

</details>

### Full example

Inputs order in the form is determined by \`index\` property of representing object

<details>

<summary>Click here to see form with inputs represented above</summary>

```
{
    "id": "0b05797b-a15b-42a5-96ec-XXXXXXXXXXXX",
    "orgId": "95a25389-5b2f-4b43-a311-XXXXXXXXXXXX",
    "locale": "en",
    "config": {
        "radioButtonsInputs": [
            {
                "index": 1,
                "name": "device_type",
                "displayName": "I have a problem with my:",
                "buttons": [
                    {
                        "value": "phone",
                        "displayName": "Phone"
                    },
                    {
                        "value": "laptop",
                        "displayName": "Laptop"
                    },
                    {
                        "value": "elbow",
                        "displayName": "Elbow"
                    }
                ]
            }
        ],
        "multipleButtonsInputs": [
            {
                "index": 0,
                "name": "conversation_expectation",
                "displayName": "I expect the conversation to be:",
                "buttons": [
                    {
                        "value": "quick",
                        "displayName": "Quick"
                    },
                    {
                        "value": "nice",
                        "displayName": "Nice & kind"
                    },
                    {
                        "value": "helpful",
                        "displayName": "Helpful"
                    }
                ]
            }
        ],
        "radioListInputs": [
            {
                "index": 2,
                "name": "timeline",
                "displayName": "I have been a customer for:",
                "options": [
                    {
                        "value": "under_six_months",
                        "displayName": "<= 6 months"
                    },
                    {
                        "value": "six_months_to_two_years",
                        "displayName": "<= 2 years"
                    },
                    {
                        "value": "longer",
                        "displayName": "> 2 years"
                    }
                ]
            }
        ],
        "checkboxListInputs": [
            {
                "index": 3,
                "name": "favorite_colors",
                "displayName": "Colors I like:",
                "options": [
                    {
                        "value": "white",
                        "displayName": "White"
                    },
                    {
                        "value": "black",
                        "displayName": "Black"
                    },
                    {
                        "value": "yellow",
                        "displayName": "Yellow"
                    }
                ]
            }
        ],
        "textInputs": [
            {
                "index": 4,
                "name": "name",
                "displayName": "The best programming language is:",
                "placeholder": "Type language name here..."
            }
        ]
    },
    "availableForAgents": true,
    "name": "Problem questionaire",
    "expireInterval": 60000,
    "sendInterval": 10000,
    "blockIfPreviousUnsubmitted": true,
    "routeOnSubmit": false
}
```

</details>

## Auto assign form

{% hint style="info" %}
Use this form to route clients' conversations based on their choice
{% endhint %}

![Auto assign form](/files/HlNXC6231txECLJXFfQu)

<details>

<summary>Click here to see form configuration</summary>

The form above is represented by the following object:

```
{
    "id": "2909d885-d34c-49b9-8e8e-XXXXXXXXXXXX",
    "orgId": "d90482fe-17bf-48d5-aa75-XXXXXXXXXXXX",
    "locale": "en",
    "config": {
        "type": "auto_assign_form",
        "tagGroups": [
            {
                "tagGroupId": "23b133fa-f2d1-4140-bddc-XXXXXXXXXXXX",
                "displayName": "First tag group"
            },
            {
                "tagGroupId": "c0f47b47-8269-4002-9734-XXXXXXXXXXXX",
                "displayName": "Second tag group"
            },
            {
                "tagGroupId": "c972191f-ddea-40df-bbbe-XXXXXXXXXXXX",
                "displayName": "Third tag group"
            }
        ]
    },
    "availableForAgents": true,
    "name": "assignment_form",
}
```

</details>

## &#x20;Predefined message form

Predefined message is a  form to send simple text without any inputs as a adviser message. Form configuration accepts the only property `` message` ``. Such form could be used to send links and messages with additional conversation data:

* {{roomId}} - conversation room id

![Predefined meesage](/files/uUDdp40NNwPg41cE9255)

<details>

<summary>Click here to see form configuration</summary>

The form above is represented by the following object:

```
{
    "id": "b5cb64ec-9d85-4fe1-8df7-c8a4b8131b2d",
    "orgId": "95a25389-5b2f-4b43-a311-7625f73da813",
    "locale": "pl",
    "config": {
        "type": "predefined_message_form",
        "message": "Simple predefined message with in room id = {{roomId}}"
    },
    "availableForAgents": true,
    "name": "Simple message",
    "routeOnSubmit": false
}
```

</details>

## API

#### Create

**`POST - /api/message-widgets`**

* Creates new form
* Requires apiKey header of an adviser with `settings_action_forms` permission
* Requires body with following fields:
  * required: `locale`, `name`, `availableForAgents`, `config` (described above), `blockIfPreviousUnsubmitted`, `routeOnSubmit`
  * optional: `expireInterval`, `sendInterval`

<details>

<summary>Click here to see an example</summary>

```
Example
curl --location --request POST 'https://spinner.closer.app/api/message-widgets' \
--header 'x-api-key: your-api-key-here' \
--header 'Content-Type: application/json' \
--data-raw '{
    "locale": "en",
    "name": "a_problem_questionaire",
    "availableForAgents": true,
    "config": {
        "textInputs": [
            {
                "index": 0,
                "name": "best_language",
                "displayName": "The best programming language is:",
                "placeholder": "Type language name here..."
            }
        ]
    },
    "blockIfPreviousUnsubmitted": true,
    "routeOnSubmit": true
}'
```

</details>

#### Update

**`PUT - /api/message-widgets/{messageWidgetId}`**

* Updates existing form
* Requires apiKey header of an adviser with `settings_action_forms` permission
* Requires body with the same schema as POST request, but without `locale`

<details>

<summary>Click here to see an example</summary>

```
Example
curl --location --request PUT 'https://spinner.closer.app/api/message-widgets/d7f68940-e47f-4cd3-bc99-79e112749559' \
--header 'x-api-key: your-api-key-here' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "a_problem_questionaire",
    "availableForAgents": false,
    "config": {
        "textInputs": [
            {
                "index": 0,
                "name": "best_language",
                "displayName": "The best programming language is:",
                "placeholder": "Type language name here..."
            }
        ]
    },
    "blockIfPreviousUnsubmitted": true,
    "routeOnSubmit": true
}'
```

</details>

#### Read

**`GET - /api/message-widgets?locale={locale}`**

* Gets all created forms' DTOs
* Requires apiKey of organization's adviser

<details>

<summary>Click here to see an example</summary>

```
Example
curl --location --request GET 'https://spinner.stage.closer.app/api/message-widgets?locale=en' \
--header 'x-api-key: your-api-key-here'
```

</details>

**`GET - /api/message-widgets/{messageWidgetId}?orgId={orgId}`**

* Gets single form DTO
* Does not require authentication

<details>

<summary>Click here to see an example</summary>

```
Example
curl --location --request GET 'https://spinner.closer.app/api/message-widgets/0b05797b-a15b-42a5-96ec-fd821456c69e?orgId=95a25389-5b2f-4b43-a311-7625f73da813
```

</details>
