> For the complete documentation index, see [llms.txt](https://docs.akinon.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.akinon.com/tutorials/instore/instore-dynamic-agreements.md).

# Instore Dynamic Agreements

Dynamic Agreements is an Instore widget that manages the agreements shown on the **Create a New Customer** screen. Each agreement can be displayed as a **modal**, a **link**, or plain **text**, and a single agreement can contain multiple links and send multiple parameter names. The legacy single-link, single-name setup is still supported.

<figure><img src="https://3333414532-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIbwGN7KwvYi0iLbjtnXz%2Fuploads%2FXfoPRcunwaiGSjIvT2Yy%2F01-new-customer-screen.png?alt=media&amp;token=ee58b4b5-4a32-4492-8725-97fc78d3fec4" alt=""><figcaption></figcaption></figure>

In this tutorial, you will:

1. Create the widget schema in Omnitron.
2. Create the widget and add agreements to it.
3. Enable dynamic agreements in Instore.

## Prerequisites

* Access to Omnitron with permission to manage widget schemas and widgets for the relevant sales channel.
* Access to the Instore **Settings** menu.

## Step 1: Create the widget schema

1. In Omnitron, go to **Sales Channels > Content Management > Widget Schema Management**.
2. Click **New Widget Schema** in the upper-right corner.

<figure><img src="https://3333414532-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIbwGN7KwvYi0iLbjtnXz%2Fuploads%2F262xWrU4YmGz98dENeGF%2F02-widget-schema-management.png?alt=media&amp;token=caa955f8-4cbd-4d07-8b55-2c264859565a" alt=""><figcaption></figcaption></figure>

3. In **Widget Type**, enter `Instore Dynamic Agreements`.
4. In **Schema**, paste the following JSON:

```json
{
  "instore-dynamic-agreements": {
    "key": "instore-dynamic-agreements",
    "label": "Instore Dynamic Agreements",
    "multi": true,
    "schema": {
      "version": {
        "key": "version",
        "label": "Version",
        "required": false,
        "data_type": "text",
        "description": "Version string for constructing 'true/1.0.0' values. Comma-separated and aligned with 'agreement_parameter'; a single value applies to every param, and a blank slot leaves that param unversioned (plain 'true'). Only used for params placed in 'attributes' or 'both'."
      },
      "visible": {
        "key": "visible",
        "label": "Visibility",
        "choices": [
          {
            "label": "Visible",
            "value": "visible"
          },
          {
            "label": "Hidden",
            "value": "hidden"
          }
        ],
        "required": true,
        "data_type": "dropdown"
      },
      "placement": {
        "key": "placement",
        "label": "Placement",
        "required": false,
        "data_type": "text",
        "description": "Comma-separated, aligned position-by-position with 'agreement_parameter'. Each value is 'root' (top-level boolean), 'attributes' (nested versioned string), or 'both'. A single value applies to every param. A blank slot (e.g. 'attributes, , root') leaves that param at the page default. If omitted entirely, the page default is used (root on register, attributes on profile)."
      },
      "link_1_url": {
        "key": "link_1_url",
        "label": "Link 1 URL",
        "required": false,
        "data_type": "text",
        "is_localizable": true
      },
      "link_2_url": {
        "key": "link_2_url",
        "label": "Link 2 URL",
        "required": false,
        "data_type": "text",
        "is_localizable": true
      },
      "link_3_url": {
        "key": "link_3_url",
        "label": "Link 3 URL",
        "required": false,
        "data_type": "text",
        "is_localizable": true
      },
      "link_1_type": {
        "key": "link_1_type",
        "label": "Link 1 Type",
        "choices": [
          {
            "label": "Modal",
            "value": "modal"
          },
          {
            "label": "Link",
            "value": "link"
          }
        ],
        "required": false,
        "data_type": "dropdown"
      },
      "link_2_type": {
        "key": "link_2_type",
        "label": "Link 2 Type",
        "choices": [
          {
            "label": "Modal",
            "value": "modal"
          },
          {
            "label": "Link",
            "value": "link"
          }
        ],
        "required": false,
        "data_type": "dropdown"
      },
      "link_3_type": {
        "key": "link_3_type",
        "label": "Link 3 Type",
        "choices": [
          {
            "label": "Modal",
            "value": "modal"
          },
          {
            "label": "Link",
            "value": "link"
          }
        ],
        "required": false,
        "data_type": "dropdown"
      },
      "requirement": {
        "key": "requirement",
        "label": "Requirement",
        "choices": [
          {
            "label": "Required",
            "value": "required"
          },
          {
            "label": "Optional",
            "value": "optional"
          }
        ],
        "required": true,
        "data_type": "dropdown"
      },
      "default_value": {
        "key": "default_value",
        "label": "Default Value",
        "choices": [
          {
            "label": "True",
            "value": "true"
          },
          {
            "label": "False",
            "value": "false"
          }
        ],
        "required": false,
        "data_type": "dropdown"
      },
      "agreement_text": {
        "key": "agreement_text",
        "label": "Agreement Text",
        "required": true,
        "data_type": "text",
        "is_localizable": true
      },
      "allow_selection": {
        "key": "allow_selection",
        "label": "Allow Selection",
        "choices": [
          {
            "label": "True",
            "value": "true"
          },
          {
            "label": "False",
            "value": "false"
          }
        ],
        "required": false,
        "data_type": "dropdown"
      },
      "link_1_modal_title": {
        "key": "link_1_modal_title",
        "label": "Link 1 Modal Title",
        "required": false,
        "data_type": "text",
        "is_localizable": true
      },
      "link_2_modal_title": {
        "key": "link_2_modal_title",
        "label": "Link 2 Modal Title",
        "required": false,
        "data_type": "text",
        "is_localizable": true
      },
      "link_3_modal_title": {
        "key": "link_3_modal_title",
        "label": "Link 3 Modal Title",
        "required": false,
        "data_type": "text",
        "is_localizable": true
      },
      "agreement_parameter": {
        "key": "agreement_parameter",
        "label": "Agreement Parameter Name",
        "required": false,
        "data_type": "text",
        "description": "Comma-separated parameter names, e.g. 'confirm, privacy_policy'"
      },
      "link_1_modal_content": {
        "key": "link_1_modal_content",
        "label": "Link 1 Modal Content",
        "display": "html-editor",
        "required": false,
        "data_type": "area",
        "is_localizable": true
      },
      "link_2_modal_content": {
        "key": "link_2_modal_content",
        "label": "Link 2 Modal Content",
        "display": "html-editor",
        "required": false,
        "data_type": "area",
        "is_localizable": true
      },
      "link_3_modal_content": {
        "key": "link_3_modal_content",
        "label": "Link 3 Modal Content",
        "display": "html-editor",
        "required": false,
        "data_type": "area",
        "is_localizable": true
      }
    },
    "data_type": "nested"
  }
}
```

<figure><img src="https://3333414532-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIbwGN7KwvYi0iLbjtnXz%2Fuploads%2FVczk4048RZrf6gdYT3pq%2F03-add-widget-schema.png?alt=media&amp;token=55af3d57-92ed-4430-95b1-bd9d4e9a28c4" alt=""><figcaption></figcaption></figure>

5. Click **Save**.

## Step 2: Create the widget

1. In Omnitron, go to **Sales Channels > Content Management > Widget Management**.
2. Click **New Widget** in the upper-right corner.

<figure><img src="https://3333414532-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIbwGN7KwvYi0iLbjtnXz%2Fuploads%2Fg6TxRKyBThLBJLYzkcSh%2F04-widget-management.png?alt=media&amp;token=111571b6-3390-40be-b366-d497fcb001fb" alt=""><figcaption></figcaption></figure>

3. Fill in the fields as follows:

| Field       | Value                        |
| ----------- | ---------------------------- |
| Widget Name | `Instore Dynamic Agreements` |
| Widget Slug | `instore-dynamic-agreements` |
| Widget Type | `Instore Dynamic Agreements` |
| Template    | `/`                          |

4. Click **Add Subcontent** to add an agreement. Repeat this for each agreement you want to show on the registration screen.

<figure><img src="https://3333414532-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIbwGN7KwvYi0iLbjtnXz%2Fuploads%2FMZQIZ6gxCST8mj2x5CKF%2F05-add-widget.png?alt=media&amp;token=5f1bed6c-cd02-40b8-8aad-288e9385f782" alt=""><figcaption></figcaption></figure>

5. Configure the subcontent fields described in the next section, then click **Save**.

<figure><img src="https://3333414532-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIbwGN7KwvYi0iLbjtnXz%2Fuploads%2F5h2fPIQw295GjWLSjc1r%2F06-widget-subcontent-fields.png?alt=media&amp;token=049916ab-94fb-4036-8fd6-ffcbec78308b" alt=""><figcaption></figcaption></figure>

### Subcontent fields

In the field names below, **N** stands for 1, 2, or 3. Each agreement supports up to three links.

#### Display and behavior

* **Visibility** (required): Select **Visible** to show the agreement or **Hidden** to hide it.
* **Requirement** (required): Select **Required** to make the agreement mandatory or **Optional** to make it optional.
* **Allow Selection**: Controls whether the agreement can be selected with a checkbox.
* **Default Value**: When **Allow Selection** is set to **False**, sets the agreement's default value. **True** saves the agreement as selected by default; **False** saves it as not selected.

#### Agreement text

* **Agreement Text** (required): The text displayed for the agreement. For **Modal** and **Link** types, wrap the clickable part in `<link>` tags. The wrapped text is underlined and opens the modal or the link when clicked. For example, entering `I have read and accept the <link>Membership Agreement</link>.` makes **Membership Agreement** the clickable part.

#### Links

* **Link N Type**: The agreement type. Choose one of the following:
  * **Modal**: Clicking the linked text opens a modal with the configured title and content.
  * **Link**: Clicking the linked text redirects the user to the configured URL.
  * **Text**: Leave the type empty to create a plain-text agreement. Text agreements don't need a URL, modal title, or modal content.
* **Link N URL**: For **Link** type agreements, the URL the user is redirected to.
* **Link N Modal Title**: For **Modal** type agreements, the title of the modal.
* **Link N Modal Content**: For **Modal** type agreements, the HTML content of the modal.

#### Data sent to the backend

* **Agreement Parameter Name**: The parameter name sent to the backend when the customer accepts the agreement, for example `email_allowed` or `sms_allowed`. To send multiple names, separate them with commas. A single acceptance sends every listed name as `true`.
* **Placement**: Where each parameter is placed in the registration request. Values are comma-separated and match the parameter names by position. A single value applies to all parameters. If you leave this field empty, the page default is used (`root` on registration, `attributes` on the profile page).

  * `root`: Sends the parameter in the top-level object.

    ```json
    {"name": "Jane", "email": "user@example.com", "test_agreement": true}
    ```
  * `attributes`: Sends the parameter inside the `attributes` object.

    ```json
    {"name": "Jane", "email": "user@example.com", "attributes": {"test_agreement": true}}
    ```
  * `both`: Sends the parameter in both locations.

  Leave a slot blank to use the page default for that parameter, for example `attributes, , root`.
* **Version**: The version used to build versioned values such as `true/1.0.0`. Values are comma-separated and match the parameter names by position. A single value applies to all parameters, and a blank slot sends a plain `true`. Applies only to parameters placed in `attributes` or `both`.

## Step 3: Enable dynamic agreements in Instore

1. In Instore, open the left menu and go to **Settings > Configuration**.
2. Turn on **Use Dynamic Agreements on the new customer registration screen**.

<figure><img src="https://3333414532-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIbwGN7KwvYi0iLbjtnXz%2Fuploads%2FUA00cz15Wz4pfKrBAsVO%2F07-instore-configuration.png?alt=media&amp;token=23ebf9aa-4f3f-4b1c-bf7d-cdfb10dbe0ea" alt=""><figcaption></figcaption></figure>

The agreements you configured now appear on the **Create a New Customer** screen.


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.akinon.com/tutorials/instore/instore-dynamic-agreements.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
