# Welcome!

Our aim to assist all our customers and users with the best help.

We understand that using a new product can sometimes be challenging, so we're here to assist you every step of the way.&#x20;

Whether you're a new customer or a long-time user, we've covered you with comprehensive guides, tutorials, and troubleshooting tips to ensure a seamless experience.&#x20;

<table data-view="cards"><thead><tr><th></th><th data-type="content-ref"></th><th data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>GETTING STARTED</strong></td><td><a href="/pages/PnGSE8dNM1sCHwsC0KkQ">/pages/PnGSE8dNM1sCHwsC0KkQ</a></td><td><a href="/pages/HuFPLvEi8bDh6UyAA50T">/pages/HuFPLvEi8bDh6UyAA50T</a></td></tr><tr><td><strong>BOT BUILDER</strong></td><td><a href="/pages/yoQeaanOi6YcYGlLVEoj">/pages/yoQeaanOi6YcYGlLVEoj</a></td><td><a href="/pages/qVQ3aJuKcg2NyNE2Z387">/pages/qVQ3aJuKcg2NyNE2Z387</a></td></tr><tr><td><strong>AI STUDIO</strong></td><td><a href="/pages/Nmv76GJ4K6itLEEynjX6">/pages/Nmv76GJ4K6itLEEynjX6</a></td><td><a href="/pages/JyGerGFac9eknK1MufxK">/pages/JyGerGFac9eknK1MufxK</a></td></tr><tr><td><strong>LIVE CHAT</strong></td><td><a href="/pages/jAKFdXl9bOredWPvNU8o">/pages/jAKFdXl9bOredWPvNU8o</a></td><td><a href="/pages/Pwp12wtuH1DUqwvqd8uv">/pages/Pwp12wtuH1DUqwvqd8uv</a></td></tr><tr><td><strong>INTEGRATIONS</strong></td><td><a href="/pages/yTlYx2XGnVrrYkGPggdl">/pages/yTlYx2XGnVrrYkGPggdl</a></td><td><a href="/pages/SPHTGqSpXQZq08Rop0Z8">/pages/SPHTGqSpXQZq08Rop0Z8</a></td></tr><tr><td><strong>WHATSAPP API</strong></td><td><a href="/pages/oiRAPtIlT7eQ9H0AvEmM">/pages/oiRAPtIlT7eQ9H0AvEmM</a></td><td><a href="/pages/QkJFz2mxq7CmozeAkoo0">/pages/QkJFz2mxq7CmozeAkoo0</a></td></tr><tr><td><strong>REPORTING</strong></td><td><a href="/pages/8i4KBVql7DCaXE24pL7C">/pages/8i4KBVql7DCaXE24pL7C</a></td><td><a href="/pages/BT8vDAtXmToalhJB1SD1">/pages/BT8vDAtXmToalhJB1SD1</a></td></tr><tr><td><strong>SUPPORT</strong></td><td><a href="/pages/GDKszVXXNqBx11ku9mCx">/pages/GDKszVXXNqBx11ku9mCx</a></td><td><a href="/pages/M0dCkFdB1Hc2uNFAbAZ4">/pages/M0dCkFdB1Hc2uNFAbAZ4</a></td></tr><tr><td><strong>TROUBLESHOOTING</strong></td><td><a href="/pages/koBmYyGM62x9WMepjlVq">/pages/koBmYyGM62x9WMepjlVq</a></td><td><a href="/pages/tfuc6EUbocWZuEr5853M">/pages/tfuc6EUbocWZuEr5853M</a></td></tr></tbody></table>


# Building a chatbot

Chatbots are the way forward for any business looking to automate any repetitive or manual task. Now that you're interested in creating a chatbot, let's learn about building a chatbot

### What type of chatbots I can build?&#x20;

There are two types of chatbot that you can build. They are;&#x20;

1. [Inbound Chatbot](#how-do-i-build-an-inbound-chatbot)
2. [Outbound Chatbot](broken://pages/bu3664jwucUoNIkJGoFP)

### What is Inbound chatbot?&#x20;

An inbound chatbot is a type of chatbot that is designed to interact with customers or users who initiates contact with business or organisation. These chatbots are usually placed on a company's website or social media platform and are programmed to respond to customer inquiries, provide product information, schedule appointments, or handle other customer service tasks.&#x20;

### How do I build an Inbound Chatbot?

You can follow the following steps to build an inbound chatbot;&#x20;

* Go to '**Bot Builder**' <br>
* Click on '**Build a Bot**' <br>
* Choose '**Build an Inbound Bot**' <br>
* Select the '**Channel**' from available options<br>
* Choose how you want to build your bot i.e. '**Use this Templates**' or '**From Scratch**' <br>
* Add '**Action Blocks**' in the conversational flow<br>
* Configure '**Action Blocks**' on the right panel<br>
* Click on '**Test this Bot**' to test the flow <br>
* Click on '**Deploy**' to deploy the bot

{% embed url="<https://youtu.be/Sda10R5b0TY>" %}


# Building a AI agent

AI agents are smart bots that answer questions from a data source.

AI agents are all the rage these days, thanks to ChatGPT.&#x20;

ChatGPT has opened a new way of asking questions and getting answers – that are accurate, brief, and quick.

{% embed url="<https://youtu.be/GMSSzHn9wlU?si=XOAXusDfF9tf9Yba>" %}

Here are the steps to build your own AI agents:

## Step 1: Creating a bot

Next, we need to build a bot that will speak with the visitor and use this knowledge base to fetch the answers to questions asked.

Go to Bot Builder > Build a bot > Inbound > Web

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

## Step 2: Creating a AI agent block

Choose the "AI agent" block from the list and create a new AI agent from the right panel.

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

## Step 3: Setting up the AI agent

The fundamentals of an AI agents are — Prompt, Functions, Paths, LLM settings.

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

### Prompt

A prompt guides the AI on how you want the answer to be generated. Write a clear and concise instruction. Or you can use the "Generate prompt" button to get it auto-generated for you.

[Learn more](/build/prompts)

### Functions

Function allow the AI agent to dynamically execute a function to provide contexual responses. For example, you can create function to "fetch order status", "cancel a order" etc which allow the conversation to feel more natural and powerful.

[Learn more](/build/functions)

### Paths

By default, the AI agent will run on a loop, answering any question it is asked. But if you want the AI agent to come outside of the execution loop, you can define paths.&#x20;

Each path consists of a name, and a description that lets the AI know when should it take this path.

Every path you create displays a path on the canvas.

### LLM settings

Depending on the scope of your project, you can choose the LLM model you prefer to use along with the max tokens used to provide a response and the temperature for the creativity in responses.

For each response the AI agent generates, a AI credit is consumed. Some models consume more credits while some less.

[Learn more about AI credits](/build/ai-credits)

## Step 4: Creating a knowledge base

Let's build a knowledge base, so the AI agent always refers to it when trying to generate an answer to a question.

* Enable the "Use data from knowledge base" on the right panel
* Create a Knowledge base&#x20;
* Start adding data sources

[Learn more about knowledge base](/build/knowledge-base)

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

{% hint style="info" %}
**NOTE:**&#x20;

* More data sources, enable more accurate responses.
* Train your website for more context about your business.
* [Setup refresh frequency](/build/knowledge-base/refresh-frequency) for your website data sources, so that it is always up-to-date.
  {% endhint %}

## Step 5: Add your flow

Feel free to add more blocks if you have chosen to add paths in your AI agent.&#x20;


# Building a bot with live chat

Chatbots are meant to automate the first level of conversations with users.

But sometimes, you need to offer users human assistance depending on the situation.

Here are the steps to add live chat to your chatbot:

## Step 1: Creating your chatbot

Goto Bot Builder -> Build a bot -> Inbound -> Web and build your chatbot flow.

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

## Step 2: Add a talk to human action block

Now, add the 'Talk to human' action block at the point in the chatbot flow where you want to transfer the chat to a human agent.

{% hint style="info" %}
Available on the **PREMIUM** plan and above.
{% endhint %}

<figure><img src="/files/3qM2hWZvLIhkFGg8FWRF" alt=""><figcaption></figcaption></figure>

## Step 3: Configure your assignment rules

On the 'Talk to human' action block, add the assignment rules for the chat to be assigned to your agents.&#x20;

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

Learn more about assignment rules here :point\_down:

{% embed url="<https://help.wotnot.io/bot-builder/action-blocks/talk-to-human#assignment-rules>" %}


# Interface

The Bot Builder is where you visually design chatbot workflows using blocks and actions. Here’s a breakdown of the main components to help you navigate and build effectively:

## Canvas

The central workspace where your entire chatbot flow is designed.

Each conversation path is represented visually, allowing you to drag, drop, and connect blocks in a flowchart-style interface. This is your main area for building and structuring the bot logic.

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

## Action blocks

Each block on the canvas represents a specific action — such as sending a message, collecting user input, booking a meeting, handing off to an agent, or using an AI agent.

These are the building blocks of your bot and can be connected in sequences to define how your chatbot should behave.

[See all action blocks](/build/action-blocks)

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

## Action panel

When you click on any action block, the right-hand Action Panel appears.

This panel lets you configure the settings for that specific block — such as messages, conditions, API calls, or AI agent behavior. It’s where the customization happens.

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

## Utility tools

Located at the bottom of the canvas, the utility bar includes tools to:

* Search blocks across the flow
* Undo / Redo changes
* Zoom in/out or fit the view
* Recenter the canvas
* Toggle grid lines for better alignment

These tools help streamline your building experience and keep things organized.

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


# Variables

Variables are reusable objects containing a user-submitted value.

Variables are essential for capturing and utilizing the data dynamically in the conversation. With variables, you can personalize the chat experience by being able to say “Hey Hardik!”, instead of “Hey there!”.

## Types of variables

### **Conversation variable**&#x20;

Used for storing temporary data that is only relevant within a single session.

* Conversation variables are session-specific and do not persist
* Values are reset after the conversation ends
* Ideal for storing temporary inputs like selections, intermediate responses, or flow-specific data
* Helps manage state within a single interaction without affecting future conversations

### Contact variable

Used for storing user-specific data that persists across conversations — making it ideal for personalization and long-term context.

* Contact variables persist across all conversations with the same user
* Values are stored at the user (contact) level, not session level
* Ideal for storing information like name, email, preferences, lead status, etc.
* Can be updated anytime and the latest value is always used
* Enables personalized and contextual conversations over time

### Secret variable

Used for storing sensitive values, such as API keys and authentication tokens.

* Secret variables are encrypted at rest — the value is never exposed in plain text.
* Once a value is set, no one on the team can view it — not even admins.
* The value cannot be read after it is saved. It can only be updated (replaced) with a new value.
* Secret variables can only be referenced in — HTTP request, and  JavaScript blocks.
* Use this type for API keys, OAuth tokens, webhook secrets, or any credential that should never be visible to teammates.

## Creating variables from variables settings

Under Settings > Variables, you will find all the variables in your workspace. You can click “Create” to create a new variable and provide the details like -- name, description and type.&#x20;

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

## **Creating variables from the bot builder**

In action blocks that allow you save user input like “Collect Input”, “Buttons” etc. you have the option to create a new variable.&#x20;

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

First, you choose the type of variable, next you provide the details like name, description, type.&#x20;

## Editing variables

Go to Settings > Variables > Click “Edit” on the variable.&#x20;

You will be only allowed to edit the description and data type.&#x20;

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

## Deleting variables

Variables can only be archived and not deleted.&#x20;

Go to Settings > Variables and click “Archive” on the variable you want to archive.

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

## Using a variable

You can invoke a variable by typing # to preview the variable dropdown across the bot builder.&#x20;

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

## Data types in variables

You can store the following type of data in variables:

<table><thead><tr><th width="169">Data type</th><th>Description</th></tr></thead><tbody><tr><td>Text</td><td>Stores any text input.</td></tr><tr><td>Number</td><td>Stores only numeric digits from 0 to 9.</td></tr><tr><td>Boolean</td><td>Stores only 0, 1, true, false.</td></tr><tr><td>Date</td><td>Stores date formats as DD/MM/YYYY and MM/DD/YYYY</td></tr><tr><td>Email</td><td>Stores email addresses.</td></tr><tr><td>Phone</td><td>Stores phone numbers.</td></tr><tr><td>Regex</td><td>Stores input based on your validation rule.</td></tr></tbody></table>

## Adding default value to variables

You can add a default value to the variable, so that incase there is no value present a default value can be shown to the user.

To add the default value, open the bot builder canvas, and click on the variable tag. You can then enter the fallback value.

<div align="left"><figure><img src="/files/jn9N5GKSiIV40PalnXkb" alt=""><figcaption></figcaption></figure></div>

## Customizing error messages in variables

You can customise error messages in variables.

1. Navigate to Settings > Variables.
2. Locate the variable with this format (Number, Boolean, Date, Email, Phone & Regex) used for validation.
3. Click "Edit" and edit the error message field.
4. Save the changes and test the flow to confirm the new error message is displayed.

This allows you to replace the default *“Invalid! Please enter a valid input”* with a custom, user-friendly error message (e.g., *“Please enter a valid business email address to continue”*).

## Retrieving JSON objects from a variable

If you are storing JSON objects into variables and want to refer a particular field from the JSON object, you can follow the below approach:

* Create a TEXT type variable
* Store the JSON object in that variable
* Use # followed by your variable name and append the field you want to refer
* Hit enter so the variable chip is created

For example:

```
// Assume this is your JSON object
[
  { "account_id": "A1", "user": "John" },
  { "account_id": "A2", "user": "Sara" },
  { "account_id": "A3", "user": "Mike" },
  { "account_id": "A4", "user": "Tina" }
]

// If I want to refer to the second object i.e. account_id=A2
#name[1].account_id#
```

## System variables offered

Here are the system variables offered by default:&#x20;

<table><thead><tr><th width="282">Variable</th><th>Description</th></tr></thead><tbody><tr><td>name</td><td>Name of the visitor</td></tr><tr><td>email</td><td>Email of the visitor</td></tr><tr><td>phone</td><td>Phone number of the visitor</td></tr><tr><td>ip_address</td><td>IP address of the visitor</td></tr><tr><td>city</td><td>City detected through the IP address of the visitor</td></tr><tr><td>state</td><td>State detected through the IP address of the visitor</td></tr><tr><td>zipcode</td><td>Zipcode detected through the IP address of the visitor</td></tr><tr><td>country</td><td>Country detected through the IP address of the visitor</td></tr><tr><td>timezone</td><td>Browser timezone of the visitor</td></tr><tr><td>os</td><td>System OS of the visitor</td></tr><tr><td>referrer_url</td><td>Referrer domain to the visitor.</td></tr><tr><td>unsubscribed_phone_numbers</td><td>Whether the phone number is unsubscribed from outbound messaging.</td></tr><tr><td>utm_source</td><td>Utm source </td></tr><tr><td>utm_medium</td><td>Utm medium </td></tr><tr><td>utm_campaign</td><td>Utm campaign </td></tr><tr><td>utm_content</td><td>Utm content </td></tr><tr><td>utm_term</td><td>Utm term </td></tr><tr><td>browser</td><td>Browser used during the chat</td></tr><tr><td>contact_id</td><td><br></td></tr><tr><td>bot</td><td>Name of the bot the visitor interacted with.</td></tr><tr><td>browser_language</td><td>Language set in the browser.</td></tr><tr><td>browser</td><td>Name of the browser.</td></tr><tr><td>channel</td><td>Name of the channel where the chat took place.</td></tr><tr><td>contact_created_by</td><td>Who created the contact.</td></tr><tr><td>conversation_url</td><td>Link to the conversation.</td></tr><tr><td>country_code</td><td>ISO country code of the country where the chat originated from.</td></tr><tr><td>created_at</td><td>Date when the chat was created.</td></tr><tr><td>gcal_selected_slot_day</td><td>Selected day when booking the meeting on Google Calendar.</td></tr><tr><td>gcal_selected_slot_time</td><td>Selected time when booking the meeting on Google Calendar.</td></tr><tr><td>timezone</td><td>Timezone of the device.<br></td></tr><tr><td>url</td><td>URL of the webpage where the user is interacting with the bot.</td></tr><tr><td>chat_history</td><td>Includes the transcript of the conversation so far.</td></tr></tbody></table>

## Best practices for variable management

* **Use descriptive names**: Choose variable names that clearly reflect the data they hold, such as "userEmail" or "orderTotal".
* **Document purposefully**: Write clear descriptions that explain the variable's role within your AI agent's workflow.
* **Maintain consistency**: Use a consistent naming convention for your variables to make them easily identifiable and manageable.
* **Regularly review and refine**: As your AI agent evolves, revisit your variables to see if they still serve their intended purpose or need adjustments.


# Cloning bots

Duplicate your chatbot.

We know that there are different channels that the businesses are engaged in, and building the same bot again & again for different channels can be time-consuming.&#x20;

In order to avoid this, we support the cloning of bots from one channel to another.&#x20;

## Pre-requisites&#x20;

You must have 'Deployed' the chatbot at least once. Meaning you should have click the 'Deploy' button inside the chatbot flow once.

## Cloning&#x20;

Follow these steps to clone your bot:&#x20;

* Go to 'Bot Builder' & hover over the 'Bot' you want to clone.
* Click on 'Menu' to see the list of actions that can be performed on this bot.
* Click on 'Clone' & select the 'Channel'.

## Note&#x20;

* When cloning bots from one channel to another, you will see some warnings to replace the non-compatible action blocks.&#x20;
  * For instance, 'Carousel' is not supported in 'WhatsApp' channel.
* You will see a warning modal when you open the copied bot.
* Copied bots have a prefix 'Copy of' to their name. You can change the name on the canvas.


# Requesting edit access

To make chatbot building more clean we're adding read-only access.

By default, only the initial user has **EDIT** access to the bot builder canvas, while additional users have **READ-ONLY** access.

#### **To request edit access:**

1. Click “Read Only”
2. Enter a request message
3. Request is sent to the editor for approval
   1. If approved, you’ll receive confirmation, and the page will reload with edit access
   2. If declined, you will remain in read-only mode

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

{% hint style="info" %}
**Note**: If the editor neither approves nor declines the request, access will be automatically granted after 30 seconds.
{% endhint %}


# Connecting action blocks

These action blocks need to be connected with each other in order to ensure that the bot is having flawless conversation with the visitors

{% hint style="info" %}
You can also connect multiple action blocks to a single action block
{% endhint %}

There are three ways to connect these action blocks with each other, they are:

## Adding a new action block

You can simply click on '+' sign and select the action block from the available list that you would like to add to the flow.

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

## Manually connecting

Drag the + icon from the source block and connect it to the destination block in the flow.

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

## Using Jump

If your chatbot flow is complex and not large, you can use the '[Jump](/build/action-blocks/jump)' action block to logically connect two action blocks.&#x20;

Using jump, no visual link is created between two action blocks.

<figure><img src="/files/9ZrM9nIeoS1ErUijZha3" alt=""><figcaption></figcaption></figure>


# Viewing bot versions

WotNot automatically saves every deployed version of your bot, allowing you to track changes and revisit past versions at any time.

#### Viewing versions

To view your bot’s version history:

1. Click on the bot name in the title bar.
2. Select Version History.

A right-side panel will appear showing all past versions, including the user who deployed each version and the timestamp of deployment.

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

#### Restoring a version

Click **Restore** next to the version you want to revert to.

This will load that version onto the canvas, allowing you to make edits if needed.

> Note: The restored version will remain undeployed until you click Deploy again.

#### Previewing a version

Click **Preview** to open that version in a new browser tab.

The preview opens in read-only mode, so you can explore the bot flow without making any changes.

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


# Creating a loop

If you want to create a loop in your chatbot flow, you can following these steps:

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

You can also use the 'Jump' action block to create an invisible loop.


# Action blocks


# Trigger

Starting point of the chatbot flow.

The Trigger block helps WotNot decide which chatbot to launch when a user initiates a conversation.

Since you can have multiple chatbots on your account, setting up trigger conditions ensures the right one gets activated based on the context. You can combine conditions using AND / OR logic to build more precise rules.

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

Here are the available trigger conditions:

<table data-header-hidden><thead><tr><th width="193"></th><th></th></tr></thead><tbody><tr><td><strong>URL</strong></td><td>Triggers the chatbot based on the webpage the user is on. E.g., “URL contains pricing” or “URL equals https://wotnot.io”</td></tr><tr><td><strong>Browser language</strong></td><td>Uses the user’s browser language to trigger a chatbot. E.g., “Language is French”</td></tr><tr><td><strong>Date range</strong></td><td>Activates the chatbot only within a specific date range. Useful for seasonal campaigns or special announcements.</td></tr><tr><td><strong>Keyword</strong></td><td><em>(WhatsApp &#x26; SMS only)</em> Triggers when a user sends a specific keyword. E.g., “Book appointment”</td></tr><tr><td><strong>Button payload</strong></td><td><em>(WhatsApp &#x26; SMS only)</em> Triggers when a user clicks a button on a template message sent by the business.</td></tr></tbody></table>

{% hint style="info" %}
**NOTE:**&#x20;

* **Conditions are not mandatory.**&#x20;
* If no conditions are set, WotNot will trigger the first active chatbot by default.
  {% endhint %}

## Contact subscription

{% hint style="info" %}
Applicable only for WhatsApp and SMS.
{% endhint %}

In channels like WhatsApp and SMS, businesses can reach out to contacts at any time, even if the contact doesn't want to have a conversation.&#x20;

Countries' laws mandate that companies maintain a subscription status for each contact, meaning that a contact has subscribed or unsubscribed from receiving your communication. This is similar to how unsubscription works on emails.

**SUBSCRIBED -** Will receive any new template message that the company sends as a promotion.

**UNSUBSCRIBED -** Will not receive any template message that the company sends as a promotion.

So, based on the conditions you define for the trigger, you can choose to set the subscription status for the contact.&#x20;

Generally, you should always have two chatbots:

* Your main chatbot, which has the 'Subscribed' status
* An acknowledgment chatbot for when users type 'STOP.'

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

## Inject data into the chatbot

If you want to send external data to the chatbot, you can use this option. Once enabled, you can map the fields that contain the value with the WotNot variable.

{% embed url="<https://www.loom.com/share/fdb974a916004066aff4e555999e0318?sid=58afc33c-b32f-4660-ba83-ae7c3fc8a6d1>" %}

Two ways you can inject the data:

### Using Query params

With this method, when the WotNot snippet is loaded on the website for the first time, the defined query params and their values will be stored in the WotNot variable.

For example, if your URL is the following`www.wotnot.io?cust_id=1234&plan=9896`

You can choose to store the values of `cust_id` and `plan` on the trigger action block.

<div align="left"><figure><img src="/files/II227IIVY7tnBVDlN2OA" alt=""><figcaption></figcaption></figure></div>

### Using JSON

With this method, you can inject a JSON payload inside the WotNot’s code snippet and map the objects to be stored in the trigger action block.

To do this you need to add the following object with your desired fields in the WotNot code snippet

```
data-session-payload='{"field1": "value", "field2: "value"}
```

Now, let's take an example to understand this.

Assume you are using the chatbot in your web app and you already know who is the user initiating the chat. For your agents to be aware of the user details, you can add their name, email, customer\_id, plan, etc. to the WotNot code snippet.

```javascript
<script src="" data-session-payload='{"name": "Charles", "phone": "8164848686"}' defer></script>
```

We have stored the “name” and “phone" fields to WotNot variables on the trigger action block.

<div align="left"><figure><img src="/files/15qeVyCwOMBrreQg7xSb" alt=""><figcaption></figcaption></figure></div>

{% hint style="info" %}
Note:

* WotNot reads this object only once when the code snippet is fired. Sending data after the code snippet loads will not be read.
* Dynamically add the data-session-payload object to the WotNot code snippet
  {% endhint %}

{% hint style="info" %}
Use the following object paths to store the selected button's text, payload, or text message in a variable within the trigger block for WhatsApp Meta Cloud.

* For selected button's payload
  * entry\[0]\['changes']\[0].value.messages\[0].button.payload
* For selected button's text
  * entry\[0]\['changes']\[0].value.messages\[0].button.text
* For a text message
  * entry\[0]\['changes']\[0].value.messages\[0].text.body
    {% endhint %}


# Send message

Sends a message and proceeds to the next part of the flow.

{% hint style="info" %}
The rich text editor supports all languages, so you can now type your input in any language you want, such as French, Spanish, etc.
{% endhint %}

As the name suggests, the 'Send message' sends your defined message and moves forward to the next step in the chatbot flow.

You can choose to add a **text message** or a **file**.&#x20;

You can bundle multiple messages/files inside a single 'Send message' action block.

{% embed url="<https://www.loom.com/share/8d7b68d29eee49ba865de8e298a76df6?sid=9312eca3-a8d0-4347-89f0-aea8b5671d22>" fullWidth="false" %}
Setting up 'Send Message' action block
{% endembed %}

### Text formatting&#x20;

You can format your text using the formatting bar in the rich text editor.&#x20;

* Bold
* Italics
* Underline
* Ordered bullet lists
* Unordered bullet lists&#x20;
* Hyperlink
* Emojis

{% hint style="info" %}
Max characters allowed in a single message block is 1000.
{% endhint %}

### File types

You can upload the following file types:&#x20;

* png/jpg/gif
* mp4
* mp3
* pdf
* csv/xlsx

{% hint style="info" %}
File size cannot exceed 50mb.
{% endhint %}

### Tracking links

Enabling this feature tracks all link clicks occurring on the chatbot flow. Once enabled, the link will first open the tracking domain and then redirect to the actual URL defined.

[Learn more](/support-and-billing/faq/setting-up-link-tracking)

### Send message as info title

Enabling this will compress the message description and show the title as defined. It appears as a tooltip that can be expanded to see the information.

<figure><img src="/files/1pETcmroiPPgU5B2oY1H" alt=""><figcaption></figcaption></figure>


# Collect input

Collect a response from the visitors to the question asked.

Collect Input action block is used for asking questions to which your visitors can respond in the chat.

![](/files/F5S3G80X769DdL3HaWpr)&#x20;

### Using the Collect Input block

Add the Collect Input block onto the canvas and connect it to the step before it. Click on the block to configure where the user’s response should be saved.

#### Configuration

* **Question**: The question you want the bot to ask when collecting the user's response.
* **Save response**: Select or create a variable where the user’s complete message will be stored. This variable can be referenced later in your workflow. [Learn more about variables](/build/interface/variables)
* **Add an info message**: Displays an info icon with helper text to provide additional context about this message.

{% hint style="info" %}
The chat flow will not proceed until this question is answered by the user.&#x20;
{% endhint %}

{% hint style="info" %}
If your variable requires a specific kind of input which the user wrongly submits, the user will show an error message and not be allowed to proceed.
{% endhint %}

<br>


# Buttons

Buttons offers a rich UX for users by showing them a list of predefined options to choose from. This makes the chat more conversational.

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

The button action block is made up of 3 things:

1. Question to ask
2. Options to be displayed
3. Saving user input

## Question

A question that explains the user to choose from the list of buttons displayed.&#x20;

For example, “What do you need assistance in?”.

## Options

Along with the question, we show a list of pre-defined options that the user can choose from.&#x20;

These buttons are generally of two types:

### Branch buttons

Adding a branch button, adds a grey color node on the canvas. Using this node you can create different paths for each button in the chat flow.

For example, you can have a question like “How often do you shop online?” with the buttons,

* Every other day
* Once in a week
* Once in a month
* Rarely

{% hint style="info" %}
You can add a maximum of 10 buttons. To add more buttons, use the [Dynamic data](/build/action-blocks/dynamic-data) action block.
{% endhint %}

### URL buttons

Adding a URL button, allows you to open a webpage when that button is selected.&#x20;

For example, you can have a button which says “Read case study” which when clicked opens a webpage on a new tab.&#x20;

{% hint style="info" %}
You can also use 'mailto:<hello@example.com>' and 'tel:+919999999999' to open the email client or phone dialer when the button is clicked.&#x20;

![](/files/iXQ2Ea7n3MR7X4QGrjEn)

![](/files/k9X4KSwoDIRrWKie7mTc)
{% endhint %}

### Variables

Variables are used to store the button selected by the user, so you can reference it for later use.&#x20;

You can either choose an existing variable from the dropdown or create a new one.

[Learn more](/build/interface/variables)<br>

## Some more button settings&#x20;

### Search

Enabling it shows a searchbox on top of the list of buttons, so that users can easily find the option they are looking for.&#x20;

This is really helpful when you have a huge list of buttons.

<div align="left"><figure><img src="/files/YT3ZYmKRXStW3yypVarX" alt="" width="368"><figcaption></figcaption></figure></div>

### Multi-select

Allows the user to select multiple buttons at a time. After choosing the required buttons, user would need to hit “Send” to proceed to the next step in the chat flow.

When using multi-select, the flow will always route to the “Default” branch.

When using variables for multi-select, all values will be stored in a comma separated format i.e. “Fever, cough”.&#x20;

<div align="left"><figure><img src="/files/6QvnlSsjAoMzwm9GkUVI" alt=""><figcaption></figcaption></figure></div>

### Buttons layout

Renders the button in the specified format:

* **Horizontal** – Horizontal placement of buttons as per available space.
* **Vertical** – Each item is displayed in a new line.

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

### Buttons sorting

You can choose to sort the list of buttons in the following order:

* A - Z – In an ascending order starting from A.
* Z - A – In a descending order starting from Z.
* Random – Button list will be randomized
* As defined – The order as displayed in the action panel.

### Free text input

By enabling "Enable free text" option, users can either choose from predefined buttons or type their own response in the chat input. Also, on the canvas a new "Free text" node will be added, which can be connected to an [AI agent](/build/action-blocks/agent) action block for AI-generated responses.

This allows for more natural, two-way conversations, and any free text entered can be handled by an AI agent for dynamic responses.

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


# Reply buttons

Render up to three buttons in your conversation flow on WhatsApp.

{% hint style="info" %}
This action block is only supported for the WhatsApp channel for the following BSPs: 360Dialog, Meta, and GupShup.
{% endhint %}

<figure><img src="/files/ONnsZIH9qIEdSfFdXTZT" alt=""><figcaption><p>Preview of reply button on WhatsApp</p></figcaption></figure>

The Reply Button action block gives your visitors different options to choose from using buttons, making it easier for them to submit an input.&#x20;

The Reply Button action block is made up for 4 sections;&#x20;

1. Header
2. Body
3. Footer
4. Buttons / Options

Let’s understand each section in brief:<br>

### Header:&#x20;

Header is usually the standout portion of the message. Usually, it consists of the heading  text or a cover image.&#x20;

Type of headers that you can configure;&#x20;

<table data-header-hidden><thead><tr><th width="179"></th><th></th></tr></thead><tbody><tr><td><strong>Text</strong></td><td>Add a static text displayed in ‘Bold’<br>Example: “Welcome to WotNot”</td></tr><tr><td><strong>Media (Static)</strong></td><td>Add a static text displayed in ‘Bold’<br>Example: “Welcome to WotNot”</td></tr><tr><td><strong>Media (Dynamic)</strong></td><td>Send a dynamic image, video or file by using a variable. The variable needs to contain a publicly hosted file URL.<br>Example: Invoices or personalised images with name.</td></tr></tbody></table>

### Body:&#x20;

Here, you can write the question which will be sent along with the list of buttons. Something contextual to the options they would see like “Select the category of your problem”.&#x20;

### Footer:&#x20;

Allows you to add any sort of disclaimer or information that the user needs to be aware of.&#x20;

Will be displayed in a small grey colour font beneath the body.

Example: “Choose one of the option from displayed options”

### Buttons or Options:&#x20;

Buttons is what this block is all about, so you can add up to 3 reply buttons here.

For example, if you are an ecommerce company and want to collect the category of a support query, your options would be  – Product related, Refund related, Delivery related

{% hint style="info" %}
**Note**: You can add up to 3 buttons as per the guidelines from WhatsApp
{% endhint %}

### Variables:&#x20;

Variables are used to store the option selected by the visitor, so you can reference it for later use.&#x20;

You can either choose an existing variable from the dropdown or create a new one.

[Learn more about variables here](/build/interface/variables).&#x20;

### Enable free text

By enabling "Enable free text" option, users can either choose from predefined buttons or type their own response in the chat input. Also, on the canvas a new "Free text" node will be added, which can be connected to an [AI agent](/build/action-blocks/agent) action block for AI-generated responses.

This allows for more natural, two-way conversations, and any free text entered can be handled by an AI agent for dynamic responses.

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


# Carousel

Displays a set of cards in a carousel.

{% hint style="info" %}
Only supported in the WEB channel.
{% endhint %}

Carousels are a set of cards which displays the items with Click to Action buttons (CTAs) associated with each card.

{% embed url="<https://www.loom.com/share/1ce6d428e1cf4c48bfd9cde0a96a780a?sid=c7d35bf9-1698-4093-9ba5-ab552265e738>" %}
Setting up 'Carousel' action block
{% endembed %}

Carousels action block is made up of 2 sections;&#x20;

1. Configuring the cards to be shown
2. Saving user input

### Configuring cards

In order to display the items, you will need to add the cards to the action block by clicking on ‘+ Card’.&#x20;

{% hint style="info" %}
**NOTE**:&#x20;

* Max cards allowed is 10&#x20;
* Max image file size is 5 mb
* Recommended image dimension 16:9
  {% endhint %}

You can click on the card to configure it.&#x20;

Card consist of following elements:

<table data-header-hidden><thead><tr><th width="182"></th><th></th></tr></thead><tbody><tr><td>Image</td><td>A cover image for each card.</td></tr><tr><td>Card title</td><td>Title of the card.</td></tr><tr><td>Card description</td><td>Brief description of the card.</td></tr><tr><td>Buttons</td><td>Call to action buttons for each card. You can add a max of 2 buttons.<br><br>Button types:<br><strong>Branch:</strong> On click, moves the chat to the next step in the flow.<br><strong>URL:</strong> Opens a URL on the browser; flow ends at that point.</td></tr></tbody></table>

{% hint style="info" %}
Maximum of **three buttons allowed**.
{% endhint %}

### Variables

Variables are used to store the input received from the visitor, so you can reference it for later use.&#x20;

You can either choose an existing variable from the dropdown or create a new one.

{% hint style="info" %}
Only Branch button selection made by the visitor will be stored in the variable.&#x20;
{% endhint %}

[Learn more about variables here](/build/interface/variables)

### Enable free text

By enabling "Enable free text" option, users can either choose from predefined buttons or type their own response in the chat input. Also, on the canvas a new "Free text" node will be added, which can be connected to an [AI agent](/build/action-blocks/agent) action block for AI-generated responses.

This allows for more natural, two-way conversations, and any free text entered can be handled by an AI agent for dynamic responses.

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

### Example:&#x20;

Imagine you are building a chatbot to showcase the properties offered in your real estate company.

You can use Carousel to display all the properties offered by you with an image, name of property and details of some amenities offered.

And the buttons can be:

* **Learn more** -- which redirects to your webpage with more details.
* **Book a visit** -- which continues the flow asking for contact info to book a site visit.

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


# Agent

Runs your AI agent with prompts and functions to generate a response.

The Agent block allows you to create an AI-powered conversational step inside your flow. It uses Large Language Models (LLMs) and your knowledge sources to generate answers, while also supporting rules, paths, and functions.

## When to use the Agent block

Use the Agent block when you want the chatbot to:

* Answer questions dynamically using your knowledge base
* Connect with external APIs or functions for real-time data
* Branch into different paths depending on user intent
* Hand over to a human agent if needed

If your use case only requires simple, predefined answers, use a Message block instead.

{% embed url="<https://www.loom.com/share/7e32a5ee7917482280298ceff776ab14?sid=01d0e86a-8285-4310-b6a6-808ad7243e96>" %}

## Creating an AI Agent

* Add the AI agent block
* Click 'Create AI Agent' on the AI agent dropdown

<figure><img src="/files/5Cq2Sc3FrV1uZHWBuvko" alt=""><figcaption></figcaption></figure>

Configure the core components of the AI agent:

1. **Prompt** — instructions the AI follows.
2. **Functions** — APIs/external logic
3. **Paths** — branching logic
4. **LLM settings** — temperature, model selection etc.

### Prompt

The prompt tells the AI how to behave and what style of answers to give.

* Keep instructions short, clear, and specific
* Include tone (e.g., professional, friendly, concise)
* Add context (“You are a banking support assistant helping customers with credit card queries”)

Example

* ❌ Poor prompt: *Answer user questions*
* ✅ Good prompt: *You are a support assistant for ACME Bank. Answer in a professional, polite tone. If unsure, guide the user to contact support.*

<figure><img src="/files/uzPcJSWscg9SdTsfXruh" alt=""><figcaption><p>Prompt section when creating a Agent</p></figcaption></figure>

Here’s what makes a strong prompt:

* Clear Directives: Define exactly what the agent’s role is and how it should behave in various scenarios.
* Personality Design: Set the tone, formality, and communication style your agent should follow.
* Knowledge Scope: Outline what the agent should know and when to refer to external sources.
* Context Handling: Provide guidance for sensitive topics and when to escalate to a human.

{% hint style="info" %}
You can learn to create a prompt [here](/build/prompts).
{% endhint %}

### Functions

Functions allow the Agent to call external APIs or run logic before answering.

* Example: *Check order status from an API, then respond with the delivery date.*
* Use functions when the answer requires live data instead of static knowledge

{% hint style="info" %}
Learn about creating a function [here](/build/functions#creating-a-function).
{% endhint %}

<figure><img src="/files/kzaWxrAbkkeTG1xVYzKf" alt=""><figcaption><p>Function section when creating a Agent</p></figcaption></figure>

### Path

Paths let you branch the flow based on what the user says.

* Define triggers (keywords or intent) that send users down specific paths
* Example: *If user says “talk to human” → route to Live Chat*

<figure><img src="/files/aN43hWb0aUuIqwWTpE6c" alt=""><figcaption><p>Path section when creating a Agent</p></figcaption></figure>

**Path Examples:**

Human Handoff Path

* Path Name: Transfer to Human Agent
* Description: Trigger this path when the user explicitly requests to speak with a real person. Phrases like “I want to talk to a human,” “Can I speak to an agent?” or “I need help from a real person” should activate this path.
* Required Variable: None
* LLM Description: This path allows the agent to hand over the conversation to a human agent. Ensure the system recognizes phrases requesting a human interaction and promptly transfer the conversation.<br>

Book Demo Path

* Path Name: Schedule Product Demo
* Description: Trigger this path when the user expresses interest in booking a product demo or meeting. Look for phrases such as “I want to book a demo,” “Can I schedule a meeting to see the product?” or “How can I try the product?”
* Required Variables:
  * Name
  * Email
* Variable Descriptions:
  * Name: Collect the user’s full name so the meeting can be scheduled properly.
  * Email: Capture the user’s email to send demo details and confirmation. Ensure the email is in a valid format (e.g., contains @ symbol and proper domain).

This path ensures that when a user wants to book a demo, all necessary details like their name and email are captured before proceeding with the demo scheduling.

### LLM settings

The LLM Settings section allows you to customize how the language model behaves:

* **LLM Model** — Choose which language model (e.g., GPT-3, GPT-4) you want to use for generating responses. Models offered:
  * OpenAI
  * Anthropic
  * Google Gemini
  * Custom Models *(Available on Enterprise plan)*
* **Max Tokens** — This setting controls the maximum length of the response. A higher token limit allows the model to generate longer responses, while a lower limit results in shorter replies.
* **Temperature** — This adjusts the randomness of the model’s responses.&#x20;
  * Lower = safer, more predictable answers
  * Higher = more creative, varied answers

These settings help fine-tune how the AI interacts with users based on your desired response style and length.

{% hint style="info" %}
You can view all the AI models supported [here](/build/ai-credits)
{% endhint %}

<figure><img src="/files/rMxHpEARJ4hhqlOg28fc" alt=""><figcaption><p>LLM settings when creating an agent</p></figcaption></figure>

***

## Creating a knowledge base

To empower your AI agent to only answer questions that you want it to, create a knowledge base.

* Turn on the *Use data from knowledge base*
* Click *Create knowledge base* from the knowledge base dropdown

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

* Add data sources to the knowledge base

<figure><img src="/files/0OhOjt0BfATRSm5PKYVF" alt=""><figcaption></figcaption></figure>

### Chunks

In RAG, long documents are too big to give directly to an AI model. So, the documents are broken down into smaller pieces of text, called chunks.

Each chunk is just a section of the original content (like a paragraph or a few sentences) that can be stored and searched easily.

When a user asks a question, the system finds the most relevant chunks instead of searching through the entire document. These chunks are then passed to the AI model, so it has the right context to generate an accurate answer.

{% hint style="info" %}
**NOTE:**

* More chunks sent to LLMs, result in better answers.&#x20;
* Recommended chunk count is 5.
  {% endhint %}

***

## Other configurations

These are the toggles/settings that customize how the Agent interacts with users.&#x20;

### Answer source

When the AI generates a response, it often relies on external information—like documents or web pages. To make this process transparent, we show the Answer Source.

The Answer Source is basically a link to the original webpage (or document) that was used to generate the response. This way, users can:

* Verify the accuracy of the information
* Read the full content for more details
* Trust that the answer isn’t coming from a “black box,” but from a clear, traceable source

### Execute only once

By default, the AI Agent block runs in a loop, meaning the flow keeps executing within the same block until an exit path condition is met.

If you’d like the AI Agent to run just once and then automatically continue to the next step in the flow, enable the Execute Only Once setting.

### Collect feedback

Shows 👍 / 👎 on agent answers so users can rate responses; helps admins improve the bot.

Their feedback helps admins improve the bot by identifying where answers fall short, so they can:

* Add more data sources to the knowledge base
* Update or refine existing content

In short, Collect Feedback gives admins a direct way to learn from users and continuously enhance the bot’s performance.

### Show results as

By default, the AI Agent displays its response as plain text in the chat.

If you turn on any of the options—Buttons, Carousel, or File—the response will also include those formats for a richer experience.

Example:

A user asks: *“Show me the available credit card options.”*

* Text (default):

  “Here are the available credit cards: Gold, Platinum, Titanium.”
* Buttons (if enabled):

  Along with the text, users will see buttons like Gold, Platinum, Titanium that they can click.
* Carousel (if enabled):

  Each card is shown as a card-style item with an image, short description, and a “Select” button that users can scroll through.
* File (if enabled):

  The agent attaches a downloadable PDF with full details of all credit cards.

***

## Best Practices & Tips

* Keep prompts short and action-oriented
* Avoid overlapping path triggers (use clear keywords/intents)
* Test with real queries to validate output
* If using functions, confirm the API is reliable and handles errors gracefully
* Use “Exit paths” to prevent loops

## Common Pitfalls

* Forgetting to capture variables before using them in paths/functions
* Setting temperature too high, causing irrelevant answers
* Not linking fallback paths for when AI cannot find a match

## Checklist before going live

* Prompt is clear and instructive
* Paths are defined and tested
* Functions return correct data
* Human handoff works smoothly
* Edge cases tested with sample queries


# Answer AI

Uses an LLM-based AI model to generate an answer for the question asked.

The Answer AI action blocks uses LLM models to generate an answer to the user's question using the knowledge base for reference.

Process in which the Answer AI works,

1. User asks a question
2. AI generates the answer from a knowledge base

<figure><img src="/files/67sYDyhRPMbJmbksx2zk" alt=""><figcaption></figcaption></figure>

## Step 1: Define the question

This message will prompt the user to ask their question.

For example, your message could be,

> 👋 Hey! I'm an AI assistant, how can I help you?

[Learn more about prompts](/build/prompts)

## Step 2: Choose a knowledge base

Choose the knowledge base from which AI will generate an answer.

[Learn more](/build/knowledge-base)

## Step 3: Configure your AI for accurate answers

LLM models require guidance to be able to generate a relevant and accurate answer. There are some tools you can use to guide your AI; they are:

### Instructions/Prompt

A prompt is nothing but an instruction that helps the LLM know what to remember and follow while generating an answer.

The more clear, concise and brief your instruction, the more accurate your answers will be from the AI.

Things to write in your prompt:

* **Objective** - What is its objective
* **Output format** - Typically would be HTML/markdown.
* **Writing style** - How should the answers be written.
* **Don'ts** - Clear instructions of what to avoid.
* **Examples** - Examples of question and answer.

Some more advanced settings available are:

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

### LLM model

Select the LLM model that will be used to parse your training data and generate an answer.&#x20;

[See the supported models list](/build/ai-credits#multiplier-matrix)

### Restrict answer size

The maximum length of the answer is defined in tokens.&#x20;

Tokens can be thought of as pieces of words, and 1 token=4 characters. [Learn more](https://help.openai.com/en/articles/4936856-what-are-tokens-and-how-to-count-them)

### Temperature

You can control whether you would like to receive unique responses every time a question is asked or get the same response every time the question is asked.&#x20;

Define a number between 0 and 1. Nearer to 1 gives you distinct responses; nearer to 0 gives you fix responses. By default, we keep the number as **0.5**.

### Chunks

When the AI is asked a question, it first fetches relevant content from the knowledge base, which is then sent to the LLM model to generate an answer.

The more relevant content the AI can fetch, the more chances of accurate responses are.

The number indicates the number of relevant responses which will be fetched from the knowledge base.

### Include chat history

Enabling this will include the entire chat history of the chat when answering any question.

This helps when user asks follow-up questions as 'its pricing', and the LLM would be aware that your previous question was about WotNot, so you meant "WotNot's pricing'.&#x20;

### Collect feedback&#x20;

For every AI generated response, we allow the user to submit feedback about the generated answer.

This helps you know how helpful are AI's answers.

### Answer source

Displays the URL of the content source from where the answer was referenced from. This only works for knowledge bases built using a website URL.


# Set AI

Uses an LLM-based AI model to generate an response based on the prompt given.

The Set AI action block is used to generate a response to the prompt supplied to it.&#x20;

When using the Set AI block, the user submits a prompt, which is then either processed by the AI Studio or the LLM model to generate a response. This response is then stored into a variable

Process in which the Set AI works:

1. We supply it with the user question and knowledge base
2. Provide a prompt to follow instructions
3. AI generates the response
4. Response is stored in a variable
5. Use this paste to print the response

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

## Step 1: Define the prompt/instruction

LLM models require guidance to be able to generate a relevant and accurate answer. There are some tools you can use to guide your AI; they are:

### Instructions/Prompt

A prompt is nothing but an instruction that helps the LLM know what to remember and follow while generating an answer. The more clear, concise and brief your instruction, the more accurate your answers will be from the AI. [Learn more](/build/prompts)

Things to write in your prompt:

* **Objective** - What is its objective
* **Output format** - Typically would be HTML/markdown.
* **Writing style** - How should the answers be written.
* **Don'ts** - Clear instructions of what to avoid.
* **Examples** - Examples of question and answer.

An example prompt could be:

> Given the ‘user’s question’: “\[QUESTION]”
>
> And the detailed information provided in ‘chunks’: “\[CHUNKS]”<br>
>
> Determine, whether a clarifying question is required.
>
> Instructions:
>
> 1\. Analyse the 'chunks' and the 'user's question' to identify the specificity of the query and the scope of the information in 'chunks'.
>
> 2\. If the query is broad and the 'chunks' have multiple categories or types, output '#' and guide the chatbot to ask for clarification.
>
> 3\. If the query aligns well with a specific part of the 'chunks' that provides a comprehensive answer, output '\~'.
>
> Output format: \[Decision: '\~' or '#', (if '#') then clarification is required. If '#' also, 'specify the type of information or category that would help better address their question. This should be based on 'chunks'.
>
> Important: if the user's question is likely to have a device specific answer, then you should ask for more information.
>
> If the user has given a device, then we don't need to clarify.

## Step 2: Store the response in a variable

The AI would process the instruction/prompt and generate a response. To get an ideal response, make sure you include in the instructions what kind of response you want to receive.

Choose the variable you want to store the response in. [Learn more](/build/interface/variables)

For example, if you want to check if the user has asked for a follow up question, you can write the instruction like:

> Examine the user's last utterance:
>
> "\[LAST INPUT]"<br>
>
> Determine if the user has asked a follow-up question by looking for:
>
> \- Interrogative words (who, what, where, when, why, how, etc.)
>
> \- Phrases that indicate a desire for additional information (e.g., "I would like to know", "Can you tell me about", "I'm interested in", "Could you explain")
>
> \- Continuation phrases or conjunctions that introduce new topics or questions (e.g., "but", "however", "also", "in addition")<br>
>
> \- Output '1' if any of these indicators suggest a follow-up question is present.
>
> \- Output '0' if no follow-up question is detected.<br>
>
> \[Note: Only output '1' or '0' based on this analysis.]


# Send an email

Sends an email notification to notify about an event occurring in the chat flow.

Send an Email action block is used for sending real time email notification to internal stakeholders about the conversation that happened between the chatbot and the visitor.&#x20;

{% embed url="<https://www.loom.com/share/68ba897a0a174609983577912b1698ac?sid=148ba04f-86a9-4de1-88f6-718a9bd9f5a6>" %}
Setting up 'Send Email' action block
{% endembed %}

Send an Email action block is made of the following:

### Recipients:&#x20;

You can add the email IDs of the recipients or internal stakeholders who will be notified about the conversation that happened between the chatbot and visitor.&#x20;

Just like the emails, you can configure the ID’s in following fields:&#x20;

* To
* CC
* BCC

### Subject:&#x20;

Allows you to define the subject name for this email notification. By default it will be “Lead generated via WotNot”&#x20;

{% hint style="info" %}
**Note**: You can even use the variables in the subject&#x20;
{% endhint %}

### Body:&#x20;

Brief overview of the information that you want your stakeholders to be notified about.&#x20;

For example, if I want to be notified about a new lead generated by the bot. You would use the following body:

> Hey! A new lead was generated by the bot. <br>
>
> Here are the details:
>
> Name: { name}
>
> Email: {email}
>
> Phone: {phone}
>
> Description: {info}
>
> Location: {city}, {country}
>
> Webpage: {url}

{% hint style="info" %}
**Note**: You can use variables in the email.&#x20;
{% endhint %}

#### Include chat transcript

By enabling this,  we will include the entire conversation history between the user and the bot till this point. It will allow your team to look at the chat exactly as it occurred.&#x20;

After enabling this, you can still add the body for more context. This will be added at the bottom of the email.<br>


# List

Renders a list of items grouped by categories on a drawer.

{% hint style="info" %}
Available on WhatsApp for the WA API providers: 360Dialog, Meta, and GupShup.
{% endhint %}

This action block is used for a rich approach of allowing users to choose from a list of options.&#x20;

Most commonly, it is used as an alternative to the [Option](/build/action-blocks/options) action block, as it it not user-friendly and prone to users from the users.

<figure><img src="/files/3OS4vD8YR8DcYolImLLp" alt=""><figcaption><p>Preview of list on WhatsApp </p></figcaption></figure>

List action block is made up of the following:

1. Header
2. Body
3. Footer
4. Button name
5. Items & categories
6. Error message
7. Variable

## Configure the question

### Header

Shows the text in a bold format -- making it look like a title. It is an optional field.

### Body

The text will be the question associated with showing the list of options.&#x20;

For example, "Select the service you are interested in".

### Footer

The text is displayed in a small grey color format. Mostly used to display a disclaimer to the user when selecting the option from the list.

## Configure the list items

### Button name

Along with the above, a button will be displayed, on click of which we will show the list of options in a drawer format.&#x20;

You can write the button's name here, such as 'Choose', 'Select', etc.

### Items & Categories

All the items that are to be displayed in the list are defined here.&#x20;

Each item contains the following information,

* **Item name** — Name of the item
* **Item description** — A short description of the item
* **Category** — List of all categories created. It is optional.
* **Button payload** — Button payload is like a hidden label you attach to each item in your list.

On the bot builder canvas, for each list item, you will see a new branch created. You can use this to create personalized flows.

{% hint style="info" %}
A maximum of **10** items and categories can be created.
{% endhint %}

### Using button payload

When the user clicks an item, this hidden label gets saved using the “Save button payload response” option. This means the bot remembers which item the user selected.

Later, in the Condition block, you check this saved label (payload value) to decide where to send the user.

Example:

* You set the button payload as “cart” for Item 1 and Item 2
* The user clicks Item 1 → the bot saves “cart” because of “Save button payload response”
* In the Condition block, you check: “If saved value = cart → go to Cart Flow”

So, button payload helps the bot know which item was selected and route the user correctly.

### Variable

Users can store the value of the selected list item in a variable for future reference.

[Learn more](/build/interface/variables)

### Enable free text

By enabling "Enable free text" option, users can either choose from predefined buttons or type their own response in the chat input. Also, on the canvas a new "Free text" node will be added, which can be connected to an [AI agent](/build/action-blocks/agent) action block for AI-generated responses.

This allows for more natural, two-way conversations, and any free text entered can be handled by an AI agent for dynamic responses.

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


# Condition

Create conditions to branch your chatbot flow.

For chatbot flows requiring a logical condition to be evaluated to branch out to the next step in the flow, you can use the condition action block.

{% embed url="<https://www.loom.com/share/f76d6db4dfc44ecea3eafbdb362029a9?sid=818b818e-8082-4387-be3c-9e77c1a88a6e>" %}
Setting up 'Branch' action block
{% endembed %}

You can create a set of conditions for each branch in the chatbot flow.&#x20;

Each condition is made up of:

* **Variable** - which contains the value to be compared.
* **Operator** - specifies the operation to be carried out.
* **Value** - the value against which the variable's value is to be compared.

All conditions will be evaluated with **ANY** if you want any one condition to be satisfied, and ALL if you want all conditions to be satisfied.&#x20;

<div align="left"><figure><img src="/files/yBKj9Vtc0xi6qCCby0cj" alt=""><figcaption></figcaption></figure></div>

## Operators supported

<table><thead><tr><th width="175.33333333333331" align="center">Operator</th><th width="303" align="center">Description</th><th align="center">Example</th></tr></thead><tbody><tr><td align="center">Equals to</td><td align="center">Commonly used when you want to match the value of the variable with the defined value</td><td align="center">"City" '<strong>Equals To</strong>' "New York" </td></tr><tr><td align="center">Not equals to</td><td align="center">Commonly used when you don't want the value of the variable to be matched with the defined value</td><td align="center">"City" '<strong>Not Equals To</strong>' "New York" </td></tr><tr><td align="center">Contains</td><td align="center">Commonly used when you want the variable to contain the defined value</td><td align="center">"URL" '<strong>Contains</strong>' "Web"</td></tr><tr><td align="center">Does not contain</td><td align="center">Commonly used when you do not want the variable to contain the defined value</td><td align="center">"URL" '<strong>Does Not Contain</strong>' "Web"</td></tr><tr><td align="center">Is empty</td><td align="center">You can use this operator to identify whether the variable is empty or not</td><td align="center">"Phone" is '<strong>Empty</strong>'</td></tr><tr><td align="center">Is not empty</td><td align="center">You can use this operator to ensure that variable is not empty</td><td align="center">"Name" is '<strong>Not Empty</strong>'</td></tr></tbody></table>

## Default condition

If none of the conditions are satisfied, the chat flow will automatically proceed toward the 'Default condition' branch on the bot builder canvas.

This default branch cannot be deleted.&#x20;


# Talk to human

Transfer the chat to a human agent on the live chat page.

{% hint style="info" %}
Available in the **PREMIUM** plan and above.
{% endhint %}

In certain use cases, you may want to hand over the conversation to a human agent to provide a more personalized experience. This can be done using the “Talk to Human” action block.

When a chat is handed off, it follows the assignment rules you define in the flow. After the transfer, the chatbot steps back and the conversation is managed by the assigned agent.

To set this up, simply add the “Talk to Human” block at the point in your chatbot flow where the handoff should occur, and configure the assignment settings as explained below.

## Assignment rules

It instructs the system who to assign a conversation to. Conversations will be assigned in the defined order of assignment rules.&#x20;

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

For each assignment rule, you need to define:

**Assignee** — The assignee tells the system to whom the chat should be assigned. An assignee can either be an agent or a team.

**Wait time** — If the assigned agent does not reply to a conversation within the wait time, the next assignment rule will be invoked.

{% hint style="info" %}
If all the assignment rules fail, the chat will be transferred to the **Unassigned** queue.
{% endhint %}

### Dynamic assignment

Dynamic Assignment allows you to assign a chat to a specific agent based on external logic, such as the contact owner retrieved from your CRM.&#x20;

To use this approach, select 'Dynamic assignment' in the "Assign to" field under the assignment rules menu.

Simply pass the agent’s email via an API call, store it in a variable, and choose that variable in the dropdown. Make sure that the email used must belong to an active user on your WotNot account.

{% hint style="info" %}
**NOTE:**

Generally, it is best practice to have multiple assignment rules like:&#x20;

1. Assign to support reps
2. Assign to Support manager
   {% endhint %}

## Default messages

Under the "Advanced settings" menu, you can customize the system's default messages when transferring a chat to an agent.

* When the chat is assigned to an agent
* When the human handover feature is disabled under Settings > Live chat > Human handover
* When no agent is available/online
* When human handover occurs beyond operational hours

## When can a human handover fail

* When the "Human handover" feature is disabled under Settings > Live chat > Human handover
* When there are no agents available at the time of chat assignment
* When the human handover request occurs beyond operational hours
* When all available agents have hit their max chat thresholds


# Dynamic data

Dynamically renders a list of options from an API response.

{% hint style="info" %}
Available on the **PREMIUM** plan and above.
{% endhint %}

For use cases that require the list of options to be fetched from an API call (meaning the list is unique to each visitor), you would use the Dynamic data action block.

Using this block, you can dynamically display list items for,

* Button
* Carousel
* Option (WhatsApp and SMS)
* List (WhatsApp)
* Reply button (WhatsApp)
* File

## Step 1: Store the response in a variable

The API response containing the list items needs to be stored in a variable. You can do this using the [HTTP request action block](/build/integrations/http-request-api).

{% hint style="info" %}
Make sure you store the entire payload response in a variable. Do not append anything after the result on the object path to do this.
{% endhint %}

<figure><img src="/files/j8O9tMXWSZIVqY57ACxU" alt=""><figcaption><p>Mapping of response into a variable</p></figcaption></figure>

## Step 2: Setup the Dynamic data action block

Add the 'Dynamic data' action block after the HTTP request action block and configure the details.

#### Data variable

Contains the entire payload response received from the API. In our example, it is the `response` variable.

#### Action block to generate

Choose the action block that you would like to generate. Dynamic data supports the following action blocks,

* Button
* Carousel
* Option (WhatsApp and SMS)
* List (WhatsApp)
* Reply button (WhatsApp)
* File

#### Question

Configure the block for the question i.e. what question is to be shown while displaying the list items.

#### Configuring list items

Depending on which action block you have chosen, you would then map the object paths of the data you want to shown for that action block.&#x20;

For example, if the payload response stored is the following,

```json
[
    {
        "product_id": "123",
        "status": "pending"
    },
    {
        "product_id": "456",
        "status": "delivered"
    },
    {
        "product_id": "798",
        "status": "pending"
    }
]
```

And if we want to render the product\_id from this list as button, we would configure the object path as follows:

`result[*].product_id`

Where \[\*] denotes that we need to display all occurances of the field **product\_id**.


# Javascript

Executes a javascript code on the client side.

{% hint style="info" %}
Available on the **PREMIUM** plan and above.
{% endhint %}

Javascript is basically a piece of code that can be run on the browser to perform an action. Some of the cases where a Javascript action block can be used are:&#x20;

* Performing maths calculations.
* Dynamically rendering the values of the variables.&#x20;
* String modification.
* Firing & tracking events in Google Analytics.

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

You can choose to run the Javascript code on:

* **Client** — The code runs on the user’s device (like their browser or phone).
* **Server** — The code runs on your backend server instead of the user’s device.

You can also **execute your JavaScript code asynchronously** without the bot enforcing a delay on the end user. This results in a smoother experience with improved chat speed.

## Math calculations:&#x20;

Here are few of the snippets that you can use to perform the maths calculations within the chatbot flow:&#x20;

<table data-full-width="true"><thead><tr><th width="204.5946044921875" align="center">Parameter</th><th width="230.865478515625" align="center">Snippet</th><th align="center">Description</th></tr></thead><tbody><tr><td align="center">Summation (Addition)</td><td align="center"><em>const additionResult = num1 + num2;</em></td><td align="center"><ul><li>Num 1 &#x26; Num 2 can be any number or variable which has a number stored in it</li><li>The result will be stored in <em>additionResult</em> variable</li></ul></td></tr><tr><td align="center">Subtraction (Minus)</td><td align="center"><em>const additionResult = num1 - num2;</em></td><td align="center"><ul><li>Num 1 &#x26; Num 2 can be any number or variable which has a number stored in it</li><li>The result will be stored in <em>additionResult</em> variable</li></ul></td></tr><tr><td align="center">Division (Divide)</td><td align="center"><em>const additionResult = num1 / num2;</em></td><td align="center"><ul><li>Num 1 &#x26; Num 2 can be any number or variable which has a number stored in it</li><li>The result will be stored in <em>additionResult</em> variable</li></ul></td></tr><tr><td align="center">Multiplication (Multiple)</td><td align="center"><em>const additionResult = num1 * num2;</em></td><td align="center"><ul><li>Num 1 &#x26; Num 2 can be any number or variable which has a number stored in it</li><li>The result will be stored in <em>additionResult</em> variable</li></ul></td></tr></tbody></table>

## Storing values into variables:&#x20;

Here are few of the snippets that you can use to render values in variables.&#x20;

<table><thead><tr><th width="199.9375" align="center">Parameter</th><th align="center">Snippet</th><th align="center">Example</th></tr></thead><tbody><tr><td align="center">Set Variable (Conversation)</td><td align="center"><p><em>wn.setConversationVariable(“variable_name”,”variable_value”);</em><br></p><p><em>Or</em> <br></p><p><em>WotNot.setConversationVariables({“variable_name”:”variable_value”})</em></p></td><td align="center"><p><em>wn.setConversationVariable(“name_wn”,”ABC”);</em></p><p></p><p><em>Or</em></p><p></p><p><em>WotNot.setConversationVariables({“t1”:”123”})</em></p></td></tr><tr><td align="center">Set Variable (Contact)</td><td align="center"><p><em>wn.setContactVariable(“variable_name”,”variable_value”);</em><br></p><p><em>Or</em> <br></p><p><em>WotNot.setContactVariables({“variable_name”:”variable_value”})</em><br></p></td><td align="center"><p><em>wn.setContactVariable(“name_wn”,”ABC”);</em></p><p></p><p><em>Or</em><br></p><p><em>WotNot.setContactVariables({“t1”:”123”})</em></p></td></tr></tbody></table>

## String modification:&#x20;

Here are few of the snippets that you can use to calculate the length of the variable or get part of the variable.&#x20;

<table><thead><tr><th width="208.66143798828125" align="center">Parameter</th><th width="239.998291015625" align="center">Snippet</th><th align="center">Example</th></tr></thead><tbody><tr><td align="center">Length of String</td><td align="center"><em>const lengthOfString = “variable_name”.length();</em></td><td align="center"><p><em>const lengthOfString = “some_string_content”.length();</em></p><p></p><p><em><strong>//Output: 19</strong></em> </p><p></p><p>Calculates the number of characters passed/present in the value</p><p><br></p></td></tr><tr><td align="center">Get part of a string</td><td align="center"><em>const partOfString = “variable_name”.slice();</em></td><td align="center"><p><em>const partOfString = “some_string_content”.slice(5);</em></p><p><br><strong>Note: We need to pass the starting index from where we need to get the sub-string. The index starts from 0.</strong><br><br><strong>//Output: string_content</strong><br><br>Commonly used to pass the phone number without country code</p></td></tr></tbody></table>

## Fire & Track events in Google Analytics:

Here is the snippet that you can use to push or record events into Google Analytics or any other analytics tool

<table><thead><tr><th width="175.04595947265625" align="center">Tool</th><th width="308.5130615234375" align="center">Snippet </th><th align="center"> Example</th></tr></thead><tbody><tr><td align="center">Google Analytics 4</td><td align="center"><p><em>window.dataLayer = window.dataLayer || [];</em></p><p><em>function gtag() {</em></p><p>  <em>window.dataLayer.push(arguments);</em></p><p><em>}</em></p><p><em>gtag("js", new Date());</em></p><p><em>gtag("config", "YOUR-MEASUREMENT-ID");</em></p><p><em>gtag("event", "YOUR-EVENT-NAME", {</em></p><p>  <em>"send_to": "YOUR-MEASUREMENT-ID"</em></p><p>  <em>// Additional parameters that you may want to pass</em></p><p><em>});</em></p></td><td align="center"><p>window.dataLayer = window.dataLayer || [];</p><p>function gtag() {</p><p>  window.dataLayer.push(arguments);</p><p>}</p><p>gtag("js", new Date());</p><p>gtag("config", "123");</p><p>gtag("event", "WotNot_Test", {</p><p>  "send_to": "123",</p><p>  "name": "Test",</p><p>  "phone": "123456789",</p><p>});</p></td></tr></tbody></table>

## Triggering day-based flow:

Here is the snippet that you can use to trigger the flow based on specific day

|                   Parameter                  |                                                                                                                   Snippet                                                                                                                  |                   Description                   |
| :------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------: |
|               Get current date               |                                                                                                      *const currentDate = new Date();*                                                                                                     |          Helps to get the today’s date          |
| Check if Fromdate should be more than Todate | <p><em>isFromDateBeforeToDate(fromDate, toDate) {</em></p><p>  <em>const fromDateObj = new Date(fromDate);</em></p><p>  <em>const toDateObj = new Date(toDate);</em></p><p>  <em>return fromDateObj < toDateObj;</em></p><p><em>}</em></p> | Helps to trigger the flow the day specific flow |


# Set variable

The Set Variable action block lets you assign a specific value to a variable during a conversation flow. As the name suggests, you can define or update a variable with a new value at any point in the chat.

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

## Why use the Set Variable block?

Variables are powerful because they allow you to store information, pass it between steps, and personalize the conversation. The Set Variable block makes it easy to:

* **Control logic in the flow** – Define flags or states (e.g., mark if a user is a “qualified lead”).
* **Pass data to integrations** – Pre-set values that need to be sent to your CRM, helpdesk, or other systems.
* **Simplify expressions** – Store a reusable value instead of repeating it in multiple places.
* **Personalize experiences** – Assign values like “plan = Premium” or “status = Returning Visitor” to tailor responses.

## Where can it be used?

You can use the Set Variable block in a variety of situations, such as:

1. **Lead qualification**
   * Example: If a user selects “Company Size = 500+,” you can set a variable lead\_segment = Enterprise.
   * This makes it easier to filter and route leads later.
2. **Conversation routing**
   * Example: Set support\_priority = High if the user reports an urgent issue.
   * You can then use this variable in assignment or branching rules.
3. **Default values**
   * Example: When no data is captured from the user, you can set a variable like region = Unknown.
4. **Experimentation & tracking**
   * Example: For A/B testing different flows, set test\_group = A or test\_group = B.

## How to configure the block

1. Drag and drop the Set Variable action block into your flow.
2. Choose the variable you want to set (or create a new one).
3. Enter the value you want the variable to hold.
4. Connect it to the next step in the conversation.

{% hint style="info" %}
**NOTE:**&#x20;

* You can use variables to map values to variables.
* You can use arithmetic operators to define values as well.
  {% endhint %}


# Collect file

Collects a file(s) from the user during a chat.

Collect file action block is best used when you want to collect any file or image from your visitors.&#x20;

<figure><img src="/files/2SnqTtkKUQ5r6IoBkZPD" alt=""><figcaption></figcaption></figure>

### Configuration

* **Question**: Ask a question that will prompt your visitors to upload a file or image. For example: “Can you upload the invoice?”&#x20;
* **Format**: Select the type of files that you would like to allow visitors to upload.
  * .pdf
  * .jpg
  * .png
  * .heic
  * .doc
  * .docx
  * .ppt
  * .xls
  * .xslx
  * .csv
* **Restrict file size**: Set the maximum file size from 1 MB to 10 MB that a visitor can upload from the drop down list.
* **Restrict number of files**: Set the maximum number of uploads from 1 to 10 allowed for the visitor.
* **Save response**: Select or create a [variable](/build/interface/variables) where the user’s uploaded file will be stored. This variable can be referenced later in your workflow.

{% hint style="info" %}
**Note**: The uploaded file is stored on WotNot’s cloud server, and a publicly hosted file URL will be stored in this variable.
{% endhint %}


# Form

Collects multiple inputs in a single go.

Using the form action block, you can collect multiple inputs in a single view making it easier for the user to submit and saving time. Also, this helps reduce drop-offs, as users tend to exit if the chatbot asks for multiple questions in the chat flow.

Form action block consists of the following:

{% embed url="<https://www.loom.com/share/997f235fa1d74887982c30c07ac40878?sid=37e5a5e3-2756-4fa2-92ce-17f014987f95>" %}
Setting up 'Form' action block
{% endembed %}

## Question

Before showing the form itself, this question helps set the context of why the user is being asked to complete the form.

For example, “Can you please help me with your contact information?”

## Form fields

Form fields are individual inputs that make up the form. Users must fill these fields out to proceed in the chat flow.&#x20;

Each form field is made up of the following;&#x20;

* **Name of the field** – Provide the name of the field that will appear to your visitor.
* **Variable** – Map the variable in which the response provided by the visitors will be stored.
* **Optional flag** – You can choose to keep this form field as optional.

{% hint style="info" %}
You can add a maximum of up to 5 form fields.
{% endhint %}


# Webhook

Listens to events that occur on this event and proceeds to the next step in the flow.

{% hint style="info" %}
Available on the **PREMIUM** plan and above
{% endhint %}

Webhooks are used to listen to events occurring on a third-party app.&#x20;

It is most commonly used for use cases like payment collection, where the chatbot waits for the third-party payment processor to call the webhook once payment is received.

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

## Endpoint

Set this webhook endpoint on the application that will publish the event.&#x20;

When invoking this endpoint, it is mandatory to return the `conversation_key` as part of the response payload; if it is not present, our systems will not consider it a successful response.

You can use the variable **Conversation URL** to extract the conversation\_key value from it.

Use a javascript action block before using the webhook block with this code.

```
const conversation_url = "Conversation URL";

// Function to extract the conversation key from the URL
function getLastPartOfUrl(url) {
    // Split the URL by slashes
    const parts = url.split('/');

    // Return the last part
    return parts[parts.length - 1];
}

// Retrieve the conversation key from the URL
const conversation_key = getLastPartOfUrl(conversation_url);

// Sets the conversation key into a new variable
wn.setConversationVariable("conversation_key", conversation_key);

// This variable will be used to push the conversation_key to the third-party app.
```

## Timeout

The chat flow will wait for this webhook call for the specified duration.&#x20;

If the webhook is not invoked in the given timeframe, the chat flow will proceed in the <mark style="background-color:red;">FAILURE</mark> flow.

{% hint style="info" %}
Set the duration between 1 and 300 seconds.
{% endhint %}

## Response

When a webhook response is received, you can map the fields that are to be saved into variables.&#x20;

{% hint style="info" %}
You can map a maximum of 50 variables.
{% endhint %}


# Flow

Breaks down larger flows into manageable chunks.

Flow action block is used to segment parts of your chatbot tree into smaller flows.&#x20;

For example, if you have three items in your menu like Explore WotNot / Talk to sales / Support, instead of building all the flows in one tree, you will build three flow with the same names. So that each flow has only its flow in it.

## How does it help?&#x20;

* Creating smaller manageable flows for each path
* Easier navigation between conversational flow
* Easier onboarding of teams to the chatbot

{% embed url="<https://www.loom.com/share/6d6b2e891dd74d7da24cc107d536dab4?sid=0cb4500c-7250-4b9e-975e-7598562a568f>" %}
Setting up 'Flow' action block
{% endembed %}

## Creating a flow

Click on + and choose the 'Flow' action block

<figure><img src="/files/9XqCRnx7V8bmT5s6SCYu" alt=""><figcaption></figcaption></figure>

## Entering a flow

1. Double click on the "Flow" node&#x20;

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

2. Click on the flow dropdown at top-left and choose the flow

<figure><img src="/files/7GE5NtGYU7o0QMlKHzCN" alt=""><figcaption></figcaption></figure>

## Moving selections into a flow

If you already have a flow already built that you want to move inside a 'Flow' action block, follow these steps:

* Hold shift and select the area of action blocks you want to move
* Click on the 'Move' icon
* The highlighted flow will be moved to your desired 'Flow' action block

<figure><img src="/files/3ebSNPtJwvcVzbHAmMWs" alt=""><figcaption></figcaption></figure>


# Jump

Routes the chatbot flow to the specified action block.

Allows users to jump from one point of the flow to another, without having to create a connection between the blocks.

This becomes extremely helpful when you have a very large chatbot tree, and connecting the two blocks is tough.&#x20;

To configure a Jump action block:

* **Title** — you can rename the jump block to keep your flow organized and easy to understand.
* **Jump to** — select the exact action block where you want the flow to go to.

Once configured, the conversation will immediately continue from the selected action block when users reach the Jump block.

<figure><img src="/files/2xemvTb3fFeGU6gWBM5Q" alt=""><figcaption></figcaption></figure>


# Options

Displays a list of options for the user to choose from.

{% hint style="info" %}
Available only for SMS and WhatsApp channels.
{% endhint %}

Using this action block you can display a list of options the user can choose from. It is most commonly used when a selection from a list of items is to be made.&#x20;

The options in the list are displayed in an ordered list, such as:

<div align="left"><figure><img src="/files/Tt8X8dmQMQMr7EY8lPw9" alt="" width="375"><figcaption></figcaption></figure></div>

Option action block is made up of the following:

1. Message
2. List of options
3. Error message
4. Variable
5. Hot keywords

### Message

This is the question the bot would ask while presenting the list of options.&#x20;

For example, "Please choose from the list of options below".

### List of options

The list of options that are to be shown will be defined here.&#x20;

Up to **10 options** can be included in one action block. If you need more, you can nest 'Option' blocks together.&#x20;

Users can select from options by typing the following,&#x20;

* The numeric digit i.e. 1, 2, 3...
* Alphabetic name i.e. one, two, three...&#x20;
* Value of the option itself, i.e., Blue, Green, etc.

### Error message

When submitting a selection from the list of options, if any input does not match the list, this error message will be shown along with the list of options.&#x20;

The user will have to retry by entering a valid number.

### Variable

Users can store the value of the selected option in a variable for future reference.&#x20;

For example, if I choose 2 from the above image, 'Yellow' would be stored on the variable.

[Learn more about variables](/build/interface/variables).

### Hot keywords

You can define hot keywords that bring users to this action block, wherever they are in the conversation flow.&#x20;

Imagine you are at a certain point in the flow. To return to this action block, you can type the keyword MENU.

### Enable free text

By enabling "Enable free text" option, users can either choose from predefined buttons or type their own response in the chat input. Also, on the canvas a new "Free text" node will be added, which can be connected to an [AI agent](/build/action-blocks/agent) action block for AI-generated responses.

This allows for more natural, two-way conversations, and any free text entered can be handled by an AI agent for dynamic responses.

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


# Calendar

Calendar action block is used for collecting date from the or for booking appointments

The calendar action block opens a calendar UI in the chat widget. Visitors can choose a date from the calendar view.

Some use cases of the calendar block are appointment booking, requesting a callback, and entering a date of birth.

Here is what you need to setup the calendar action block:

{% embed url="<https://www.loom.com/share/439306e3b3534f4c97bfb28f5ff60511?sid=4ab59bb6-5225-4d4b-8f7b-fc6d9896ffe5>" %}
Setting up 'Calendar' action block
{% endembed %}

## Question

Before showing the calendar UI, you need to ask a question to let users know why they are seeing it in the first place.&#x20;

For example, “Select your desired date of appointment”.

## Variable

Variables store the date selected by the user so that it can be referenced later.&#x20;

You can choose an existing variable from the dropdown or create a new one.

[Learn more about variables here](/build/interface/variables).&#x20;

## Other configurations

Few more configuration options you can use:

### Nature of date selection

You can choose to allow users to select from a single date selection or a date range selection. Currently, only single date selection is available for use.

### Show past dates

Enabling this will allow visitors to choose past dates from today as well. Disabling it will only show the dates from today to the future.

### Exclude days

You can choose to exclude certain days of the week, like Saturday and Sunday, from this dropdown. Doing so will always prevent those days from showing up in the calendar UI.

### Exclude specific dates

You can click on the calendar icon and select the date you want to disable in the calendar UI. These could be to hide dates of public holidays in your region.&#x20;

<br>


# Delay

Adds a specified wait time to the flow.

Using the delay action block, the chatbot will intensionally show a typing indicator for the specified duration before proceeding to the next step in the chatbot flow.

You can add delays from **1s, 2s, 5s, and 10s**.

{% embed url="<https://www.loom.com/share/be6dbbdfd8614478b12b9d4363eb58b1?sid=c91aa28c-d04d-4843-ae7c-bd3188065f5b>" %}
Setting up 'Delay' action block
{% endembed %}

Alternatively, if you want to generally add delays to all your chatbot messages you can goto Channel configuration -> Web -> General settings.&#x20;

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

## Delay (in outbound bots)

Adds an intentional delay period for which the contacts do not proceed forward in the execution flow.

You can add the following type of delay:

* **Relative** - for a relative time period i.e. 4 hours, 5 days etc.
* **Fixed** - exact date/time i.e. 21 Jun 2024 10 am America/New York

<figure><img src="/files/0oCvLxMaO2nrOE17Lkmd" alt=""><figcaption></figcaption></figure>

You can see the number of contacts in the wait queue until the contacts are delayed.

{% hint style="info" %}
Deleting the 'Delay' action block will allow the waiting contacts to proceed immediately to the next step of the flow.
{% endhint %}


# Codeblock

Codeblock allows you to create and execute custom functions built by WotNot.

These functions are made by the WotNot team to deal with complex requirements on customer projects.&#x20;


# Slider

An interactive way of collecting a value from the user.

{% hint style="info" %}
Available on the **WEB** channel only.
{% endhint %}

Slider is used to collect a numerical value from the user in a visual way.

Below is how the slider looks like in the web channel:

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

{% embed url="<https://www.loom.com/share/3ee9bbb91142496a87327d93063755c3?sid=9445cd2a-9728-4a2b-84bb-73ebcb67bc3c>" %}
Setting up 'Slider' action block
{% endembed %}

A slider action block is made up of:

## Question

A question to give context to the user on choosing the value from the slider.

## Range

Enter the range values (Minimum to Maximum) that you want to allow the visitors to choose from.

## **Variable**&#x20;

Stores the selected value into this variable for future referencing.&#x20;

[Learn more](/build/interface/variables).

## **Enabling step account**

By default, the slider will have a free-flowing slider.&#x20;

Enabling this config allows you to create steps in the slider. Once enabled, you can choose the number of step counts to be displayed.

{% hint style="info" %}
The value for the step count can be between 2 & 5
{% endhint %}

## **Unit for slider values**

Select a unit for the slider values from the drop-down list, i.e., $, ‎€, ₹, £, °C.&#x20;

By default, we do not have any unit assigned to the slider


# Image gallery

Displays a set of images in a carousel.

Image Gallery action block is used for displaying a set of images in a carousel.&#x20;

{% embed url="<https://www.loom.com/share/d9992e0eafe44df988aa104a708edb99?sid=75ac6f8e-bf22-4a4b-acb9-60b4a2bff5ad>" %}
Setting up 'Image Carousel' action block
{% endembed %}

This is best suited for use cases like showing a bunch of images after a real estate property or product is selected.&#x20;

{% hint style="info" %}
**Note**:&#x20;

* Maximum size per file allowed is 10 MB
* Supported formats are .png, .jpeg or .jpg
* Maximum number of images that you can add in single action block is 10
  {% endhint %}


# Send WhatsApp

Send an outbound WhatsApp template message to a contact.

{% hint style="info" %}
Available on **OUTBOUND** bots only.
{% endhint %}

Using the Send WhatsApp action block, you can send a WhatsApp message proactively to your contact.

Most commonly used for use cases like:

* Sending promotional message
* Feedback surveys&#x20;
* Appointment confirmation&#x20;

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

To configure the 'Send WhatsApp action block:

1. Add the 'Send WhatsApp' action block on the canvas&#x20;
2. Choose the WhatsApp number you want to send the message from using the 'From' field.&#x20;
3. Choose the variable containing the contact's phone number in the 'To' field
4. Select the approved WhatsApp template message that you want to send

If you have used 'Reply buttons' in your template message, you can configure the button payload you want to send for each button.&#x20;


# Send SMS

Send an outbound message to a contact on SMS.

{% hint style="info" %}
Available on **OUTBOUND** bots only.
{% endhint %}

Using the Send SMS action block, you can send an SMS message proactively to your contact.

Most commonly used for use cases like:

* Sending promotional message
* Feedback surveys&#x20;
* Appointment confirmation&#x20;

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

To configure the 'Send SMS' action block:

1. Add the 'Send SMS' action block on the canvas&#x20;
2. Choose the number you want to send the SMS using the 'From' field.&#x20;
3. Choose the variable containing the contact's phone number in the 'To' field
4. Add the message that you want to send

{% hint style="info" %}
SMS texts have a limit of **160 characters**.
{% endhint %}


# Send MMS

{% hint style="info" %}
Available on **OUTBOUND bots** only
{% endhint %}

Using the Send MMS action block, you can send an MMS message proactively to your contact.

Most commonly used for use cases like:

* Brochures
* Offer pamplets

To configure this action block, you need to provide the following:

**Phone number** — which number do you want to send this MMS from

{% hint style="info" %}
We only support TECHALPHA as the SMS provider for this functionality at the moment.
{% endhint %}

**To** — the field which contains the phone number of the recipient.

**Media** — upload the media that you want to send.&#x20;

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


# Send Email

Send outbound email to a list of contacts.

{% hint style="info" %}
Available only for **TECHALPHA** as an email provider.
{% endhint %}

If you intend to send an email to your contacts in the outbound bot, you can use the 'Send Email' action block.

<figure><img src="/files/5DZXrsZRgkQi9iEIAeFB" alt=""><figcaption></figcaption></figure>

To configure the 'Send Email' action block:

1. Add the 'Send Email' action block on the canvas&#x20;
2. Choose/Add the 'From' address.
3. Choose the 'Reply to' address.
4. Choose the variable containing the contact email address in the 'To' field.
5. Add email addresses to 'CC'.
6. Add email addresses to 'BCC'.
7. Select the email template you want to send.&#x20;

You can choose to view the template by clicking the 'Template preview' button.&#x20;

## Unsubscriptions

WotNot now natively manages email unsubscriptions for your outbound campaigns. With native unsubscription management, every unsubscribe is tracked directly in WotNot, giving you full control over your contact lists and subscription groups from one place.

### **For contacts receiving your emails:**

1. A contact receives a campaign email sent via an outbound bot.
2. They click the **Unsubscribe** link in the email.
3. They are taken to WotNot's hosted **Subscription Preferences** screen, where they can unsubscribe from specific groups or all communications.
4. Their unsubscription is recorded immediately in WotNot.

### **For you managing campaigns:**

1. Navigate to your outbound bot and open the **Send Email** block.
2. When designing your campaign, assign the email to one or more **Unsubscription Groups**.
3. After your campaign runs, go to **Settings > Email > Unsubscribed Contacts** to view which contacts have unsubscribed and from which groups.
4. Unsubscribed contacts are automatically excluded from future sends to those groups.

### Key things to know

* Unsubscriptions are now tracked in WotNot — you no longer need to cross-reference your transactional email provider to know who has opted out.
* You can create and manage **Unsubscription Groups** (e.g. "Product Updates", "Weekly Newsletter") so contacts can selectively unsubscribe rather than opting out entirely.
* Contacts who unsubscribe are automatically suppressed from future campaign sends to those groups.
* The WotNot Subscription Preferences screen is hosted and handled by WotNot — no custom setup required.
* Historical unsubscriptions recorded only on your email provider's side are not retroactively imported.


# Send Status

Design personalized campaigns based on conditions.

When an outbound message is sent to a contact via SMS or WhatsApp, the message can either be:

* **Not sent:** Email has bounced or failed to send.
* **Sent:** Email has been sent to the email sending service, but not yet delivered.
* **Delivered:** Email has been delivered to the contact.
* **Opened:** Email has been opened at least once by the contact.
* **Clicked:** User has interacted with the email by clicking at least one URL inside the email.

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

### How it helps?

Say you sent a broadcast to a group of 1000 people, and 200 of them did not have the message delivered, because they do not have a WhatsApp account, you can use the Send Status block to send them an SMS/Email instead.


# WhatsApp flow

WhatsApp Flows is a way to build structured interactions for business messaging. With Flows, businesses can define, configure, and customize messages with rich interactions that give customers more structure in their communication.

[Learn more about flows](https://developers.facebook.com/docs/whatsapp/flows/)

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

To configure the Whatsapp flow action block:

## Step 1: Create a template&#x20;

To initiate a WhatsApp flow, you must first create a flow on your Facebook account.&#x20;

* Go to your **Facebook Business settings** → **WhatsApp Manager**, or click [**here**](https://business.facebook.com/wa/manage).
* Under Account tools → Select **Message Templates**.

This will allow us to use the drag-and-drop builder to create our WhatsApp Flow. You won’t have to submit a template at the end of this guide — we’re just using this to access the drag-and-drop Flow builder.

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

* Select **Create Template**.

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

* Choose the category of the flow

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

* Customize your flow details using the drag-and-drop builder for WhatsApp flows.

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

* You can add multiple screens as part of one flow by clicking on **+ Add new** on the left and giving your screen a name.

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

* Customize your flow screen by editing the components you add. You can choose to add radio, input, text input, dropdown, date picker, [and many more](https://developers.facebook.com/docs/whatsapp/flows/reference/flowjson/components/).

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

* When you’re done, click **Save**:

<figure><img src="/files/5vhFobujgqoP7HMbJtet" alt=""><figcaption></figcaption></figure>

Your WhatsApp flow is now created and you can find it in the WhatsApp manager menu -> Account tools, select Flows:

<figure><img src="/files/2WohFEvBgPQkg5HToEsX" alt=""><figcaption></figcaption></figure>

### Restrictions

* You can add up to 8 components on every screen. A multiple-choice question is considered one component, regardless of the number of choices.
* The maximum number of screens per WhatsApp Flow is also 8.

## Step 2: Setup the "WhatsApp flow" action block

Add the "WhatsApp flow" action block on the bot builder and configure it.

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

#### Header <a href="#header" id="header"></a>

Shows the text in a bold format -- making it look like a title. It is an optional field.

#### Body <a href="#body" id="body"></a>

The text will be the question associated with showing the list of options.

For example, "Select the service you are interested in".

#### Footer <a href="#footer" id="footer"></a>

The text is displayed in a small grey color format. Mostly used to display a disclaimer to the user when selecting the option from the list.

#### Button name <a href="#button-name" id="button-name"></a>

Along with the above, a button will be displayed, on click of which we will show the list of options in a drawer format.

You can write the button's name here, such as 'Choose', 'Select', etc.

**Error message**

If the user types a random text instead of clicking the button, this error message will be sent.

## Step 3: Select and setup the WhatsApp flow

* Choose the flow from the dropdown
* And the starting screen you want to launch when the flow is executed.

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

{% hint style="info" %}
We will show the flows in the dropdown that are fetched from the phone number that you have connected for that bot on the "**Trigger**" action block.
{% endhint %}

* Next, select the data that you want to send from WotNot to the WhatsApp flow
* Map the fields fetched from the flow with the values/variables that you want to send

This is done to make the flow dynamic and contextual to the user's interactions.

## Step 4: Store the responses into variables

After the flow is executed and the user has completed interacting with it, choose the results that you want to store into variables for further use in the chat flow.

This could be things like dropdown selected, input added etc.

Map the response path with the variable that you want to store it in.

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


# Catalogue

{% hint style="info" %}
Available on **WHATSAPP** channel for all plans
{% endhint %}

Using Catalogue, you can display a list of products that users can browse, select, and add to their cart for a seamless shopping experience.

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

## Configuring the action block

Below are the configurations to setup the Catalogue as per your business use case.

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

### Catalogue type

Depending on how many products you wish to show to users, choose an option:

* **Entire catalogue** - displays all your products.
* **Single product** - displays only one product.
* **Multi product** - displays the list of selected products.

### Catalogue ID

To use the Catalogue on WhatsApp, first you need to create a Catalogue on your Meta business manager. Once you upload the list of all your products on Meta business manager, use your Catalogue ID here to reference it.

[Learn how to create a catalogue](https://en-gb.facebook.com/business/help/1275400645914358?id=725943027795860)

### Product ID

Enter the list product IDs that you want to display in the catalogue.

You can list various products into sections using 'Multi product' catalogue type.

### Content

Write the header, body and footer text which will be displayed to prompt the user to open and view your catalogue.&#x20;

### Variable

Once the user adds products to the cart and checks out, the entire cart will be stored in this variable in a JSON format.&#x20;

Here is the sample JSON payload which will be stored in the provided variable,

{% code fullWidth="false" %}

```json
{
  "product_items": [
    {"product_retailer_id": "331100", "quantity": 1, "item_price": 195, "currency": "INR"},
    {"product_retailer_id": "112233", "quantity": 1, "item_price": 60, "currency": "INR"}
  ],
  "catalog_id": "712073530499979",
  "text": ""
}
```

{% endcode %}

You can then parse this JSON response and create a order in your order management system or generate a payment link to collect payment and confirm the order.

E.g. above JSON response is stored in a "purchased\_products" variable, then following Javascript can be used to parse the JSON response,

```javascript
var purchased_products = #purchased_products#;

let totalAmount = 0;

purchased_products.product_items.forEach(item => {
  totalAmount += item.item_price * item.quantity;
});

wn.setConversationVariable("amount", totalAmount); // "amount" is a conversation type variable
```

## Restrictions

* Max products that can added to a catalogue - 500
* Max products that can be displayed at a time - 30
* Max products under a section - 30
* Max sections in a catalogue - 10


# Collect location

Collects the location from the end user on WhatsApp

You can now **collect user location seamlessly on WhatsApp** using a native block that allows users to share their location with just a tap of a button—no typing required.

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

### Question

The question to be asked when collecting the location from the user. This question will be followed with a "Send location" button.&#x20;

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

### Error message

The error message to be sent when the user sends something unexpected than the location details i.e they closed the location input screen and typed something random.

### Location response

When the user submits the location, we receive the following details:

* Location name
* Address
* Latitude
* Longitude

You can map these fields to your variables to use the collected data for API calls for anything else.

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


# Send template

Sends a WhatsApp template message

{% hint style="info" %}
Available only on the **WHATSAPP** channel
{% endhint %}

You can now use the new **Send Template** block in inbound bots to send rich template messages during a chatbot conversation.

This enhancement allows you to go beyond standard message formats like reply buttons and lists, enabling support for **media-rich carousels**, **image+text combo messages**, and more — all within the same conversation flow.

This gives you more flexibility to deliver engaging, visually appealing experiences to your users.

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

{% hint style="info" %}
**Note**:

* Make sure you have selected the phone number on the "Trigger" block to see the list of its approved templates.
* Only "Approved" templates will be listed in the dropdown
  {% endhint %}


# Knowledge base

Source of information used by AI to answer your questions.

To use AI to generate answers, you need to first build a knowledge base with the information you want the answer from.&#x20;

A knowledge base is nothing but a collection of data sources. Think of it as chapters in a book, the more chapters the more information it has.

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

A data source can be one of three types:

* URL
* File
* Text

## URL

You can add content using a domain or a set of web pages.

**When using a domain**, you simply enter the domain address or sitemap address, and our system will automatically import all URL(s) of that domain.

**Supported types:**

* Domain i.e. [https://wotnot.io](https://wotnot.io/)
* Sitemap i.e. <https://wotnot.io/sitemap.xml>

As good practice, it is always better to delete the URLs that are not needed to avoid wrong or incorrect answers from the bot. Because, the more junk you add, the more confused the AI gets.

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

**When using webpages**, you explicitly list down the exact URL(s) you want to import content from.

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

{% hint style="info" %}
Refer to plan details at [www.wotnot.io/pricing](https://help.wotnot.io/build/www.wotnot.io/pricing) to know the maximum number of data sources that can be added to a knowledge base.
{% endhint %}

### Advanced crawling criterias

Crawling of a website happens real quick, if you find no content being crawled try adding the following configurations:

* **wait time** - delay in crawling until your page loads.
* **wait CSS** - delay in crawling until a CSS selector is loaded.
* **Execute Javascripts** - to prevent any unwanted popups to be crawled instead of the actual webpage content.

<figure><img src="/files/Q0fXlRWaY3pTsFLX0wju" alt=""><figcaption><p>Advanced crawling criterias</p></figcaption></figure>

### Refreshing domain

If you have trained your knowledge base with a domain, you can choose or change the refresh frequency by clicking on the 'Domain(s)' button.

Changing the frequency will apply to all child URL(s) which are fetched from this domain. However, changing child frequency manually, will not impact the parent domain.

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

## File

You can add content by uploading a set of documents to your knowledge base.&#x20;

Upload one or files and click 'Train' to start training your knowledge base with the contents of those files.

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

**Supported file types:**

* csv
* xlsx
* txt
* pdf
* doc
* docx

{% hint style="info" %}
Max file size supported is 5 MB.

Refer to your plan details at [www.wotnot.io/pricing](https://help.wotnot.io/build/www.wotnot.io/pricing) to know the maximum number of URL(s) that can be fetched.
{% endhint %}

## Text

You can also directly add the information as content to the knowledge base.

By choosing this data source method, you can copy-paste the content you want to add.

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

{% hint style="info" %}
A maximum of 2,500 characters is allowed.
{% endhint %}

{% hint style="info" %}
**NOTE**:

While custom JSON databases aren't directly supported, users can convert JSON into `.txt` files to upload for training. Also mention users can connect this knowledge base to a bot to check response accuracy.
{% endhint %}

## Chunks

Clicking on a data source displays all the details of that data source i.e. when was it added, its refresh rate etc.&#x20;

“Chunks” are a way to handle large pieces of information by breaking them down into smaller, manageable parts.&#x20;

**When are chunks used?**

Chunks are used when the system needs to obtain specific information from the knowledge base to optimize the response generated.

When a user asks a question, here's what happens:

1. The system retrieves relevant chunks from the knowledge base that may contain the answer.
2. These chunks, along with prompts, are sent to OpenAI.
3. OpenAI generates a response using the provided chunks.
4. The response is then displayed to the user.

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


# Refresh frequency

Retrain allows you to refresh knowledge base at a given time interval.

Retrain allows you to train your knowledge base with the latest content on it.

For "URL" data sources, you can define a refresh frequency at which you want to retrain it. Frequency offered are:

* Daily
* Weekly
* Monthly

## Domain-level refresh

Enabling this will apply the refresh frequency to all its child pages.&#x20;

* Open the knowledge base
* Click "Domain(s)" button
* Select the frequency from the dropdown

Now, your domain will always be scanned again for new URL(s), and the content of all URL(s) will be scrapped again.

<figure><img src="/files/3Fe3BWQqPXJRwx55JIK4" alt=""><figcaption></figcaption></figure>

## URL-level refresh

Enabling this will apply the refresh frequency to only the selected URL.

* Open the Knowledge base
* Click on the "URL" data source you want to schedule a retrain&#x20;
* Select the frequency from the dropdown

<figure><img src="/files/2B2jZnMDjF1LL3bbSm0e" alt=""><figcaption></figcaption></figure>

You can also multi-select the URL data sources you want to schedule a refresh frequency in bulk.

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


# Functions

Execute functions to help your AI generate dynamic answers.

{% hint style="info" %}
Available in the **PREMIUM** plan and above.
{% endhint %}

AIs were limited to answering questions from your static knowledge base.

With function calling, you can have your AI execute third-party APIs or custom logic using Javascript code or HTTP Request to generate a dynamic answer.

First, we create a function form the AI Studio > Function Call screen

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

You can even create functions from Set AI and Answer AI blocks in Bot Builder screen.

Each function is made up of 2 things:

## Prompt

A brief description that helps the AI understand what this function does and when to invoke this function. It is important as you may create multiple functions, and the prompt helps the AI choose the right one.

For example: "when the user requests the status of their order"

## Function handler

This is the API details or Javascript code executed to generate the response to the question asked.&#x20;

This function would generally consist of:

* API endpoint that is to be invoked ([Learn more about HTTP request](/build/integrations/http-request-api))
* Conditions and logic to ask follow-up questions if parameters are missing

## Testing the function

On the function, click on 'Save & Run function' to open the test window.

You can customize the LLM model used and see the response generated by it.

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

Also, to view the exact execution of the function, you can click the 'Show log' to view the entire log.

Here you can view the arguments detected by the function and the output generated by the function.

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


# Outbound bots

Send proactive messages to your contacts.

{% hint style="info" %}
Support channels of outreach are **WhatsApp & SMS**.
{% endhint %}

Outbound bots are used to run broadcasts to your contacts.

It's most commonly used for sending promotional messages, transactional messages, follow-ups, etc.

### One-off campaign

Runs the broadcast only once for the uploaded contacts.

[Learn more](/build/outbound-bots/building-one-off-campaign)

### Ongoing campaign

Runs the broadcast everytime a contact is enrolled.

[Learn more](/build/outbound-bots/building-ongoing-campaign)


# Building One Off Campaign

Send a one-time campaign to a set of contacts on WhatsApp, SMS and email.

{% hint style="info" %}
Available on the **STARTER** plan onwards.
{% endhint %}

### Pre-requisites:&#x20;

Depending on the channel you want to run your campaigns on, you would need,

* Email API (Supported partner: Gmail, Microsoft, TechAlpha, Other)
* SMS API (Supported partner: Twilio, TechAlpha)
* MMS API (Supported partner: TechAlpha)
* WhatsApp API (Supported partner: Meta, 360dialog, Twilio, GupShup)

{% hint style="info" %}
If you do not have an API, you can reach out to sales at **`hello@wotnot.io.`**
{% endhint %}

## Step 1: Create a outbound bot using one-off campaign

Go to the bot builder page, and choose to create an outbound bot and select one-off as your campaign preference.

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

## Step 2: Upload your contacts

Click on the 'Trigger' action block and upload a 'CSV' file which contains the contacts you want to reach out to.&#x20;

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

Once uploaded, you need to map the columns of the CSV with the variables on your account. This mapping is done to help you dynamically replace values in the messages of your campaigns.&#x20;

For example, if you want to include a message like *"Hello {name}, glad we could meet on {date}",* you need to store the name and date field in the contact mapping.

{% hint style="info" %}
We consider the first row of the 'CSV' file as the column heading, these headings will be shown in the mapping of variables.
{% endhint %}

{% hint style="warning" %}
It is mandatory to have a phone/email field mapped, in order to be able to send a campaign to contacts.&#x20;
{% endhint %}

## Step 3: Create your outbound flow

Add a outbound block like **Send SMS** or **Send WhatsApp** and configure its fields on the right panel.

The configuration fields would differ based on the channel you use.&#x20;

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

## Step 4: Deploy your bot to run your campaign

Once your flow has been created, double-check all the messages for typos or any other mistakes and hit **Deploy**. \
\
A confirmation prompt will be shown to you for final approval before launching the campaign

{% hint style="info" %}
Once the bot is deployed, **it cannot be stopped**. All contacts will start getting the messages that you have defined&#x20;
{% endhint %}

## Step 5: See the results

Once the bot is deployed, it may take a few minutes for the bot to finish sending all the messages to the recipients. This delay may vary based on the contact list and the API provider you have used.&#x20;

Post that you can see the results of the campaign. Click on the numbers to go to a deeper view and be able to download a CSV which will contain the results of the campaign on a per contact basis.

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

[Learn more about outbound reports](/monitor/reporting/outbound-report)

## Stopping campaigns

To stop an active campaign, open the bot and click “Stop Campaign.”

Once stopped, all contacts currently in the queue will no longer receive any future messages.

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


# Building Ongoing Campaign

Trigger the outbound bot to start its campaign using webhooks to send the contact data.

{% hint style="info" %}
Available on the **STARTER** plan and above.
{% endhint %}

### Pre-requisites:&#x20;

Depending on the channel you want to broadcast on, you would need,

* Email API (Supported partner: TechAlpha)
* SMS API (Supported partner: Twilio)
* MMS API (Supported partner: TechAlpha)
* WhatsApp API (Supported partner: Meta, 360dialog, Twilio, GupShup, TechAlpha, Unifonic)

{% hint style="info" %}
If you do not have an API, you can reach out to sales at **`hello@wotnot.io.`**
{% endhint %}

{% embed url="<https://www.loom.com/share/1ba7323db31f495baaaec4564be78559?sid=9a64f62d-20d2-41fe-96eb-1eda4bad8447>" %}

## Step 1: Create an outbound bot

1. Goto Bot builder&#x20;
2. Choose "Build a bot" then select "Build an outbound bot"
3. Select "Ongoing" campaign as we want this broadcast to run when contacts are enrolled

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

## Step 2: Configuring the webhook

Click on the 'Trigger' block and choose **Webhook** as the import source.&#x20;

Your system should invoke our webhook with the required contact payload to trigger them into this broadcast.&#x20;

To trigger this webhook, you will need:

* **Webhook URL** - Found on the trigger block
* **Authorization token** - Go to Settings > Account Settings > Developer
* **Payload** - The contacts data you want to send the broadcast to

## Adding contacts to campaign

<mark style="color:green;">`POST`</mark> `https://outbound.wotnot.io/api/v1/outbound/...`

You can find your webhook URL on the trigger block of your outbound bot.

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

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

{% hint style="info" %}
**Token** — you can get your account token by going to Settings > Account Settings > Developer > and copy your "API Access Token"
{% endhint %}

**Body**

{% tabs %}
{% tab title="Single contact" %}

```json
{
  "id": 1,
  "name": "John",
  "phone": "12312313",
  "email": "test@test.com"
}
```

{% endtab %}

{% tab title="Multiple contacts" %}

```json
[
    {
    "id": "1",
    "name": "John Doe", 
    "phone": "18181818181", 
    "email": "example@email.com"
    },
    {
    "id": "2",
    "name": "James Doe", 
    "phone": "18282828282", 
    "email": "example@email.com"
    }
]
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
A maximum of **10,000 contacts** can be sent in single request
{% endhint %}

**Response**

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

```json
{
    "id": "7vrrqo3nwr3k130023374200bywmhn",
    "ok": true,
    "status": "in-progress"
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "status": 400,
    "message": {
        "data": [
            "Not a valid list."
        ]
    },
    "ok": false,
    "error": "BAD_REQUEST"
}
```

{% endtab %}
{% endtabs %}

## Step 3: Map the response fields to variables

To store the contacts received from your webhooks, map the API response fields with the contact variables that you want to save it in.&#x20;

This mapping is done to help you dynamically replace values in the messages of your campaigns.&#x20;

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

For example, if you want to include a message like *"Hello {name}, glad we could meet on {date}",* you need to store the name and date field as variables in the contact mapping.

{% hint style="danger" %}
It is mandatory to have a phone/email field mapped, in order to be able to send a campaign to contacts.&#x20;
{% endhint %}

## Step 4: Create your campaign flow

Create your desired flow by adding blocks like **Send SMS** or **Send WhatsApp** and configure its fields on the right panel.

The configuration fields would differ based on the channel you use.&#x20;

<figure><img src="/files/523g9BwVMXULj874CqBv" alt=""><figcaption></figcaption></figure>

## Step 5: Deploy to activate this campaign

Once your flow has been created, double-check all the messages for typos or any other mistakes and hit **Deploy**. \
\
A confirmation prompt will be shown to you for final approval before launching the campaign.

Now, when your systems invokes the webhook, the contacts will be enrolled into this outbound bot flow.

{% hint style="info" %}
You can turn off your outbound bot, if you do not want to accept any new requests.&#x20;
{% endhint %}

## Viewing campaign reports

Once the bot is deployed, it may take a few minutes for the bot to finish sending all the messages to the recipients. This delay may vary based on the contact list and the API provider you have used.&#x20;

Wait for a few mins and then visit Analytics > Outbound to see the reports.

[Learn more](/monitor/reporting/outbound-report)

<figure><img src="/files/5OWqSNoL0A9R6v0LGRRE" alt=""><figcaption></figcaption></figure>


# Prompts

Prompt/instruction is a set of rules an AI uses to generate an answer.&#x20;

By using the right prompts, we can make sure our AI chatbots are responding accurately and appropriately—and that we’re delivering more sophisticated and engaging user experiences. They're kind of like nudges in the right direction.

Some common reasons for using prompts are:

* To get a specific answer format
* Evade certain questions
* Length of the answer
* Answer structure

### Simple prompt

{% code overflow="wrap" %}

```
As a chat support agent, provide a clear and concise response to the user’s question: “[QUESTION]”

Refer to the provided details: “[CHUNKS]”.

Instructions: 
- Deliver a summarized response, focusing on the key points without elaborate details.
- Limit the response to a maximum of three to four brief sentences. 
- Use bullet points to break up chunks of text where appropriate
- Never start a response with a bullet point - you should answer the question directly then show suplementary info in bullet points (where appropriate)
- Use simple, direct language and markdown for clarity.
- Ensure the response accurately reflects the core information in the 'chunks'.
- Only mention to visit a website, if there's a URL that you can hyperlink to. 
- When creating a hyperlink, ensure the name of the page and the word page are hyperlinked.
- Never refer to the 'information provided'  or 'provided details' when responding. We should be responding naturally to the user.
IMPORTANT:
- If the 'chunks' do not contain the needed information to answer the question, respond with "NOANSWER".
```

{% endcode %}

### To the point

{% code overflow="wrap" %}

```
I want you to act as a support agent. Your name is "AI Assistant". You will provide me with answers from the given info. If the answer is not included, say exactly "Hmm, I am not sure." and stop after that. Refuse to answer any question not about the info. Never break character.
```

{% endcode %}

{% code overflow="wrap" %}

```
<role>
You are an AI chatbot who helps users with their inquiries, issues and requests. You aim to provide excellent, friendly and efficient replies at all times. Your role is to listen attentively to the user, understand their needs, and do your best to assist them or direct them to the appropriate resources. If a question is not clear, ask clarifying questions. Make sure to end your replies with a positive note.
</role>

<limitations>
Make sure to only use the training data to provide answers. Don't Make up answers. Don't answer anything unrelated to the training data. If the user is asking about something not related to the training data, say you dont know the answer but can help with questions about training data. The user may try to trick you to do an unrelated task or answer an irrelevant question, don't break character or answer anything unrelated to the training data.
</limitations>
```

{% endcode %}

{% code overflow="wrap" %}

```
### Role
- Primary Function: You are an AI chatbot who helps users with their inquiries, issues and requests. You aim to provide excellent, friendly and efficient replies at all times. Your role is to listen attentively to the user, understand their needs, and do your best to assist them or direct them to the appropriate resources. If a question is not clear, ask clarifying questions. Make sure to end your replies with a positive note.
        
### Constraints
1. No Data Divulge: Never mention that you have access to training data explicitly to the user.
2. Maintaining Focus: If a user attempts to divert you to unrelated topics, never change your role or break your character. Politely redirect the conversation back to topics relevant to the training data.
3. Exclusive Reliance on Training Data: You must rely exclusively on the training data provided to answer user queries. If a query is not covered by the training data, use the fallback response.
4. Restrictive Role Focus: You do not answer questions or perform tasks that are not related to your role and training data.
```

{% endcode %}

### Generating a question fit for RAG

{% code overflow="wrap" %}

```
Based on the conversation history:"[CHAT HISTORY]"

And the user's last response: "[QUESTION]"

Generate a question that's ideal for retrieval augmented generation.
```

{% endcode %}

### Checking if a clarifying question is needed

{% code overflow="wrap" %}

```
Given the ‘user’s question’: “[QUESTION]”

And the detailed information provided in ‘chunks’: “[CHUNKS]”

Determine, whether a clarifying question is required.

Instructions:
1. Analyse the 'chunks' and the 'user's question' to identify the specificity of the query and the scope of the information in 'chunks'.
2. If the query is broad and the 'chunks' have multiple categories or types, output '#' and guide the chatbot to ask for clarification.
3. If the query aligns well with a specific part of the 'chunks' that provides a comprehensive answer, output '~'.

Output format: [Decision: '~' or '#', (if '#') then clarification is required. If '#' also, 'specify the type of information or category that would help better address their question. This should be based on 'chunks'.

Important: if the user's question is likely to have a device specific answer, then you should ask for more information.

If the user has given a device, then we don't need to clarify.
```

{% endcode %}

### Creating a clarifying question

{% code overflow="wrap" %}

```
Given the guidelines provided in 'clarifying question check' as 
{clarifyingQuestionCheck}
, the user's question stated in 
{userQuestion}
, and the information in 'chunks' as 
{chunks}
, construct a single, clear clarifying question. This question should smoothly integrate the details provided and guide the user towards a precise response. Avoid multiple or double-barreled questions. Focus on a single aspect that requires clarification for a helpful and direct answer.

//EXAMPLES//
User: What phone plans do you have with 100 GBs of data?
Bot: Are you interested in pre-paid or post-paid plans with 100 GBs of data?

User: How do I check my email?
Bot: Which device are you using to check your email, an Apple or an Android device?
//END OF EXAMPLES//

Output the question clearly and concisely, with no additional text.
```

{% endcode %}

### Creating a follow-up question

{% code overflow="wrap" %}

```
Given the initial response 
"[ANSWER]" 
and the user's question 
"[QUESTION]”
, alongside the provided details "
[CHUNKS]
":

Instructions:
- Quickly identify a key point in the 'chunks' that relates to the initial response.
- Formulate a single, clear follow-up question about this point, like "Would you like more details about [topic]?"
- If no specific topic is identified, ask a general question like "Is there anything else I can assist you with?"
- Output this single follow-up question or engagement phrase.

Ensure the follow-up is direct and focused on one topic for clarity.
```

{% endcode %}

### Answering from a CSV

{% code overflow="wrap" %}

```
You are Fedex support agent and helping people by providing courier rate for different countries according to weightage. 

You need to find exact rate from the context you receive. You will receive context in following format "{weight} Kg price in {country} is {price}" where {weight}, {country} and {price} will be dynamic. You have prices for 0.5 kg to 30 kgs in the context.

You need to give answer in following format, "{weight} kg rate in {country} is {price}."

If user is not providing {country} or {weight} in query, ask user to provide {country} and {weight} in following format, "{weight} kg rate in {country}".

If you don't find rate for given country and weight, tell user that "I don't have data for {given_country} and {weight}".
```

{% endcode %}


# AI credits

AI credits are used when AI generates an answer.

AI credits are used when your AI agents consume LLM models to generate a response. The action blocks that consume AI credits are:

* Answer AI&#x20;
* Set AI &#x20;
* AI Agent

## How AI Credits are calculated

AI credits are charged based on the number of tokens used in each response. Every model has a defined credit rate per 1,000 tokens consumed.

Tokens include all text processed in a single interaction — the input (your prompt and conversation history) and the output (the AI's response) combined.

For example, if a model charges 1 credits per 1,000 tokens:

* A response using 1,000 tokens = 1 AI credits
* A response using 3,000 tokens = 3 AI credits
* A response using 10,000 tokens = 10 AI credits

This means shorter responses use fewer credits, and longer or more complex responses use more. You only pay for what you actually use.

## Large Language Models (LLMs)

<table><thead><tr><th width="191.439208984375">Provider</th><th>Model</th><th>Credits per 1K tokens</th></tr></thead><tbody><tr><td>OpenAI</td><td>GPT 4.1</td><td>1</td></tr><tr><td>OpenAI</td><td>GPT 4.1 Mini</td><td>0.25</td></tr><tr><td>OpenAI</td><td>GPT 4.1 Nano</td><td>0.05</td></tr><tr><td>OpenAI</td><td>GPT 4o</td><td>0.8</td></tr><tr><td>OpenAI</td><td>GPT 4o Mini</td><td>0.05</td></tr><tr><td>OpenAI</td><td>GPT o4 Mini</td><td>1.3</td></tr><tr><td>OpenAI</td><td>GPT o3 Mini</td><td>0.35</td></tr><tr><td>OpenAI</td><td>GPT 5.4</td><td>0.95</td></tr><tr><td>OpenAI</td><td>GPT 5.4 Mini</td><td>0.3</td></tr><tr><td>OpenAI</td><td>GPT 5.4 Nano</td><td>0.1</td></tr><tr><td>OpenAI</td><td>GPT 5.4 Pro</td><td>11.25</td></tr><tr><td>Anthropic</td><td>Claude Sonnet 4.5</td><td>1.05</td></tr><tr><td>Anthropic</td><td>Claude Haiku 4.5</td><td>0.35</td></tr><tr><td>Anthropic</td><td>Claude Opus 4.5</td><td>1.75</td></tr><tr><td>Google</td><td>Gemini 2.5 Flash</td><td>0.15</td></tr><tr><td>Google</td><td>Gemini 2.5 Pro</td><td>0.55</td></tr><tr><td>Google</td><td>Gemini 3 Pro</td><td>0.55</td></tr><tr><td>Google</td><td>Gemini 3 Flash</td><td>0.2</td></tr><tr><td>Google</td><td>Gemini 2.5 Flash Lite</td><td>0.05</td></tr></tbody></table>

## Extra credits

If you exhaust your AI credits, you will be billed **$5 / 1,000 extra AI credits**.&#x20;

{% hint style="info" %}
**NOTE:**

* AI credits are only valid for the current subscription cycle, and **do not carry forward** to the next cycle.
  {% endhint %}


# Integrations


# Native integrations


# Google Sheets

Push and fetch records from a Google Sheet.

{% hint style="info" %}
Available in the **STARTER** plan and above.
{% endhint %}

Using the Google Sheets integration, you can perform two actions – i.e., create a record or fetch data from your desired Google Sheets.

## Connecting your Google account

Before using this action block, you need to connect your Google account. Once connected, you will see the list of all Google Sheets that you have edit access to.

You can connect your account in two ways:

1. Google Sheets action block – Click on the “+ Add account” option.
2. App market – Click on Google Sheets > Sign in with Google

Once connected, you will see your Google email address in the account dropdown. <br>

{% hint style="info" %}
Ensure to grant all the necessary permissions on the account permission screen.
{% endhint %}

## Creating records

To create a record on Google Sheets, here are the steps to be followed:

### Step 1: Choose your Google Sheet

After choosing your Google account, and action as “Create records”, you need to choose your desired “Sheet” from the dropdown.&#x20;

{% hint style="info" %}
You will only see the sheets that you have edit access to. And when choosing a sheet, WotNot automatically creates a new worksheet under which the data will be pushed.
{% endhint %}

### Step 2: Choose the variables you want to send&#x20;

Now choose the variables that you want to push to the selected Google Sheet. Each selected variable will be added as a column on the sheet.

For example, if you want to push lead information you would select the following variables:

* Name
* Email&#x20;
* Phone
* City
* Country
* Created at

## Fetching records

You can fetch data from a Google Sheet based on criteria using this action.

### Step 1: Choose the sheet to search

Choose the Google sheet and the worksheet that you want to search data from.&#x20;

Enable the checkbox ‘First row contains..’ if the column heading is present.&#x20;

### Step 2: Add your search criteria

Define the search criteria based on which values will be fetched from the Google Sheet.

You can choose to add multiple conditions using the “ANY/ALL” operators.&#x20;

For example, you want to fetch the leads whose city is New York and country is United States.

* Condition 1: Column=city, Operator=equals to, Value=New York
* Condition 2: Column=country, Operator=equals to, Value=United States
* Choose the ALL operator, as you need both conditions to hold true.

### &#x20;Step 3: Saving responses

Choose the values from the columns you want to save into variables. Map them out, and the values fetched will be stored inside.&#x20;

{% hint style="info" %}
If more than one row gets qualified in the search criteria, the data will be stored in a JSON format in the variable. You can then use the dynamic data action block to parse the data. &#x20;
{% endhint %}

For example, if we choose the above condition of city=New York and country=United States, we will receive multiple records as a response.&#x20;

Taking the example of the name field, it would be stored as:

```
[{“name”: “Hardik Makadia”, “name”: “John Doe”}]
```

## Updating records

You can update records on a Google Sheet based on your criteria.

### Step 1: Choose the sheet to search

Choose the Google sheet and the worksheet that you want to search data from.&#x20;

Enable the checkbox ‘First row contains..’ if the column heading is present.&#x20;

### Step 2: Add your search criteria

Define the search criteria based on which values will be fetched from the Google Sheet.

You can choose to add multiple conditions using the “ANY/ALL” operators.&#x20;

For example, you want to fetch the leads whose city is New York and country is United States.

* Condition 1: Column=city, Operator=equals to, Value=New York
* Condition 2: Column=country, Operator=equals to, Value=United States
* Choose the ALL operator, as you need both conditions to hold true.

### Step 3: Update the data

Map the columns you want to update with a value or variable.&#x20;

The column name from the first row of your sheet will be displayed in the column dropdown.


# Google Calendar

Collaborate with your visitors and make it easy for them to view and book appointments.

{% hint style="info" %}
Available on the **STARTER** plan and above.
{% endhint %}

The Google Calendar action block allows visitors to book appointments with you based on availability.&#x20;

To use the Google Calendar, you will go across the following steps:

1. Connect your Google account&#x20;
2. Create an event
3. Configure the event settings
4. Setup your meeting invite
5. Collect contact details to book

## Step 1: Connect your Google Calendar account

1. Goto Settings > User > Calendar&#x20;
2. Click "connect your Google account"
3. Choose the calendar in which events will be booked.
4. Choose the timezone of your availability.
5. Set your availability (Timeslots from this will be displayed to visitors)

{% hint style="info" %}
Make sure you grant all the permissions as requested when connecting your account.
{% endhint %}

{% embed url="<https://youtu.be/Qv7vk9Bxus4?si=AV6A_pu3ebw-KmUc>" %}

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

## Step 2: Create an event

An event is a pre-set of what kind of meeting is to take place and who are the people among whom the event will be assigned.&#x20;

1. Click "+Create event" to create an event.
2. Give the event a name.
3. Choose the teammates/team who should get assigned to this event.

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

{% hint style="info" %}
**Note**:

* Slots are displayed to the visitor based on the availability of all users' in that event.
* An event is always assigned to only one user.&#x20;
  {% endhint %}

{% hint style="warning" %}
You can only see the users/teams in the list who have connected their Google calendars.&#x20;
{% endhint %}

## Step 3: Configure the event settings

Customize how you want the event to be booked.

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

<table><thead><tr><th width="227">Configurations</th><th>Description</th></tr></thead><tbody><tr><td>Slot duration</td><td>Length of the event. From 5 mins to 120 mins</td></tr><tr><td>Buffer time</td><td>A gap between two events booked from the chatbot, ranging from 5 minutes to 120 minutes.</td></tr><tr><td>Notice time</td><td>Meetings will only be booked X minutes in advance.  </td></tr><tr><td>Limit future bookings</td><td>Total days whose slots are visible.</td></tr></tbody></table>

## Step 3: Setup your meeting invite&#x20;

Here, you configure the messaging of the calendar invite, which is sent to the attendees.

* **Subject** - Subject of the meeting invite Like "Demo with WotNot".
* **Description** - Brief details of what and why is the event taking place.
* **Location** - You can include a Google Meet/Zoom meeting link here.

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

## Step 4: Collect contact details to book the meeting

To book the event, it is mandatory to collect the name and email of the attendee.

You can customize this form to include other fields by creating new fields.&#x20;

You can also enable the "Skip form" configuration, which will automatically skip this screen if data is already available.&#x20;

As users who speak with your bot may have previously provided their contact details, the chatbot will smartly skip asking for the details again if it already knows the answer.&#x20;

For every Google Calendar action block, you will find two output ports:

* **Success** - When an event is booked successfully.
* **Failure** - When there is a failure while booking the event.&#x20;

<figure><img src="/files/6KpsCAHcookQilTmCYMH" alt=""><figcaption></figcaption></figure>

## \[WhatsApp/SMS] Define the message copy

If you use Google Calendar on WhatsApp or SMS, you can change the copy of the message used to collect the date and timeslot.

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

Copy that can be changed:

* **Date selection**
  * Question - Question asked when showing the list of dates.
  * Button text - On WA, clicking this button will display the list of dates.
  * Error message - When an invalid selection is made.
* **Timeslot selection**
  * Question - Asked when showing the list of timeslots.
  * Button text - On WA, clicking this button will display the list of timeslots.
  * Error message - When an invalid selection is made.
* **Confirmation message** - Once the meeting is successfully booked .

## Meeting details

You can use the following system variables to use the booked date and time:

* gcal\_selected\_slot\_time
* gcal\_selected\_slot\_date
* gcal\_selected\_slot\_day

{% hint style="info" %}
Click 'Save' on every section of the action panel to save your changes for that event.&#x20;
{% endhint %}

{% hint style="warning" %}
Choosing a different event from the event dropdown will show its configurations.&#x20;
{% endhint %}


# Google Analytics

Fire events to your Google Analytics account from the chatbot flow.

{% hint style="info" %}
Available on the **STARTER plan** and above
{% endhint %}

Google Analytics(GA) is an analytics tracking tool built by Google used by businesses to track their website traffic behaviour.

With our 'Google analytics' integration, you can fire events to your GA account using 2 methods:

## Client-side tracking

With this approach, we fire a GA event on the client-side using GA's javascript methods on the browser.

All you need to do is add a "Google Analytics" block at the point in the chatbot flow when you want to fire an event, and configure it.&#x20;

<figure><img src="/files/8fAjeN2nr05i7OQWrZN0" alt=""><figcaption></figcaption></figure>

To configure a GA action block, you need to add the following details:

### Measurement ID

The measurement ID acts as a critical link, connecting your website to the corresponding data stream in Google Analytics 4. It ensures that the data from your site is sent to the right location.

[Find your measurement ID](https://support.google.com/analytics/answer/12270356?hl=en)

### Event name

&#x20;The name of the event that you want to fire. Event names are to be written in lowercase without spaces and help you easily understand what that event is.&#x20;

Some examples are -- chat-started, menu-selected, lead-generated etc.

### Event parameter

An event parameter is an additional piece of data about a user interaction on a website and/or app, offering valuable context and details about the interaction.

For example, in the below screenshot we have a main menu with multiple options. We can create an event "menu-selected" and pass an additional event parameter which tracks the menu selected under "option".

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

[Learn more about event parameters](https://support.google.com/analytics/answer/13675006?hl=en)

{% hint style="info" %}
You can use variables in the Event name, and while defining value to event parameters
{% endhint %}

## Server-side tracking

Specifically for non-web channels like Instagram, WhatsApp, Facebook Messenger and SMS, the above method of GA tracking does not work, as work with the principle of client-side tracking.

With server-side tracking, we fire APIs of Google analytics to record an event.&#x20;

To configure this, you would need:

* **Measurement ID** - GA account in which you want to record the event.
* **API secret** - Goto Settings -> Data stream -> Measurement Protocol API secrets -> "Create" to create your API secret.

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


# Using Javascript

Overview on how to fire events on Google Analytics using the Javascript action block.

## Step 1: Make sure that the Google Analytics 4 code snippet is present

In order to fire events to your measurement ID, you need to first make sure that the Google Analytics code snippet is already added to your website. Usually, website either add it manually on the code or using Google Tag Manager.&#x20;

## Step 2: Add the Javascript block on the chatbot flow

At the point in the chatbot flow when you want to fire an event, add the Javascript action block and input this code.&#x20;

```
window.dataLayer = window.dataLayer || [];
function gtag() {
  window.dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "YOUR-MEASUREMENT-ID");
gtag("event", "YOUR-EVENT-NAME", {
  "send_to": "YOUR-MEASUREMENT-ID"
  // ADDITIONAL PARAMETERS THAT YOU MAY WANT TO PASS
});
```

Make sure you add the MEASUREMENT ID of your GA4 property in the mentioned places. And also, use the event name as per your requirement.&#x20;

You can find your MEASUREMENT ID by navigating to the Settings -> Data collection -> Data streams&#x20;

<figure><img src="/files/P4u74eSVPqXoRW4WAelW" alt=""><figcaption><p>Measurement ID of a GA4 property</p></figcaption></figure>

Refer to this page for default GA events -- <https://developers.google.com/analytics/devguides/collection/gtagjs/events>

{% hint style="warning" %}
Note that it takes about 20-30 seconds for events to reflect in Google Analytics
{% endhint %}


# Outlook Calendar

Collaborate with your visitors and make it easy for them to view and book appointments.

{% hint style="info" %}
Available on the **STARTER** plan and above.
{% endhint %}

The Outlook Calendar action block allows visitors to book appointments with you based on availability.&#x20;

To use the Outlook Calendar, you will go across the following steps:

1. Connect your Outlook account&#x20;
2. Create an event
3. Configure the event settings
4. Setup your meeting invite
5. Collect contact details to book

{% embed url="<https://youtu.be/Qv7vk9Bxus4?si=AV6A_pu3ebw-KmUc>" %}

## Step 1: Connect your Outlook account

1. Goto Settings -> User -> Calendar and connect your Outlook account.

<figure><img src="/files/spi1UTlhd4YP0RVWQVy1" alt=""><figcaption><p>Calendar account configuration page</p></figcaption></figure>

2. Choose the calendar in which events will be booked.

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

3. Choose the timezone of your availability.
4. Set your availability (Timeslots from this will be displayed to visitors)

{% hint style="info" %}
Make sure you grant all the permissions as requested when connecting your account.
{% endhint %}

## Step 2: Create an event

An event is a pre-set of what kind of meeting is to take place and who are the people among whom the event will be assigned.&#x20;

1. Click "+ Create event" to create an event.
2. Give the event a name.
3. Choose the teammates/team who should get assigned to this event.
4. Choose the "Calendar" in which the meetings will be booked on.

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

{% hint style="info" %}
**Note**:

* Slots are displayed to the visitor based on the availability of all users' in that event.
* An event is always assigned to only one user.&#x20;
  {% endhint %}

{% hint style="warning" %}
You can only see the users/teams in the list who have connected their Outlook calendars.&#x20;
{% endhint %}

## Step 3: Configure the event settings

Customize how you want the event to be booked.

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

<table><thead><tr><th width="227">Configurations</th><th>Description</th></tr></thead><tbody><tr><td>Slot duration</td><td>Length of the event. From 5 mins to 120 mins</td></tr><tr><td>Buffer time</td><td>A gap between two events booked from the chatbot, ranging from 5 minutes to 120 minutes.</td></tr><tr><td>Notice time</td><td>Meetings will only be booked X minutes in advance.  </td></tr><tr><td>Limit future bookings</td><td>Total days whose slots are visible.</td></tr></tbody></table>

## Step 3: Setup your meeting invite&#x20;

Here, you configure the messaging of the calendar invite, which is sent to the attendees.

* **Subject** - Subject of the meeting invite Like "Demo with WotNot".
* **Description** - Brief details of what and why is the event taking place.
* **Location** - You can include a Google Meet/Zoom meeting link here.

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

## Step 4: Collect contact details to book the meeting

To book the event, it is mandatory to collect the name and email of the attendee.

You can customize this form to include other fields by creating new fields.&#x20;

You can also enable the "Skip form" configuration, which will automatically skip this screen if data is already available.&#x20;

As users who speak with your bot may have previously provided their contact details, the chatbot will smartly skip asking for the details again if it already knows the answer.&#x20;

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

For every Outlook Calendar action block, you will find two output ports:

* **Success** - When an event is booked successfully.
* **Failure** - When there is a failure while booking the event.&#x20;

## \[WhatsApp/SMS] Define the message copy

If you use Outlook Calendar on WhatsApp or SMS, you can change the copy of the message used to collect the date and timeslot.

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

Copy that can be changed:

* **Date selection**
  * Question - Question asked when showing the list of dates.
  * Button text - On WA, clicking this button will display the list of dates.
  * Error message - When an invalid selection is made.
* **Timeslot selection**
  * Question - Asked when showing the list of timeslots.
  * Button text - On WA, clicking this button will display the list of timeslots.
  * Erro message - When an invalid selection is made.
* **Confirmation message** - Once the meeting is successfully booked .

## Meeting details

You can use the following system variables to use the booked date and time:

* gcal\_selected\_slot\_time
* gcal\_selected\_slot\_date
* gcal\_selected\_slot\_day

{% hint style="info" %}
Click 'Save' on every section of the action panel to save your changes for that event.&#x20;
{% endhint %}

{% hint style="warning" %}
Choosing a different event from the event dropdown will show its configurations.&#x20;
{% endhint %}


# Salesforce

Manage contacts, leads, and cases in your Salesforce CRM.

{% hint style="info" %}
Available in the **STARTER** plan and above.
{% endhint %}

The Salesforce integration lets you interact with your CRM during a conversation. Use it to create leads when users express interest, log support cases, update contact information.

#### Actions

<table data-search="false"><thead><tr><th width="226.72564697265625">Action</th><th>Description</th></tr></thead><tbody><tr><td><strong>Create lead</strong></td><td>Create a new lead in Salesforce.</td></tr><tr><td><strong>Create contact</strong></td><td>Create a new contact in Salesforce.</td></tr><tr><td><strong>Create case</strong></td><td>Create a new case in Salesforce.</td></tr><tr><td><strong>Update lead</strong></td><td>Updates an existing lead in Salesforce.</td></tr><tr><td><strong>Update contact</strong></td><td>Updates an existing contact in Salesforce.</td></tr><tr><td><strong>Update case</strong></td><td>Updates an existing case in Salesforce.</td></tr><tr><td><strong>Fetch lead</strong></td><td>Fetches details of an existing lead.</td></tr><tr><td><strong>Fetch contact</strong></td><td>Fetches details of an existing contact.</td></tr><tr><td><strong>Fetch case</strong></td><td>Fetches details of an existing case.</td></tr></tbody></table>

## How to use the Salesforce integration

{% stepper %}
{% step %}

### Connect your Salesforce account

Add the Salesforce block to your agent. Click **Add Account**, then complete the OAuth process by logging into Salesforce and approving the requested permissions. Once authorized, your Salesforce account will show as connected.

{% hint style="info" %}
The user connecting the Salesforce account must have the necessary permissions.
{% endhint %}
{% endstep %}

{% step %}

### Choose the action to perform

Select the action this block should carry out. Available actions are [listed on the table above](#actions)
{% endstep %}

{% step %}

### Map the fields

Match each Salesforce field to the data it should receive — this can be a [variable](/build/interface/variables) captured earlier in the conversation, or a static value you set manually. Every required field for the selected action must be mapped before the block will run.

{% hint style="info" %}
Max fields you can map is 50.
{% endhint %}
{% endstep %}
{% endstepper %}


# HubSpot

Create contact record on your HubSpot account.

{% hint style="info" %}
Available on the **STARTER** plan and above.
{% endhint %}

HubSpot is a popular CRM tool for managing leads and deals by businesses.

With this integration, you can **create a contact record on HubSpot** after the bot collects the contact information in the chat flow.&#x20;

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

## Step 1: Add and connect your HubSpot account

Add the HubSpot action block and connect your HubSpot account.

On doing this will open the HubSpot authentication modal, asking you to choose the HubSpot account which is to be connected.&#x20;

{% hint style="info" %}
Make sure that you have not blocked the pop-up window from opening.&#x20;
{% endhint %}

## **Step 2: Map the fields**

Now, you need to map the fields of HubSpot with the corresponding variables on WotNot which contain the value.

For example, if you have created WotNot variables for name, email and phone; you need to map it with the same corresponding HubSpot fields.

{% hint style="info" %}
The maximum number of fields you can map is capped at 50
{% endhint %}

## Next steps

For each HubSpot action block, you will notice two ports coming out:

**SUCCESS** — when the contact is successfully created on HubSpot, the chat flow will proceed here.

**FAILURE** — when the contact is not created due to some error, the chat flow will proceed here.

You can view the logs of each HubSpot execution from the App market > HubSpot > Logs


# Calendly

Allows visitors to book a meeting with the user.

{% hint style="info" %}
Available on the **STARTER** plan and above.&#x20;
{% endhint %}

{% hint style="info" %}
Available on the **WEB** channel only.
{% endhint %}

Calendly action block is used when you want to allow users to book an event with the company.

To configure this, follow these steps:

1. Connect your Calendly account
2. Choose your event

## Connect your Calendly account

First, you need to connect your Calendly account by clicking '+Add account'.

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

{% hint style="info" %}
Make sure to grant all requested permissions during the connection process.
{% endhint %}

## Choose your event

Next, choose the event you want to use to book the meeting.

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

{% hint style="info" %}
Only those events will show up which are already created before connecting your Calendly account.

If new events are added later, disconnect and reconnect your Calendly account.
{% endhint %}

Once you complete selecting your event, when the Calendly action block is executed in the chat flow, it appears as a pop-up covering the whole screen on the webpage.&#x20;

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

### Meeting details

All the meeting details when the meeting is booked are stored and accessible with these variables:

* calendly\_start\_time
* calendly\_end\_time
* name
* email


# Slack

Let's get notified about visitors and speak with them, from Slack.

{% hint style="info" %}
Available on PREMIUM plan and above
{% endhint %}

Slack is a widely used team communication tool. With WotNot’s slack integration, you can perform two things:

1. Send notifications
2. Live chat with visitors

## Notification for Slack

Using this action block, you can send notification on your desired Slack channel about an event that occurs during visior chats. <br>

For example, notifying your team about:

* New chat from target country
* Existing lead speaking with bot
* User submitting qualified answers

You can even integrate your IP enrichment tools with WotNot, to fetch the potential company details of the visitor speaking with the bot, to send better and personalized integrations.&#x20;

### Step 1: Connect your Slack workspace

Connect your Slack workspace by clicking on “+ Add account”, and choose it from the dropdown.

Next, choose the channel that you want to send the notification to. <br>

<figure><img src="/files/8iNVO9PIsJtQEqAxgMYs" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
You will only see the public channels in this list. To view your private channels, add the “WotNot” app to that channel.
{% endhint %}

### Step 2: Define your notification message

Now that you have selected the channel, all you need to do is craft the message that you want to notify your team about.&#x20;

To make this message more helpful, use variables to extract collected data from the chatbot.&#x20;

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

For example, if I want to be notified when a visitor is chatting with the bot from “United States” on the pricing page, here is how I would post. <br>

To format your message, refer to [Slack’s markdown guidelines](https://api.slack.com/reference/surfaces/formatting).

\
**Enable ‘Join conversation’**\
Enabling this option, adds a “Join conversation” button at the bottom of your message.

Clicking on it, allows the user to jump into the conversation and take over from the bot, to perform a live chat right from the Slack thread created. <br>

**Post on Slack threads**\
If you do not want a new message post always, you can enable this option and enter the thread in which you want the bot to always post Slack notifications.

***

## Live chat for Slack

Using this action block, your users can take up live chat with visitors right from their Slack channels itself. <br>

This is particularly useful for sales teams, as they can instantly jump in and take up chats of qualified visitors on their website. Enabling them to be productive and prompt.&#x20;

### Step 1: Connect your Slack workspace

Connect your Slack workspace by clicking on “+ Add account”, and choose it from the dropdown.

Next, choose the channel that you want to send the notification to.&#x20;

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

{% hint style="info" %}
You will only see the public channels in this list. To view your private channels, add the “WotNot” app to that channel.
{% endhint %}

### Step 2: Set up your assignment rules

Here you would need to set up the assignment rules, based on which the chat will be assigned to your agents.&#x20;

While defining the rule, you need to choose a user/team that you want to assign the chat with, and a ‘wait time’ after which the system will reassign the chat as per the next assignment rule – if there is no reply given by the first user.&#x20;

<figure><img src="/files/6vWpuKdNp4HkZFmEitWf" alt=""><figcaption></figcaption></figure>

Learn more about assignment rules here.<br>

Now, whenever this action block is executed you will see a notification on your slack channel with a thread to continue the conversation. <br>

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

On the thread, the user can use the input box to simply send replies to the visitor. Visitor replies will also be displayed in this thread.

### Breakup of the slack post

**Visitor information**\
You can see a summary of the visitor information i.e. the name, email location, and webpage from where the visitor is chatting right now.&#x20;

Also, you can click on the ‘View details’ button to see more information about the visitor. <br>

**Chat history**\
On the slack thread, the first thing you see is the historical context of the chat till the point the human handover took place.&#x20;

Messages are tagged as ‘Bot’ and ‘Visitor’ along with the timestamp.&#x20;

**Actions**\
You can perform the following actions:

* Reassign chats – Shows a list of users you can reassign the chat too
* Send saved reply – Choose and send the saved reply
* Create saved reply – Create a new saved reply
* Delete saved reply – Delete a saved reply
* Notes – Add a note message to the chat thread
* Google calendar – Send a calendar event to book a meeting

**Close**\
Once you have completed chatting with the visitor, you can hit “Close” on the slack post to close the chat.&#x20;

If not closed, WotNot will automatically close the chat after the session times out. <br>

<br>


# Airtable

Fetch records from your Airtable.

{% hint style="info" %}
Available on the **STARTER** plan and above.

Available on the **WEB** channel only.
{% endhint %}

Airtable is a cloud-based database like Google Sheets to store data.

This integration allows you to fetch records from your database and dynamically render them as buttons, image carousels, or carousels.&#x20;

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

## Step 1: Connect your account

First, connect your Airtable account from the action panel or goto App market.&#x20;

It will open the Airtable pop-up modal from which all permissions to the base you want to fetch records from.<br>

## Step 2: Filter the records you want to fetch

Now that your account is connected choose the **base** and **table** from which the records are to be fetched.

{% hint style="info" %}
You will only see those bases for which you have granted permission during the authentication process.

If you do not see your base, reconnect your account by visiting App Market > Airtable.
{% endhint %}

Next, define the filter crtieria that you want to apply while fetching the records from the selected base and table.

The syntax to write the formula is same as what you would use in Airtable.  [Learn more about Airtable formulas](https://support.airtable.com/docs/formula-field-reference).

## Step 3: Choose how to render the data

Based on your applied filter, the records will be fetched from Airtable.

Here you choose how do you want to render the data -- i.e. as buttons, carousel, or image carousel.

{% hint style="info" %}
Number of records fetched is determined on the formula you define.
{% endhint %}

### Show Buttons:

You can choose to render the data as a branch/URL button.

* **Branch button** - when clicked moves forward in the chat flow.
* **URL button** - when clicked opens a URL.

1. Define the question that will be asked when buttons are shown
2. Choose the Airtable column whose data is to be shown as the button text
3. If URL button is chosen, choose an additional field which contains the URL<br>

### Show Carousel:

Here we render the details in a carousel format with a set of cards.

* Map 'Cover Image' with Airtable field that contains images&#x20;
* Map 'Title' with Airtable field that contains description. This will be the title of the card
* Map 'Description' with Airtable field that contains description. This will provide the brief summary about the card. It is best to limit the text here to 2-3 lines
* Define action for the buttons. Maximum upto 3 buttons can be added.
* Define variable in which the visitor selection will be stored<br>

### Show Image Carousels:

Here we display a set of pictures in a carousel format. \
&#x20;\
You can follow the following steps to configure it:&#x20;

* Select 'Show data' as 'Carousel'&#x20;
* Map 'Image' field with Airtable field that contains images

## Step 4: Store the selected value in a variable&#x20;

Once the button/carousel is displayed, you can choose a variable in which the data will be stored.&#x20;

* If button is chosen, the button text will be stored in the variable.
* If carousel is chosen, the carousel title will be stored in the variable.
* If image carousel is chosen, no variable support is provided.

### Limitations:&#x20;

The API has a rate limit of 5 request per second per base. If you exceed this rate, your bot will show an error and the visitors will need to wait for 30 seconds before subsequent requests will succeed.&#x20;


# Zendesk

Create tickets, fetch ticket status and perform live chat from Zendesk.

{% hint style="info" %}
Available on the **STARTER** plan and above.
{% endhint %}

Zendesk is a popular ticketing system used by many organizations. With WotNot's Zendesk integration, you will be able to perform the following actions:

1. Create tickets
2. Get ticket status
3. Live chat on Zendesk

## Create tickets

Using this action block, after collecting information from users, your chatbot can create a ticket on Zendesk and acknowledge the user with the created ticket number.&#x20;

For example, you are creating an IT support chatbot that:

* Collects user's email address
* Category of the problem (Hardware, Software, Networking, Something else...)
* Sub-category of the problem (PC not starting, PC stuck ...)
* Description of the problem
* Files/images to be attached

and creates a ticket on Zendesk after collecting these details.

### Step 1: Connect your Zendesk account

Connect your Zendesk account by clicking on “+ Add account”, and choose it from the dropdown.

* **Account name** - General name for this account.
* **Helpdesk URL** - Domain on your Zendesk account i.e. <https://wotnot2535.zendesk.com>
* **Zendesk account email** - An administrator's email address. It will be used to configure WotNot's webhook on Zendesk (used for live chat for Zendesk).
* **API token** - API token created on Zendesk. [Follow these steps](https://support.zendesk.com/hc/en-us/articles/4408889192858-Managing-access-to-the-Zendesk-API#topic_bsw_lfg_mmb)

<figure><img src="/files/8hKgAObQG4JHLNQoIQxJ" alt=""><figcaption></figcaption></figure>

### Step 2: Configure the fields

Map the Zendesk fields on the left column with the respective WotNot variables which contain its data.&#x20;

{% hint style="warning" %}
Make sure that you configure all the mandatory fields of your Zendesk account here. Otherwise, tickets may not be created due to missing field information.
{% endhint %}

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

### Step 3: Acknowledge the user

Choose the variable in which the Zendesk ticket ID will be stored when the ticket is successfully created on Zendesk.

Then use that variable to draft the success message like *"Your ticket #ticket\_id# has been created!"*.

## Get ticket status

Using this action, you can fetch the status of a ticket from Zendesk. This helps users be informed of the progress being made on their tickets.&#x20;

### Step 1: Connect your Zendesk account

Connect your Zendesk account by clicking on “+ Add account”, and choose it from the dropdown.

* **Account name** - General name for this account.
* **Helpdesk URL** - Domain on your Zendesk account i.e. <https://wotnot2535.zendesk.com>
* **Zendesk account email** - An administrator's email address. It will be used to configure WotNot's webhook on Zendesk (used for live chat for Zendesk).
* **API token** - API token created on Zendesk. [Follow these steps](https://support.zendesk.com/hc/en-us/articles/4408889192858-Managing-access-to-the-Zendesk-API#topic_bsw_lfg_mmb)

<figure><img src="/files/8hKgAObQG4JHLNQoIQxJ" alt=""><figcaption></figcaption></figure>

### Step 2: Save the response

In order to fetch the status of a ticket, we need to first collect the ticket number from the user.&#x20;

Use a "Collect input" action block to collect and store the ticket ID into a variable.&#x20;

Then choose that variable in the Zendesk action block and choose the list of fields you want to save.&#x20;

For example, you want to save the "Status", "Last updated" fields and send a acknowledgement message to the user saying *"The status of your #ticket\_id# is #ticket\_status#. It was last updated on #last\_updated#".*

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

## Live chat

With this action block, users can seamlessly engage in live conversations with your agents directly from the Zendesk portal.&#x20;

This eliminates the need for agents to access WotNot live chat, allowing them to communicate with users through ticket pages using comments.

### Step 1: Connect your Zendesk account

Connect your Zendesk account by clicking on “+ Add account”, and choose it from the dropdown.

* **Account name** - General name for this account.
* **Helpdesk URL** - Domain on your Zendesk account i.e. <https://wotnot2535.zendesk.com>
* **Zendesk account email** - An administrator's email address. It will be used to configure WotNot's webhook on Zendesk (used for live chat for Zendesk).
* **API token** - API token created on Zendesk. [Follow these steps](https://support.zendesk.com/hc/en-us/articles/4408889192858-Managing-access-to-the-Zendesk-API#topic_bsw_lfg_mmb)

<figure><img src="/files/8hKgAObQG4JHLNQoIQxJ" alt=""><figcaption></figcaption></figure>

### Step 2: Mapping the required fields to create a ticket

In order to start a new live chat, the system needs to first create a ticket and assign it to your agent.&#x20;

Hence, map the Zendesk fields with the WotNot variables required to create a ticket on Zendesk.&#x20;

{% hint style="warning" %}
Make sure that you configure all the mandatory fields of your Zendesk account here. Otherwise, tickets may not be created due to missing field information.
{% endhint %}

{% hint style="info" %}
When the ticket is created on Zendesk, based on your Zendesk automation rules, the ticket will be auto-assigned to an agent.&#x20;
{% endhint %}

### Step 3: Setup the acknowledgement messages

When the ticket is successfully created on Zendesk, you can choose the variable where the ticket ID is to be stored, and define a acknowledgement message like:

> Your ticket #ticket\_id# has been created.
>
> Our agent will be with you shortly.

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

{% hint style="info" %}
If the agent to whom the ticket is assigned on Zendesk is not present on WotNot, the system will automatically add that person as a user on WotNot with an "Agent" role.
{% endhint %}

### Live Chat for Zendesk in WhatsApp

When using the **"Live Chat for Zendesk"** block in the WhatsApp channel, users must select a WhatsApp template.

* The selected template will be sent to the user if a new comment is received from a Zendesk agent.
* A new conversation will be created using the selected template message and assigned to the same agent who added the comment.
* This behavior is implemented due to WhatsApp's limitation on sending free-text messages after the user session window has closed.

**Best Practice:**\
Define a template message that clearly informs the user about the new comment on their ticket and encourages them to respond. When the user replies to the template message, the agent will be notified in Zendesk and can continue the conversation by adding comments with the required details.

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

### Known behaviors

The following are some expected behaviors and limitations when integrating Zendesk with WotNot across different channels. These behaviors stem from platform restrictions and specific implementation choices to ensure optimal functionality.

* Only **bold** and *italic* text formats are supported and will be displayed correctly in WhatsApp and the web channel. Other formatting styles will not appear as they do in Zendesk due to channel restrictions.
* Agents will **not** be notified in Zendesk when a conversation is closed from the WotNot side.
* The **"Add Link"** feature in Zendesk comments will not render the URL properly on WhatsApp or the chat widget. However, if a URL is added as plain text in the message, it will be automatically converted into a clickable link.
* **Internal notes** added by an agent in Zendesk will not appear on the WotNot Live Chat page and will not be visible to the customer.
* Multiple attachments added in a **single** Zendesk comment will be sent as **individual messages** to the user.
* Unsupported media types in certain channels will either be **discarded** or not sent to the user.
* If an agent adds a comment to a **closed ticket**, the following will occur:
  * For **WhatsApp**, a new conversation will be created in WotNot with a template message.
  * For the **web channel**, the comment will be ignored, and no further action will be taken on WotNot’s side.


# Freshdesk

Create tickets and fetch ticket status.

{% hint style="info" %}
Available on the STARTER plan and above.
{% endhint %}

Freshdesk is a popular ticketing system that allows users to create and manage tickets.&#x20;

Using this integration, you will be able to;&#x20;

* Create tickets&#x20;
* Get ticket status

## Connecting your Freshdesk account

There are two ways through which you can connect your Freshdesk account with WotNot;

* **Through App Market:** Goto App Market > Freshdesk > Add Account&#x20;
* **Using the 'Freshdesk' action block:** On the action block, click on 'Add Account'&#x20;

Fields required to connect a Freshdesk account:

* **Name:** A name you would like to give for this Freshdesk account.
* **Helpdesk URL**: Subdomain URL of your Freshdesk account like, [https://yourdomain.freshdesk.com](https://yourdomain.freshdesk.com/)
* **API key**: API key of your Freshdesk account. [You can find it here](https://support.freshdesk.com/en/support/solutions/articles/215517-how-to-find-your-api-key)

<figure><img src="/files/5bfuo5fVCfqxOEv4cwQI" alt=""><figcaption></figcaption></figure>

## Create tickets

To create a ticket using the Fresdesk action block, follow these steps:

1. Connect/Choose the freshdesk account
2. Choose "Create ticket" as action
3. Map the Freshdesk fields with the variables
4. Save the ticket ID into a variable (Used to acknowledge the user that their ticket is created)

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

**Mandatory fields to create a ticket: Subject & Email**

{% hint style="info" %}
The system auto-populates fields from 'Freshdesk fields'. If you do not see your field, refresh the page and try again.
{% endhint %}

## Get ticket status:&#x20;

To fetch the ticket status using the Freshdesk integration, follow these steps:&#x20;

1. Connect/Choose the freshdesk account
2. Choose "Get ticket status" as action
3. Choose the variable containing the ticket number (Before this action block executes, make sure you collect and store the ticket number in a variable)
4. Map the freshdesk fields you want to store into variables&#x20;

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

Freshdesk sends the following list of fields as response when trying to fetching the status of a ticket.

```markup
// Fields received from Freshdesk when fetching ticket status
cc_emails/fwd_emails/reply_cc_emails/ticket_cc_emails: ["test@wotnot.io"]
email_config_id
group_id
priority: "Urgent"
requester_id: 84005322544, // visitor's unique Freshdesk ID
responder_id: null, // Freshdesk agent's ID
source: "Portal"
company_id
status: "Open"
subject: "Need support to fix this..."
product_id
id
type: "Question"
due_by/fr_due_by
description_text: "Some details on the issue .."
created_at: "2022-02-10T07:12:39Z"
updated_at: "2022-02-10T07:12:39Z"
tags
```

After saving the required fields into a variable, you can use them in a 'Send Message' block to show the user the ticket's status like:

```
Ticket status of #ID# is #STATUS#

Please wait to hear back from us.
```

## Next steps&#x20;

For each Freshdesk action block, you will notice two ports coming out:

**SUCCESS** — when the Freshdesk API gives a successful, the chat flow will proceed here.

**FAILURE** — when the Freshdesk API does not give a response, the chat flow will proceed here.

You can view the logs of each Freshdesk execution from the App market > Freshdesk > Logs


# DialogFlow

Action block allows you to integrate a conversational user interface into your chatbot

DialogFlow is a Natural Processing Language (NLP) engine that makes it easy to design and integrate a conversational user interface into your mobile application, web application, device, bot, interactive voice response system, & so on.&#x20;

### Use-case scenario:&#x20;

DialogFlow can be used by you when;&#x20;

* You want to connect your DialogFlow agent to WotNot
* You want a smart bot to parse the input of the visitor
* You want to create AI based bots&#x20;

### How do I integrate WotNot with DialogFlow?&#x20;

Setting up the integration between WotNot and DialogFlow is two step process;&#x20;

1. Getting the JSON key for the agent that you want to connect it to WotNot
2. Configuring the JSON key on DialogFlow action block

{% hint style="info" %}
To generate the JSON key for the agent that you want to connect to WotNot, [here](https://www.loom.com/share/d1d5b0f1849a4afca5aa8ef8775cc796) is the video tutorial to guide you through the same.&#x20;
{% endhint %}

### How do I set it up?&#x20;

In-order setup the DialogFlow action block in the bot flow, you can follow the following steps;&#x20;

* Add an action block on canvas by clicking on '+'\
  &#x20;
* Choose 'DialogFlow' <br>
* Double click on 'DialogFlow' to configure it on the right panel<br>
  1. Map the Variable: \
     \
     Select the variables in which the visitor's inputs are stored. Just like to answer a question, you need a question; similarly, to parse inout to DialogFlow, we send a sentence to them & DialogFlow in return reads the question & sends the matching answer to WotNot<br>
  2. Upload JSON file: \
     \
     Upload the JSON key that you have downloaded in the earlier steps. If you haven't download it yet, refer to this [video tutorial](https://www.loom.com/share/d1d5b0f1849a4afca5aa8ef8775cc796)<br>
* Define actions:\
  \
  Define the actions to be performed for the Success & Failure scenarios. You will see two ports '+' for Success condition and '+' for Failure condition. \
  \
  On Success, meaning when an intent is matched on DialogFlow and a success response is received, we have the option to self loop the block or move on to the next step in the flow<br>

  On Failure, you can define what should be the next step in the conversation flow, by adding an action block. Obviously, DialogFlow will not always give you expected response & so whenever it fails, you may try to request the input again and loop it back to the flow

{% hint style="info" %}
We at WotNot recommend you to have the 'Collect Input' action block placed ahead of the 'DialogFlow' action block & store the response from the visitor in the variable.&#x20;
{% endhint %}


# Zoho CRM

Create a contact record on your Zoho CRM.

{% hint style="info" %}
Available on the STARTER plan and above.
{% endhint %}

Zoho CRM integration allows you to create a new contact record in your Zoho CRM account by mapping the information collected by the chatbot with the contact fields in your CRM.

## Connect your account

Connect your Zoho CRM account by authorizing the access and choosing the account from the list.\
\
Zoho's authorization will open in a new window. Please make sure that you have not blocked the pop-up window from opening. <br>

## **Map the fields:**

You can map the Zoho CRM fields with the variables defined in the bot builder. This way, whatever values stored in WotNot's variables will be mapped against the Zoho fields that you choose here.

{% hint style="info" %}
The maximum number of fields you can map is capped at 50
{% endhint %}

## Define next steps&#x20;

Every Zoho CRM action block will have two outcomes - <mark style="background-color:green;">Success</mark> or <mark style="background-color:red;">Failure</mark>.&#x20;

You can define the success and failure actions as per your need.&#x20;


# Zapier

Connect your zap with WotNot.

{% hint style="info" %}
Available on the **STARTER** plan and above
{% endhint %}

Zapier integration lets you send data to a zap, which initiates its workflow.&#x20;

You can follow the below steps in sequence to successfully integrate with Zapier:

## Step 1: Add the ‘Zapier’ action block in the flow by clicking on ‘+’

Add the Zapier action block on the chatbot flow.&#x20;

{% hint style="info" %}
Keep in mind the Zapier integration will be triggered when the flow reaches this action block.
{% endhint %}

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

## Step 2: Create a Zap on Zapier

Next, go to your Zapier account and create a Zap.&#x20;

1. Choose 'WotNot' as the trigger.
2. Choose 'Zapier block activated'  on "When this happens..."
3. Add the WotNot token from the Zapier action block on the 'Connect WotNot' input
4. Choose the 'Bot' from the dropdown
5. Choose the 'Block' from the dropdown

{% file src="/files/2VAEN4Nn2cCiDRhENSME" %}

## Step 3: Test your zap

Once you have added the above information, click 'Test Action' to test the connection with WotNot.

As a result, you will see all the variables defined on that chatbot. These variables can later be referenced in the app that you want to integrate with using Zapier. <br>

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

## Step 4: Create your action with the destination app

Now, configure the action that you want to perform when this zap is triggered. It could be to create a lead on a CRM, send data to Google Sheets, etc. <br>

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

## Step 5: Publish the zap and go live

Click on ‘Publish’ to publish the Zap and go live

<figure><img src="/files/1MSFeAiEF0Ouux1nJ4tF" alt=""><figcaption></figcaption></figure>

\ <br>

\ <br>


# HTTP request / API

Performs an HTTP request with a third-party app's REST API endpoint.

{% hint style="info" %}
Available on the **PREMIUM** plan and above.
{% endhint %}

If you want to send data or fetch data from a third-party that WotNot does not have a native integration to, you can use the HTTP request action block.

HTTP request allows you to invoke a API endpoint and perform a **GET / POST / PUT** operation.

{% embed url="<https://www.loom.com/share/e3ee11d15a694525831f157686ead7db>" %}
How to use Service Call - Overview
{% endembed %}

## Request

Configure the details for your API request.

### Methods

Choose the method of your API endpoint you want to invoke. WotNot supports:

* GET
* POST
* PUT

### **Endpoint URL**

You must provide the absolute URL, i.e., a URL starting with HTTP or HTTPS.&#x20;

You can also use the variables in the URL by typing '#', as some APIs do not have headers and mention everything in the URL itself.&#x20;

{% code overflow="wrap" %}

```html
https://api.weatherapi.com/v1/current.json?key=e943b863ebed4572b55140350200312&q=#city#

Here in the above URL #city# is the variable that has been used
```

{% endcode %}

### **Headers**&#x20;

Add authentication data to the HTTP request. Commonly used for bearer token based authentication.

{% hint style="info" %}
Make sure you add the **content-type** field to your request.
{% endhint %}

### **Body**

Add the required information you want to send as part of your request.&#x20;

You can send information in two ways:

#### **Raw:**

It is normal JSON format in which the request needs to be passed

<div align="left"><figure><img src="/files/HVUBrIfja7MmG18nCnBW" alt=""><figcaption></figcaption></figure></div>

#### **Form:**

It allows you to map the fields. You can either provide static value or map the variables

<div align="left"><figure><img src="/files/z6DKTsiyAxdsVBUZ6fhE" alt=""><figcaption></figcaption></figure></div>

## **Response**

When the HTTP request is made, you will receive a response from the API.

You can store the objects received from the API into variables by mapping the fields.

{% code overflow="wrap" %}

```
// Object path for storing the response into variable where list is returned

result.data.list[0].id

// Here the value of the field `id` will be stored in the variable mapped to it.
```

{% endcode %}

{% code overflow="wrap" %}

```
// Object path for storing the response into variable where single value is returned

result.data.id 

// Here the value of the field 'id' will be stored in the variable mapped to it.
```

{% endcode %}

## Testing API request&#x20;

Once you have configured your API request, you can click on the 'Test the API' button and see the response received.

From the response screen, you can directly save the object into a variable by clicking on the + icon.

<figure><img src="/files/8POKph1SszKRZiXBHDsO" alt=""><figcaption></figcaption></figure>


# Automations

Automations let you create automations which trigger during a conversation with an agent/chatbot.

You can use automations to:

* Add chat transcript to your CRM after chat ends
* Notify your team when SLA is breached
* Send slack notifications when a variable changes to X
* Send an email to the visitor after chat ends
* and more...

To create a automation follow these steps:

## Step 1: Create an automation

Goto Settings > Account > Automations

<figure><img src="/files/3NMa8ilU0uBIiTqOfsbo" alt=""><figcaption></figcaption></figure>

## Step 2: Define your trigger criteria

Set a trigger that, when met, starts this automation. You can choose from:

* Assignee change
* Conversation status
* Variable value

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

{% hint style="info" %}
You can add multiple trigger conditions by matching ALL/ANY conditions using the radio button.
{% endhint %}

## Step 3: Define the action you want to perform

Choose what action you want this automation to perform once the trigger conditions are met. You can select from:

* **Send an email** – Send an email notification to a specified address.

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

* **Fire an API** – Make an API request to a specified endpoint. [Learn more](/build/integrations/http-request-api)

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

## Step 4: Activate your automation

Finally, switch the automation on to make it active and start running whenever the trigger conditions are met.

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


# Events

Listen to webhook events from the WotNot platform.

{% hint style="info" %}
Available in the **ENTERPRISE** plan.
{% endhint %}

Enabling the events, will give you access to define your webhook endpoint which would receive all the subscribed events.&#x20;

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

## List of events

### Conversation Creation

When a new conversation is created.

{% code overflow="wrap" %}

```json
{"events": [{"event": {"type": "conversation_create", "payload": {"assigned_to_user": {"email": "seq_user@wotnot-seq.com", "id": "8181", "type": "bot"}, "created_at": "2023-08-29 04:27:48.236411", "title": "Visitor - A27187", "bot_id": 8861, "channel": {"name": 1, "provider": 0}, "is_new_visitor": false, "is_closed": 0, "external_key": "7f984da9a15b4bceb512ecad8ca461051693283267", "browser": "Chrome 116 (116.0.0.0)", "variables": [{"type": "text", "name": "bot_name", "value": "All Dialogs"}, {"type": "text", "name": "referrer_url", "value": ""}, {"type": "text", "name": "timezone", "value": "Asia/Calcutta"}, {"type": "text", "name": "os", "value": "Mac OS X 10_15_7"}, {"type": "text", "name": "browser_language", "value": "en-GB"}, {"type": "text", "name": "browser", "value": "Chrome 116 (116.0.0.0)"}, {"type": "text", "name": "ip_address", "value": "49.249.141.54"}, {"type": "text", "name": "global_channel_name", "value": "WEB"}, {"type": "date", "name": "conversation_created_at", "value": "2023-08-29T04:27:48.183000+00:00"}, {"type": "text", "name": "conversation_url", "value": "https://app.dev.wotnot.io/account/476/live-chat/bot/8861/conversations/unassigned/7f984da9a15b4bceb512ecad8ca461051693283267"}, {"type": "text", "name": "source_url", "value": "https://app.dev.wotnot.io/bot-preview/8Dc98btp4CPu0959442660854eRb8N5u"}, {"type": "text", "name": "contact_id", "value": "a569015fa03d41a283ed4c66c4601966"}, {"type": "text", "name": "visitor_contact_created_by", "value": "WotNot Development"}, {"type": "text", "name": "visitor_age", "value": "abc"}, {"type": "text", "name": "visitor_js1", "value": "hj"}, {"type": "text", "name": "visitor_name", "value": "nik"}]}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}
```

{% endcode %}

### Message exchange

When exchange of messages are made between bots/agents and visitors.

{% code overflow="wrap" %}

```json
// TEXT
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": null, "id": null, "type": "visitor"}, "message": {"type": "text", "text": "Hiiiii"}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:45.503552"}]}

//IMAGE
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "message": {"type": "image", "payload": {"link": "https://wotnot-conversation-attachment-dev.storage.googleapis.com/8861/Visitor%20-%20A27187-355aaabc63aa46aaa31b4a6ab1a89dd01693458824/30cb79cc-47bd-11ee-8b81-a241eeeaf60f_sample-clouds-400x300.jpg", "mime_type": "image/jpeg", "file_name": "photo-1579353977828-2a4eab540b9a.jpeg"}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}

//FORM
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "message": {"type": "form", "payload": {"message": "Please fill in the following details", "fields": [{"label": "Name", "type": "text", "variable": "\u00bf\u00b7$user.info.age\u00b7?", "is_optional": false}, {"label": "Email", "type": "email", "variable": "\u00bf\u00b7$user.info.email\u00b7?", "is_optional": false}, {"label": "Phone", "type": "phone", "variable": "\u00bf\u00b7$user.info.phone\u00b7?", "is_optional": false}]}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}

//FILE UPLOAD
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "message": {"type": "file_upload", "payload": {"title": "Can you please upload your file?", "allow_extensions": [".jpg", ".png", ".pdf", ".jpeg"], "max_file_size_in_kb": "Can you please upload your file?", "upload_file_limit": 1, "error_message": {"file_size": "Please upload a file below 10 MB", "file_extensions": "Please upload a valid file format", "file_not_found": "Invalid! Please upload a valid file"}}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}

//CALENDAR
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "message": {"type": "calendar", "payload": {"auto_open": true, "title": "What is your preferred date?", "validation": {"datepicker_type": "single", "start": "", "end": "", "formatter": "MM/DD/YYYY", "exclude_days": [], "include": [], "selected": "", "skip": []}}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}

//AUDIO
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "message": {"type": "audio", "payload": {"link": "https://bucket-dev.storage.googleapis.com/8791_8292_sWhsBMDwGdJf101716174591uHnJXdSB_attachment.mp3", "mime_type": "audio/mpeg", "file_name": "file_example_MP3_700KB.mp3"}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}

//CALENDLY
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": null, "id": null, "type": "visitor"}, "message": {"type": "calendly.response", "payload": {"variables": {"\u00bf\u00b7is_calendly_event_scheduled\u00b7?": true, "\u00bf\u00b7calendly_event\u00b7?": "https://api.calendly.com/scheduled_events/bddb81e6-36d4-4950-963d-1c436b9f9696", "\u00bf\u00b7calendly_invitee\u00b7?": "https://api.calendly.com/scheduled_events/bddb81e6-36d4-4950-963d-1c436b9f9696/invitees/84a6fc15-eee8-4e37-b976-0c77e3d70083"}}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:45.503552"}]}

//VIDEO
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "message": {"type": "video", "payload": {"link": "https://bucket-dev.storage.googleapis.com/8791_8292_2PoWjoofeMhP101802210051O8eGJvkH_attachment.mp4", "mime_type": "video/mp4", "file_name": "file_example_MP4_480_1_5MG.mp4"}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}

//LIST (WHATSAPP)
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "message": {"type": "list", "payload": {"header": {"type": "text", "text": "Hello"}, "footer": "", "title": "What would you like to choose?", "list": {"title": "b-1", "sections": [{"title": "c-1", "items": [{"title": "Item 1", "description": "Item-1", "next_dialog": "2"}]}, {"title": "c-2", "items": [{"title": "Item 2", "description": "Item-2", "next_dialog": "2"}]}]}}}}}, "conversation": {"key": "8e6884db0c7a480e90b2118f6daae12c1693797745", "id": 7525719}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 4395}}, "visitor": {"key": "8eef41bf4d4248dd82d6a57c5b42fca9", "id": 826389}, "timestamp": "2023-09-04 03:41:27.335786"}]}

//JAVASCRIPT
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "message": {"type": "javascript", "payload": {"script": "wn.setContactVariables({\"JS1\": \"hj\"});\nwn.setConversationVariables({\"JS2\": \"Mtech\"});\nwindow.alert(5 + 6);\nconsole.log(\"Hello World!\");", "execute_at": "client"}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}

//BUTTON
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "message": {"type": "button", "payload": {"search_enabled": false, "multi_select_enabled": false, "buttons_layout": "horizontal", "buttons_order": "as defined", "buttons": [{"title": "Button 1", "type": "branch", "callback": "", "next_dialog": "6"}, {"title": "Button 2", "type": "web_url", "callback": "{\"web_url\": \"https://www.google.com\", \"browser_window\": \"new\"}", "next_dialog": "5"}, {"title": "Button 3", "type": "branch", "callback": "", "next_dialog": "14"}], "title": "What would you like to choose?"}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}

//DOCUMENT
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "message": {"type": "document", "payload": {"link": "https://bucket-dev.storage.googleapis.com/8791_8292_B9DwdqiUy5Ea101257098374GOoPO0Mc_attachment.pdf", "mime_type": "application/pdf", "file_name": "TICKETS.pdf"}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}

//CAROUSEL
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "message": {"type": "carousel", "payload": {"title": "Image Carousel 1", "items": [{"image": "https://wotnot-conversation-attachment-dev.storage.googleapis.com/8861_8292_2uMHreVKUmDc100237912704NbQFNlWF_attachment.jpg", "action": ""}]}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}

//JAVASCRIPT RESPONSE
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": null, "id": null, "type": "visitor"}, "message": {"type": "javascript.response", "payload": {"variables": {"\u00bf\u00b7$user.info.JS1\u00b7?": "hj", "\u00bf\u00b7JS2\u00b7?": "Mtech"}}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:45.503552"}]}

//SLIDER RESPONSE
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": null, "id": null, "type": "visitor"}, "message": {"type": "slider.response", "payload": {"value": 30, "text": "30"}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:45.503552"}]}

//SLIDER
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "message": {"type": "slider", "payload": {"title": "What is your preferred value?", "min": 10, "max": 50, "step": "None", "unit": {"label": "", "value": "", "formatter": ""}}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}

//APPOINTMENT BOOKING RESPONSE
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": null, "id": null, "type": "visitor"}, "message": {"type": "appointment_booking.response", "payload": {"event_id": 622, "is_booking_confirmed": true, "is_booking_failed": false, "event_name": "fsefgr", "visitor_timezone": "(GMT+05:30) Asia/Calcutta", "variables": [{"type": "text", "name": "visitor_name", "value": "nik1"}, {"type": "text", "name": "param__gcal_selected_slot_time", "value": "10:00"}, {"type": "text", "name": "param__gcal_selected_slot_date", "value": "01/09/2023"}, {"type": "text", "name": "param__gcal_selected_slot_day", "value": "Friday"}]}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:45.503552"}]}

//BUTTON RESPONSE
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": null, "id": null, "type": "visitor"}, "message": {"type": "button.response", "payload": {"body": "Button 1", "callback": {}}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:45.503552"}]}

//FORM RESPONSE
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": null, "id": null, "type": "visitor"}, "message": {"type": "form.response", "payload": {"fields": [{"label": "Name", "variable": "\u00bf\u00b7$user.info.age\u00b7?", "type": "text", "value": "abc", "extra": "None"}, {"label": "Email", "variable": "\u00bf\u00b7$user.info.email\u00b7?", "type": "email", "value": "abc@gmail.com", "extra": "None"}, {"label": "Phone", "variable": "\u00bf\u00b7$user.info.phone\u00b7?", "type": "phone", "value": "+916767667676", "extra": {"country_code": "91"}}]}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:45.503552"}]}

//FILE UPLOAD RESPONSE
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": null, "id": null, "type": "visitor"}, "message": {"type": "file_upload.response", "payload": {"type": "image", "payload": {"mime_type": "image/jpeg", "link": "https://wotnot-conversation-attachment-dev.storage.googleapis.com/8861/Visitor%20-%20A27187-355aaabc63aa46aaa31b4a6ab1a89dd01693458824/30cb79cc-47bd-11ee-8b81-a241eeeaf60f_sample-clouds-400x300.jpg", "file_name": "sample-clouds-400x300.jpg"}}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:45.503552"}]}

//APPOINTMENT BOOKING
{"events": [{"event": {"type": "message", "payload": {"message_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "message": {"type": "appointment_booking", "payload": {"event_id": 622, "duration": {"label": "minutes", "value": 30}, "title": "fsefgr"}}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}
```

{% endcode %}

### Status change

When the conversation status changes i.e. chat changes to open or closed.

{% code overflow="wrap" %}

```json
{"events": [{"event": {"type": "status", "payload": {"closed_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "status": "Close"}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}
```

{% endcode %}

### Assignee change

When the assignee of the chat changes from bot to agent or amongst agents.

{% code overflow="wrap" %}

```json
{"events": [{"event": {"type": "assignee_change", "payload": {"changed_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "to": {"email": "example@example.com", "id": "8292", "type": "user"}, "from": {"id": "8181", "email": "seq_user@wotnot-seq.com", "type": "bot"}}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}
```

{% endcode %}

### Variable

Creation or updation of the value stored in the variable.

{% code overflow="wrap" %}

```json
// TEXT
{"events": [{"event": {"type": "variables", "payload": {"action_performed_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "variables": [{"type": "text", "name": "visitor_var12", "value": true}]}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}

//NUMBER
{"events": [{"event": {"type": "variables", "payload": {"action_performed_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "variables": [{"type": "number", "name": "visitor_phone123", "value": "123456789"}]}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}
```

{% endcode %}

### Label

Creation or attachment of a label to a chat.

{% code overflow="wrap" %}

```json
{"events": [{"event": {"type": "conversation_labels", "payload": {"action_performed_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "action": "deleted", "labels": [{"id": 2014}]}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}
```

{% endcode %}

### Note

When a note has been added to a chat.

{% code overflow="wrap" %}

```json
{"events": [{"event": {"type": "note", "payload": {"note_by": {"email": "example@example.com", "id": "8292", "type": "user"}, "note": "Hello"}}, "conversation": {"key": "42bb83f00d8240e5bb41290a12eb44401693552452", "id": 7525695}, "account": {"key": "VGYh5KEUxnaS043726528180Llb9R8pe", "id": 476, "bot": {"id": 8861}}, "visitor": {"key": "a569015fa03d41a283ed4c66c4601966", "id": 826373}, "timestamp": "2023-09-01 14:13:32.141788"}]}
```

{% endcode %}

### SLA breached

When an SLA breach event occurs with a conversation.

```json
{
      "event": {
        "type": "sla_breached",
        "payload": {
          "breached_by": {
            "email": "email@example.com",
            "id": 14223
          },
          "breach_timestamp": "2025-12-16 04:50:32.961000"
        }
      },
      "conversation": {
        "key": "80f9f4a1c48a4e77a7ba4e9ba1b01c2e1765860444",
        "id": 7568684
      },
      "account": {
        "key": "4g96HFUC7zkc0910496115822eP9lfZj",
        "id": 2020,
        "bot": {
          "id": 16298,
          "type": "inbound"
        }
      },
      "visitor": {
        "key": "d361fee8f2bb499b893baae661e79066",
        "id": 1910233,
        "name": "",
        "email": "",
        "phone": ""
      },
      "timestamp": "2025-12-16 04:50:33.030544"
}
```

### Message status

Tracks the latest delivery status of any message sent by a bot or agent.

```json
// For outbound messages
{
      "event": {
        "type": "message_status",
        "payload": {
          "message_id": "Ca55PnHpUfNd044323394480rVb9YGd5",
          "status": {
            "value": "failed",
            "failed_reason": "Maximum credits exceeded"
          }
        }
      },
      "campaign_details": {
        "request_key": "8llu8f4cdbva044314886759iqg0t5"
      },
      "account": {
        "key": "4g96HFUC7zkc0910496115822eP9lfZj",
        "id": 2020,
        "bot": {
          "id": 16289,
          "type": "outbound"
        }
      },
      "visitor": {
        "key": "3Xge7pr9QF82095213821861xQGzIdu9",
        "id": 941009,
        "name": "hp",
        "email": "harshil.paladiya@wotnot.io",
        "phone": "919327030075"
      },
      "timestamp": "2025-12-16 04:43:24.000000"
}
    
// For inbound messages
{
      "event": {
        "type": "message_status",
        "payload": {
          "message_id": "47FuUoNE7jkU044524077841Ahi61g9d",
          "status": {
            "value": "delivered",
            "failed_reason": null
          }
        }
      },
      "conversation": {
        "key": "c8553a8374234d539d62b4e56169960b1765860322",
        "id": 7568683
      },
      "account": {
        "key": "4g96HFUC7zkc0910496115822eP9lfZj",
        "id": 2020,
        "bot": {
          "id": 16298,
          "type": "inbound"
        }
      },
      "visitor": {
        "key": "d361fee8f2bb499b893baae661e79066",
        "id": 1910233,
        "name": "",
        "email": "",
        "phone": ""
      },
      "timestamp": "2025-12-16 04:45:24.000000"
}
```

***

## Subscribing to events

To subscribe to events, follow the below steps:

### Step 1: Enable the events feature

Turn on the feature, and enter your webhook endpoint and a token that would be passed when the event is published.

### Step 2: Select events

Select the events that you want to listen to and save.&#x20;

{% hint style="info" %}
Refer to the payload as shown in the above events.
{% endhint %}

### Step 3: Test the webhook

Upon saving, we'll send a HTTP POST request to the provided endpoint along with the token. We will expect the same token provided as response with 200 OK.

<figure><img src="/files/U5wa1SWsxferI6aF669T" alt=""><figcaption><p>Expected response when endpoint is invoked</p></figcaption></figure>


# Public APIs

## Authorization

All of WotNot's APIs use a Bearer token based authentication.

Your account token can be found at Settings > Account Settings > Developer.

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

## Endpoint URL

Endpoint URL for all API integration with WotNot APIs are:

<kbd><https://api.wotnot.io></kbd>

## Create a knowledge base

<mark style="color:orange;">`POST`</mark> `/v1/ai/knowledge-base`

Using this API, you can create a knowledge base in the account.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

```json
{
  "name": "KNOWLEDGE_BASE_NAME"
}
```

**Response**

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

```json
{
    "ok": true,
    "id": KNOWLEDGE_BASE_ID,
    "message": "Knowledge base has been created.",
    "code": "CREATE_KNOWLEDGE_BASE_SUCCESS_MESSAGE"
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "ok": false,
    "message": "You have reached the maximum number of knowledge bases. Upgrade your plan to create more knowledge bases.",
    "error": "MAX_KNOWLEDGE_BASE_COUNT_EXCEEDED",
    "code": "MAX_KNOWLEDGE_BASE_COUNT_EXCEEDED"
}

{
    "ok": false,
    "message": "Please reach out to support to use this feature",
    "error": "UNAUTHORIZED_FEATURE",
    "code": "UNAUTHORIZED_FEATURE"
}
```

{% endtab %}
{% endtabs %}

## Adding text/file data sources to a knowledge base

<mark style="color:orange;">`POST`</mark> `/api/v1/ai/knowledge-base/<knowledge_base_id>/upload/sources`

Using this API, you can add a data source to an existing knowledge base.

**Headers**

| Name          | Value                 |
| ------------- | --------------------- |
| Content-Type  | `multipart/form-data` |
| Authorization | `Bearer <token>`      |

**Body**

The API accepts files and text as multipart form data for upload. Each form field should be a unique key and contain either a file or text content.

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

| Name                     | Type      | Value         |
| ------------------------ | --------- | ------------- |
| file\_data\_source\_name | form-data | File location |
| {% endtab %}             |           |               |

{% tab title="Text" %}

| Name                     | Type      | Value        |
| ------------------------ | --------- | ------------ |
| text\_data\_source\_name | form-data | Text content |
| {% endtab %}             |           |              |
| {% endtabs %}            |           |              |

**Response**

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

```json
{
  "q1": [
    {
      "id": 330783,
      "type": "text",
      "name": "sample.txt",
      "status": "in-progress",
      "errors": null
    },
    {
      "id": 330784,
      "type": "text",
      "name": "sample2.txt",
      "status": "in-progress",
      "errors": null
    },
    {
      "id": 330785,
      "type": "file",
      "name": "File.pdf",
      "status": "in-progress",
      "errors": null
    }
  ],
  "d2": [
    {
      "id": 330786,
      "type": "file",
      "name": "File2.pdf",
      "status": "in-progress",
      "errors": null
    }
  ],
  "knowledge_base_id": 876,
  "ok": true
}
```

{% endtab %}

{% tab title="400" %}

```json
{
  "ok": false,
  "error": "KNOWLEDGE_BASE_NOT_FOUND",
  "message": "KnowledgeBase Not Found in DB!",
  "code": "KNOWLEDGE_BASE_NOT_FOUND",
  "status": 404
}
{
  "ok": false,
  "error": "JWT_SIGNATURE_EXCEPTION",
  "message": "Invalid JWT token",
  "status": 401
}
{
  "ok": false,
  "error": "UNAUTHORIZED_FEATURE",
  "code": "UNAUTHORIZED_FEATURE",
  "status": 401,
  "message": "Please reach out to support to use this feature"
}
{
  "ok": false,
  "error": "ACCOUNT_DETAILS_NOT_FOUND",
  "code": "ACCOUNT_DETAILS_NOT_FOUND",
  "status": 404,
  "message": "Account Details are Not Found!"
}
{
  "ok": false,
  "error": "BAD_REQUEST",
  "code": "BAD_REQUEST",
  "status": 400,
  "message": "Knowledge base does not belong to the account(876)"
}
```

{% endtab %}
{% endtabs %}

## Adding individual URLs data sources to a knowledge base

<mark style="color:orange;">`POST`</mark> `/v1/ai/knowledge-base/<knowledge_base_id>/data-sources/webpages`

Using this API, you can add individual URLs as data sources to an existing knowledge base.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

```
{
    "urls": [
        "https://wotnot.io",
        "https://wotnot.io/pricing"
    ]
}
```

**Response**

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

```json
{
    "ok": true,
    "data_sources": [
        {
            "knowledge_base_id": "29",
            "id": 1335,
            "name": "https://wotnot.io",
            "source_type": "url",
            "token": 0,
            "refresh_frequency": null,
            "last_trained_at": null,
            "status": "in-progress",
            "type": "url",
            "created_at": "2025-07-07 05:09:34.218507",
            "created_by": {
                "id": 2,
                "name": "System"
            }
        },
        {
            "knowledge_base_id": "29",
            "id": 1336,
            "name": "https://wotnot.io/pricing",
            "source_type": "url",
            "token": 0,
            "refresh_frequency": null,
            "last_trained_at": null,
            "status": "in-progress",
            "type": "url",
            "created_at": "2025-07-07 05:09:34.218507",
            "created_by": {
                "id": 2,
                "name": "System"
            }
        }
    ]
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "error": "BAD_REQUEST",
    "ok": false,
    "status": 400,
    "message": [
        {
            "message": "\"urls[0]\" must be a valid uri",
            "path": [
                "urls",
                0
            ]
        },
        {
            "message": "\"urls\" does not contain 1 required value(s)",
            "path": [
                "urls"
            ]
        }
    ]
}
```

{% endtab %}

{% tab title="401" %}

```
{
    "message": "Please reach out to support to use this feature",
    "ok": false,
    "error": "UNAUTHORIZED_FEATURE",
    "code": "UNAUTHORIZED_FEATURE",
    "status": 401
}
```

{% endtab %}
{% endtabs %}

## Adding domain data source to a knowledge base

<mark style="color:orange;">`POST`</mark> `/v1/ai/knowledge-base/<knowledge_base_id>/data-sources/domain`

Using this API, you can add domain as data source to an existing knowledge base.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

```
{
    "type": "domain",
    "url": "https://wotnot.io",
    "exclude_urls": "",
    "refresh_frequency": null
}
```

**Response**

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

```json
{
    "ok": true,
    "domain_id": 8,
    "request_id": "3QWuobWJE3jF065037422196qAdTZ2Ct"
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "message": "Maximum urls allowed 4",
    "ok": false,
    "error": "BAD_REQUEST",
    "code": "BAD_REQUEST",
    "status": 400
}

{
    "error": "BAD_REQUEST",
    "ok": false,
    "status": 400,
    "message": [
        {
            "message": "\"url\" must be a valid uri",
            "path": [
                "url"
            ]
        }
    ]
}
```

{% endtab %}

{% tab title="401" %}

```
{
    "message": "Please reach out to support to use this feature",
    "ok": false,
    "error": "UNAUTHORIZED_FEATURE",
    "code": "UNAUTHORIZED_FEATURE",
    "status": 401
}
```

{% endtab %}
{% endtabs %}

## Deleting data sources from a knowledge base

<mark style="color:red;">`DELETE`</mark> `/v1/ai/knowledge-bases/<knowledge_base_id>/data-sources`

Using this API, you can delete data sources from an existing knowledge base.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

```json
{
    "data_sources": [
        <data_source_id_1>,
        <data_source_id_2>
    ]
}
```

**Response**

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

<pre class="language-json"><code class="lang-json"><strong>{
</strong>    "ok": true
}
</code></pre>

{% endtab %}

{% tab title="400" %}

```json
{
    "error": "BAD_REQUEST",
    "ok": false,
    "status": 400,
    "message": [
        {
            "message": "\"data_sources\" is required",
            "path": [
                "data_sources"
            ]
        }
    ]
}
```

{% endtab %}

{% tab title="401" %}

```json
{
    "error": "UNAUTHORIZED",
    "ok": false,
    "status": 401,
    "message": "Invalid token. Provide the valid account token."
}
```

{% endtab %}

{% tab title="404" %}

```json
{
    "message": "Resource not found",
    "ok": false,
    "error": "RESOURCE_NOT_FOUND",
    "code": "RESOURCE_NOT_FOUND",
    "status": 404
}
```

{% endtab %}
{% endtabs %}

## Get training status of a data source <a href="#get-training-status-of-a-data-source" id="get-training-status-of-a-data-source"></a>

<mark style="color:green;">`GET`</mark> `/api/v1/ai/status/sources`

Using this API, you can fetch the status of one or more data sources in a knowledge base to know it its training is - in progress / completed / failed.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

| Name         | Type         | Description                                                               |
| ------------ | ------------ | ------------------------------------------------------------------------- |
| `source_ids` | query params | Comma-separated list of data source IDs to be passed as **query params**. |

**Response**

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

```json
{
    "sources": [
        {
            "id": 330778,
            "name": "sample.txt",
            "status": "in-progress",
            "knowledge_base_id": 876
        }
    ],
    "ok": true
}
```

{% endtab %}

{% tab title="400" %}

```json
{
  "ok": false,
  "error": "JWT_SIGNATURE_EXCEPTION",
  "message": "Invalid JWT token",
  "status": 401
}
{
  "ok": false,
  "error": "UNAUTHORIZED_FEATURE",
  "code": "UNAUTHORIZED_FEATURE",
  "status": 401,
  "message": "Please reach out to support to use this feature"
}
{
  "ok": false,
  "error": "ACCOUNT_DETAILS_NOT_FOUND",
  "code": "ACCOUNT_DETAILS_NOT_FOUND",
  "status": 404,
  "message": "Account Details are Not Found!"
}
```

{% endtab %}
{% endtabs %}

## Fetch knowledge base details

<mark style="color:green;">`GET`</mark> `/v1/ai/knowledge-base/<knowledge_base_id>`

Using this API, you can fetch knowledge base and it's relevant data sources details.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

```json
{
  "limit": 100,
  "offset": 1
}
```

**Response**

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

```json
{
  "ok": true,
  "id": KNOWLEDGE_BASE_ID,
  "name": "KNOWLEDGE_BASE_NAME",
  "total_tokens": TOTAL_TOKENS_USED_IN_KNOWLEDGE_BASE,
  "total_data_sources": TOTAL_NUMBER_OF_DATA_SOURCES,
  "data_source": [
    {
      "id": DATA_SOURCE_ID,
      "name": "DATA_SOURCE_NAME",
      "source": "DATA_SOURCE_URL_OR_CONTENT",
      "token": TOTAL_TOKENS_USED_IN_DATA_SOURCE,
      "domain_id": DOMAIN_ID,
      "refresh_frequency": null,
      "last_trained_at": "2024-12-27 09:10:11.870000",
      "status": "trained",
      "failed_reason": null,
      "type": "url",
      "created_at": "2024-12-27 09:10:02.411000",
      "created_by": USER_ID,
      "user_name": "USER_NAME"
    }
  ],
  "domains": [],
  "pagination": {
    "limit": 100,
    "offset": 1,
    "total": TOTAL_NUMBER_OF_DATA_SOURCES
  },
  "last_trained_at": "2024-12-27 09:13:26.905000"
}
```

{% endtab %}

{% tab title="404" %}

```json
{
    "ok": false,
    "message": "Resource not found",
    "error": "RESOURCE_NOT_FOUND",
    "code": "RESOURCE_NOT_FOUND"
}
```

{% endtab %}
{% endtabs %}

## Creating contacts

<mark style="color:orange;">`POST`</mark> `/v1/conversations`

Using this endpoint, you can create new contacts and update existing contacts.&#x20;

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

Contains the contacts payload. Either "email" or "phone" is mandatory to create contact.

Pass all the custom contact variables in "custom\_variables" field.

```json
{
    "contacts": [
        {
            "name": "Michael Anderson",
            "email": "michael.anderson@example.com",
            "phone": "+1212555",
            "custom_variables": {
                "company": "Example Company"
            }
        },
        {
            "name": "Jessica Martinez",
            "email": "jessica.martinez@example.com",
            "phone": "+111221555",
            "custom_variables": {
                "company": "Example Company"
            }
        }
    ]
}
```

**Response**

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

```json
{
    "created": [
        {
            "id": 24135508,
            "external_key": "111221555_13361",
            "key": "6AFH8gyvwKCB073815082213IgPXtWMj",
            "ok": true
        }
    ],
    "updated": [
        {
            "id": 24135493,
            "external_key": "1212555_13361",
            "key": "7oFMaCsVoDD2073727174868hp2AavON",
            "ok": true
        }
    ]
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "error": "BAD_REQUEST",
    "ok": false,
    "status": 400,
    "message": [
        {
            "message": "\"contacts[0]\" must contain at least one of [email, phone]",
            "path": [
                "contacts",
                0
            ]
        }
    ]
}
```

{% endtab %}

{% tab title="401" %}

```json
{
    "error": "UNAUTHORIZED",
    "ok": false,
    "status": 401,
    "message": "Invalid token. Provide the valid account token."
}
```

{% endtab %}
{% endtabs %}

## Creating a conversation

<mark style="color:orange;">`POST`</mark> `/v1/conversations`

Using this endpoint, you can start/create a new conversation.&#x20;

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

Contains the message payload. Payload differs based on channel.

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

```json
{
   "channel": "WHATSAPP",
   "from": "1123123123",
   "to": {
       "phone": "11231231230",
       "name": "John Doe",
       "email": "example@domain.com"
   },
   "message": {
       "type": "template",
       "data": {
           "template": "test_template",
           "parameters": {
               "header": [
                   "John"
               ],
               "body": [
                   "Doe",
                   "Doe2"
               ],
               "buttons": {
                   "copy_code": "123456",
                   "otp": "123456",
                   "url": "any"
               }
           },
           "variables":{
               "name": "John Doe"
           }
       }
   },
   "assignee": "agent_email@domain.com"
}
```

{% endtab %}

{% tab title="SMS" %}

```json
{
   "channel": "SMS",
   "from": "1-123-1231230",
   "to": {
       "phone": "1-1321231320",
       "name": "John Doe",
       "email": "abc@acme.com"
   },
   "message": {
       "type": "text",
       "text": "Hii"
   },
   "assignee": "agent_email@domain.com"
}
```

{% endtab %}
{% endtabs %}

**Response**

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

```json
{
  "ok": true,
  "conversation": {
    "id": "12wfegrgt4t",
    "message_id": "sdvgret4353b",
    "created_at": "",
    "assignee": {
      "id": 123,
      "to": "agent_email@domain.com"
    }
  },
  "contact": {
    "id": "11111111",
    "name": "John Doe",
    "phone": "1234567890",
    "email": "example@domain.com"
  }
}
```

{% endtab %}

{% tab title="400" %}

```json
{
  "ok": false,
  "error": "CHANNEL_TOKEN_EXPIRED",
  "code": "CHANNEL_TOKEN_EXPIRED",
  "message": "Token used to configure the channel is expired. Please reconfigure the channel.",
  "status": 400
}

{
  "ok": false,
  "error": "CONVERSATION_CREATION_EXCEPTION",
  "code": "CONVERSATION_CREATION_EXCEPTION",
  "message": "Conversation is not created. Please try again after some time.",
  "status": 400
}

{
  "ok": false,
  "error": "CHANNEL_NOT_ENABLED",
  "code": "CHANNEL_NOT_ENABLED",
  "message": "This channel is not enabled in the account.",
  "status": 400
}

{
  "ok": false,
  "error": "CONTACT_IS_BLOCKED",
  "code": "CONTACT_IS_BLOCKED",
  "message": "Conversation cannot be created for blocked contact.",
  "status": 400
}

{
  "ok": false,
  "error": "CONTACT_IS_BLOCKED",
  "code": "CONTACT_IS_BLOCKED",
  "message": "Conversation cannot be created for blocked contact.",
  "status": 400
}

{
  "ok": false,
  "error": "CONTACT_IS_BLOCKED",
  "code": "CONTACT_IS_BLOCKED",
  "message": "Conversation cannot be created for blocked contact.",
  "status": 400
}

{
  "ok": false,
  "error": "CONVERSATION_NOT_CREATED",
  "code": "CONVERSATION_NOT_CREATED",
  "message": "Conversation is not created due to user limit validation",
  "status": 400
}
```

{% endtab %}

{% tab title="401" %}

```json
{
   "error": "JWT_SIGNATURE_EXCEPTION",
   "message": "Invalid JWT token",
   "ok": false,
   "status": 401
}
```

{% endtab %}

{% tab title="404" %}

```json
{
  "ok": false,
  "error": "PHONE_NUMBER_IS_NOT_CONFIGURED",
  "code": "PHONE_NUMBER_IS_NOT_CONFIGURED",
  "message": "’From’ phone number is not configured in the account.",
  "status": 404
}

{
  "ok": false,
  "error": "WHATSAPP_TEMPLATE_NOT_FOUND",
  "code": "WHATSAPP_TEMPLATE_NOT_FOUND",
  "message": "WhatsApp template is not available in the account.",
  "status": 404
}

{
  "ok": false,
  "error": "TEMPLATE_NOT_APPROVED",
  "code": "TEMPLATE_NOT_APPROVED",
  "message": "Oops, template is not approved",
  "status": 404
}
```

{% endtab %}
{% endtabs %}

## Send agent response to a conversation

<mark style="color:orange;">`POST`</mark> `/api/v1/conversation/<conversation_id>/messages`

For every response sent by the agent on the third-party system, this API is to be invoked so it can relay this response to the user.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

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

```json
{
  "message": {
    "data": {
      "body": "Hi"
    },
    "type": "text"
  },
  "user": {
    "by": "agent_email@domain.com"
  }
}
```

{% endtab %}

{% tab title="File" %}

```json
{
  "message": {
    "file": {
      "path": "https://framerusercontent.com/images/L2xfXiiCkddPZOjvWCGTusENwb4.png",
      "size": 1,
      "type": "image/png",
      "name": "L2xfXiiCkddPZOjvWCGTusENwb4.png"
    },
    "type": "file"
  },
  "user": {
    "by": "agent_email@domain.com"
  }
}
```

{% endtab %}

{% tab title="Voice" %}

```json
{
  "message": {
    "file": {
      "path": "https://file-examples.com/storage/fe32d8b189680228b9ad370/2017/11/file_example_WAV_1MG.wav",
      "size": 1,
      "type": "audio/wav",
      "name": "file_example_WAV_1MG.wav"
    },
    "type": "voice"
  },
  "user": {
    "by": "agent_email@domain.com"
  }
}
```

{% endtab %}

{% tab title="Template message" %}

```json
{
  "message": {
    "data": {
      "template": "template_1"
    },
    "type": "template"
  },
  "user": {
    "by": "agent_email@domain.com"
  }
}
```

{% endtab %}
{% endtabs %}

**Response**

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

```json
{
  "ok": true,
  "message_id": "6HRBshHEcV8P103039226478taGDJQxC"
}
```

{% endtab %}

{% tab title="400" %}

```json
{
  "ok": false,
  "error": "INVALID_DATA",
  "code": "INVALID_DATA",
  "message": "Error message",
  "status": 400
}

{
  "ok": false,
  "error": "CONVERSATION_CLOSED",
  "code": "CONVERSATION_CLOSED",
  "message": "Assignee cannot be changed on closed conversation.",
  "status": 400
}

{
  "ok": false,
  "error": "CONVERSATION_ASSIGNED_TO_BOT",
  "code": "CONVERSATION_ASSIGNED_TO_BOT",
  "message": "Agent message cannot be sent on bot assigned conversation.",
  "status": 400
}

{
  "ok": false,
  "error": "CONTACT_IS_BLOCKED",
  "code": "CONTACT_IS_BLOCKED",
  "message": "Conversation cannot be created for blocked contact.",
  "status": 400
}

{
  "ok": false,
  "error": "MESSAGE_NOT_SENT",
  "code": "MESSAGE_NOT_SENT",
  "message": "Message is not sent due to user limit validation.",
  "status": 400
}
```

{% endtab %}

{% tab title="401" %}

```json
{
  "ok": false,
  "error": "JWT_SIGNATURE_EXCEPTION",
  "code": "JWT_SIGNATURE_EXCEPTION",
  "message": "Invalid JWT token",
  "status": 401
}
```

{% endtab %}

{% tab title="404" %}

```json
{
  "ok": false,
  "error": "CONVERSATION_NOT_FOUND",
  "code": "CONVERSATION_NOT_FOUND",
  "message": "Conversation is not available.",
  "status": 404
}
```

{% endtab %}
{% endtabs %}

## Closing a conversation

<mark style="color:orange;">`POST`</mark> `/api/v1/conversation/<conversation_id>/events`

Use this endpoint to close an open conversation.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

```json
{
  "event": "status",
  "status": "CLOSE",
  "user": {
    "by": "agent_email@domain.com"
  }
}
```

**Response**

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

```json
{
  "ok": true
}
```

{% endtab %}

{% tab title="400" %}

```json
{
  "ok": false,
  "error": "CONVERSATION_NOT_CLOSED",
  "code": "CONVERSATION_NOT_CLOSED",
  "message": "Conversation is not closed due to user limit validation.",
  "status": 400
}
```

{% endtab %}

{% tab title="401" %}

```json
{
  "ok": false,
  "error": "JWT_SIGNATURE_EXCEPTION",
  "code": "JWT_SIGNATURE_EXCEPTION",
  "message": "Invalid JWT token",
  "status": 401
}
```

{% endtab %}

{% tab title="404" %}

```json
{
  "ok": false,
  "error": "CONVERSATION_NOT_FOUND",
  "code": "CONVERSATION_NOT_FOUND",
  "message": "Conversation is not available.",
  "status": 404
}
```

{% endtab %}
{% endtabs %}

## Changing assignee in a conversation

<mark style="color:orange;">`POST`</mark> `/api/v1/conversation/<conversation_id>/events`

Use this endpoint to change the assignee in an open conversation.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

```json
// Change from assignee to assignee
{
  "event": "assignee",
  "user": {
    "by": "agent_email@domain.com",
    "to": "assignee@domain.com"
  }
}

// Change from assignee to team
{
  "event": "assignee",
  "team": {
    "by": "agent_email@domain.com",
    "to": "Sales"
  }
}
```

**Response**

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

```json
{
  "ok": true
}
```

{% endtab %}

{% tab title="400" %}

```json
{
  "ok": false,
  "error": "TEAM_NOT_FOUND",
  "code": "TEAM_NOT_FOUND",
  "message": "Team does not exist.",
  "status": 400
}


{
  "ok": false,
  "error": "CONVERSATION_CLOSED",
  "code": "CONVERSATION_CLOSED",
  "message": "Assignee cannot be changed on closed conversation.",
  "status": 400
}


{
  "ok": false,
  "error": "ASSIGNEE_CHANGE_EXCEPTION",
  "code": "ASSIGNEE_CHANGE_EXCEPTION",
  "message": "By and To user are same. Can not assign conversation to same user.",
  "status": 400
}


{
  "ok": false,
  "error": "ASSIGNEE_NOT_CHANGED",
  "code": "ASSIGNEE_NOT_CHANGED",
  "message": "Assignee is not changed due to user limit validationt.",
  "status": 400
}
```

{% endtab %}

{% tab title="401" %}

```json
{
  "ok": false,
  "error": "JWT_SIGNATURE_EXCEPTION",
  "code": "JWT_SIGNATURE_EXCEPTION",
  "message": "Invalid JWT token",
  "status": 401
}
```

{% endtab %}

{% tab title="404" %}

```json
{
  "ok": false,
  "error": "CONVERSATION_NOT_FOUND",
  "code": "CONVERSATION_NOT_FOUND",
  "message": "Conversation is not available.",
  "status": 404
}
```

{% endtab %}
{% endtabs %}

## Update variable of a conversation

<mark style="color:orange;">`POST`</mark> `/v1/accounts/<account_id>/conversations/<conversation_id>/variables`

Use this endpoint to update the variables in the conversation.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

```json
{
  "variables": [
    {
      "name": "name",
      "type": "conversation",
      "value": "John Doe"
    },
    {
      "name": "phone",
      "type": "contact",
      "value": "9999999999"
    },
    {
      "name": "company",
      "type": "conversation",
      "value": "Example"
    },
    {
      "name": "email",
      "type": "contact",
      "value": "john.doe@gmail.com"
    }
  ]
}
```

**Response**

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

```json
{
  "ok": true
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "ok": false,
    "message": {
        "variables": [
            "Shorter than minimum length 1."
        ]
    },
    "status": 400,
    "error": "BAD_REQUEST"
}
```

{% endtab %}

{% tab title="401" %}

```json
{
    "error": "UNAUTHORIZED",
    "ok": false,
    "status": 401,
    "message": "Invalid token. Provide the valid account token."
}
```

{% endtab %}

{% tab title="404" %}

```json
{
    "message": "Conversation is not found",
    "ok": false,
    "error": "CONVERSATION_NOT_FOUND",
    "code": "CONVERSATION_NOT_FOUND",
    "status": 404
}
```

{% endtab %}
{% endtabs %}

## Set webhook URL for Events feature

<mark style="color:orange;">`POST`</mark> `/v1/accounts/<account_id>/webhook`

Use this endpoint to set webhook for receiving conversation related events from the account.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

```json
{
  "webhook_url": "",
  "subscribed_events": [
    {
      "key": "conversation_create",
      "is_subscribed": true
    },
    {
      "key": "message",
      "is_subscribed": true
    },
    {
      "key": "status",
      "is_subscribed": true
    },
    {
      "key": "assignee_change",
      "is_subscribed": true
    },
    {
      "key": "sla_breached",
      "is_subscribed": true
    },
    {
      "key": "variables",
      "is_subscribed": true
    },
    {
      "key": "conversation_labels",
      "is_subscribed": true
    },
    {
      "key": "note",
      "is_subscribed": true
    }
  ],
  "is_enabled": true,
  "token": "Test"
}
```

**Response**

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

```json
{
  "ok": true
}
```

{% endtab %}

{% tab title="401" %}

```json
{
    "error": "UNAUTHORIZED",
    "ok": false,
    "status": 401,
    "message": "Invalid token. Provide the valid account token."
}
```

{% endtab %}
{% endtabs %}

## Create a bot

<mark style="color:orange;">`POST`</mark> `/v1/bot`

Using this API, you can create a bot in account.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

```json
{
  "name": "BOT_NAME",
  "template_id": REFERENCE_BOT_ID,
  "channel": "API"
}
```

**Response**

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

```json
{
    "ok": true,
    "id": BOT_ID
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "ok": false,
    "message": "Maximum bots limit reached for the account.",
    "error": "MAXIMUM_BOTS_LIMIT_REACHED",
    "code": "MAXIMUM_BOTS_LIMIT_REACHED"
}
```

{% endtab %}
{% endtabs %}

## Fetch bot flow

<mark style="color:green;">`GET`</mark> `/v1/bots/<bot_id>/flow`

Using this API, you can fetch bot's flow data.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

**Response**

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

```json
{
    "ok": true,
    "data": "BOT_FLOW_JSON",
    "is_deployed": true,
    "last_deployed_at": "2025-05-05 10:37:43.128000"
}
```

{% endtab %}

{% tab title="404" %}

```json
{
    "error": "BOT_NOT_FOUND",
    "ok": false,
    "status": 404,
    "message": "Bot not found."
}
```

{% endtab %}
{% endtabs %}

## Deploy bot flow

<mark style="color:orange;">`POST`</mark> `/v1/bots/<bot_id>/deploy`

Using this API, you can deploy the bot flow after modifying it's JSON data.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

```json
{
  "flow_diagram": "BOT_FLOW_JSON"
}
```

**Response**

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

```json
{
    "ok": true,
    "data": "BOT_FLOW_JSON",
    "is_deployed": true,
    "last_deployed_at": "2025-05-05 10:37:43.128000"
}
```

{% endtab %}

{% tab title="404" %}

```json
{
    "error": "BOT_NOT_FOUND",
    "ok": false,
    "status": 404,
    "message": "Bot not found."
}
```

{% endtab %}
{% endtabs %}

## Fetch bots list

<mark style="color:green;">`GET`</mark> `/v1/accounts/<account_id>/bots`

Use this endpoint to fetch list of bots available in the account.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Response**

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

```json
{
  "ok": true,
  "bots": [
    {
      "bot_title": "Appointment Booking",
      "channels": [
        {
          "name": "WEB"
        }
      ],
      "is_active": false,
      "bot_key": "7SgQLb4qUbp61059137828254t5QVE0H",
      "last_deployed_at": "2025-01-22 13:26:40.554000",
      "is_inactive_by_system": false,
      "priority": 1,
      "preferred_bot_language": {
        "label": "English",
        "code": "EN"
      },
      "type": "inbound",
      "outbound_type": null,
      "bot_owner": {
        "id": 14764,
        "name": "John Doe"
        "email": "john.doe@gmail.com"
      }
      "created_at": "2024-02-09 10:59:13.783000",
      "preview_key": "6H7PD4WwTmsU105913782825Zk3KCj3t",
      "bot_id": 9633
    }
  ]
}
```

{% endtab %}

{% tab title="401" %}

```json
{
    "error": "UNAUTHORIZED",
    "ok": false,
    "status": 401,
    "message": "Invalid token. Provide the valid account token."
}
```

{% endtab %}
{% endtabs %}

## Fetch account roles

<mark style="color:green;">`GET`</mark> `/v1/accounts/<account_id>/user-roles`

Use this endpoint to fetch all the user roles available in the account.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Response**

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

```json
{
  "roles": [
    {
      "role_configuration": {
        "live_chat": {
          "settings": true,
          "full_access": true,
          "human_handover": true
        },
        "analytics": {
          "full_access": true
        },
        "support_ticket": {
          "full_access": true
        },
        "bot_builder": {
          "full_access": true,
          "read_only_access": true
        },
        "ticket": {
          "full_access": true
        },
        "account_settings": {
          "teammates": true,
          "billing": true,
          "variables": true,
          "automation": true,
          "csat": true,
          "teams": true,
          "events": true,
          "settings": true,
          "link_tracking": true
        },
        "ai_studio": {
          "full_access": true
        },
        "contacts": {
          "full_access": true
        },
        "app_market": {
          "full_access": true
        },
        "channel_configuration": {
          "sms": {
            "opt_out_management": true,
            "configuration": true
          },
          "web": {
            "appearance": true,
            "trigger_conditions": true,
            "pop_up_messages": true,
            "configuration": true,
            "general_settings": true
          },
          "whatsapp": {
            "templates": true,
            "configuration": true
          },
          "instagram": {
            "configuration": true
          },
          "facebook": {
            "configuration": true
          },
          "voice": {
            "configuration": true
          },
          "email": {
            "templates": true,
            "configuration": true
          }
        }
      },
      "users_in_role": [
        {
          "user_type_id": 1,
          "image_url": null,
          "last_name": "Doe",
          "first_name": "John",
          "id": 112233,
          "email": "john.doe@gmail.com"
        }
      ],
      "master_role_id": 2,
      "id": 99,
      "role_name": "admin",
      "description": "Has complete access to configure and manage every aspect of the platform.",
      "created_at": "04-Jan-26, 01:13 AM"
    }
  ],
  "ok": true,
  "pagination": {
    "offset": 0,
    "limit": 50,
    "total": 1
  }
}
```

{% endtab %}

{% tab title="401" %}

```json
{
    "error": "UNAUTHORIZED",
    "ok": false,
    "status": 401,
    "message": "Invalid token. Provide the valid account token."
}
```

{% endtab %}
{% endtabs %}

## Invite user to account

<mark style="color:orange;">`POST`</mark> `/v1/accounts/<account_id>/user`

Using this API, you can invite user to the account.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

```json
{
    "user": {
        "email": "john.doe@gmail.com",
        "first_name": "John", // Optional
        "last_name": "Doe", // Optional
        "role_id": "262185" // Role ID received from "Fetch account roles" API
    },
    "notify_user": "true"
}
```

**Response**

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

```json
{
    "invitation_link": "{{customer_portal_domain}}/create-your-account?invitation_key={{invitation_key}}",
    "ok": true,
    "status": "invited"
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "error": "BAD_REQUEST",
    "ok": false,
    "status": 400,
    "message": [
        {
            "message": "\"user.email\" must be a valid email",
            "path": [
                "user",
                "email"
            ]
        }
    ]
}
```

{% endtab %}

{% tab title="401" %}

```json
 {
    "error": "UNAUTHORIZED",
    "ok": false,
    "status": 401,
    "message": "Invalid token. Provide the valid account token."
}
```

{% endtab %}

{% tab title="404" %}

<pre class="language-json"><code class="lang-json"><strong>{
</strong>    "error": "ROLE_NOT_FOUND",
    "ok": false,
    "status": 404,
    "message": "Role not found for this account."
}
</code></pre>

{% endtab %}
{% endtabs %}

## Update user role

<mark style="color:blue;">`PUT`</mark> `/v1/accounts/<account_id>/users/<user_id>`

Using this API, you can update the role of user.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Body**

```json
{
    "role_id": "262185" // Role ID received from "Fetch account roles" API
}
```

**Response**

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

```json
{
    "ok": true
}
```

{% endtab %}

{% tab title="400" %}

```json
{
    "error": "BAD_REQUEST",
    "ok": false,
    "status": 400,
    "message": [
        {
            "message": "\"role_id\" must be a number",
            "path": [
                "role_id"
            ]
        }
    ]
}
```

{% endtab %}

{% tab title="401" %}

```json
 {
    "error": "UNAUTHORIZED",
    "ok": false,
    "status": 401,
    "message": "Invalid token. Provide the valid account token."
}
```

{% endtab %}

{% tab title="404" %}

```json
{
    "error": "USER_NOT_FOUND",
    "ok": false,
    "status": 404,
    "message": "User not found in this account."
}

{
    "error": "ROLE_NOT_FOUND",
    "ok": false,
    "status": 404,
    "message": "Role not found for this account."
}
```

{% endtab %}
{% endtabs %}

## Remove user from account

<mark style="color:red;">`DELETE`</mark> `/v1/accounts/<account_id>/users/<user_id>`

Using this API, you can remove user from the account.

**Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

**Response**

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

```json
{
    "ok": true
}
```

{% endtab %}

{% tab title="401" %}

```json
 {
    "error": "UNAUTHORIZED",
    "ok": false,
    "status": 401,
    "message": "Invalid token. Provide the valid account token."
}
```

{% endtab %}

{% tab title="404" %}

```json
{
    "error": "USER_NOT_FOUND",
    "ok": false,
    "status": 404,
    "message": "User not found in this account."
}
```

{% endtab %}
{% endtabs %}


# Testing the chatbot

Preview how the chatbot works before deploying it to production.

To run a test on the chatbot flow that you create, you need to click on the "Test bot" button.

Doing this will open a drawer from the right with your chatbot flow.

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

You can even test from a certain point in the chatbot flow, by hovering on the action block and click the "Test" button. This will help you skip the blocks are working fine, allowing you to only test what's changed.

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

{% hint style="info" %}
After testing the bot, make sure to click on **DEPLOY** to publish the current version of the chatbot flow.
{% endhint %}


# Chat logs

The Logs feature allows you to see detailed information for every interaction that occurs with your bot.

Each log captures events such as user queries, bot responses, AI model details, latency, and message flow — helping you debug, analyze, and optimize your bot’s performance.

You can view these logs in two places:

* **Test Bot page**: Click “View Logs” to see a chronological record of each message exchange while testing your bot.

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

* **Live Chat page**: Click context menu > View logs to view real-time logs for ongoing or completed conversations with users.

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

These insights help you understand how your bot is interpreting queries, what responses are being generated, and how tokens or AI credits are being used.

{% hint style="info" %}
**NOTE**: Logs are stored for a 90 day period.
{% endhint %}


# Publishing agents

<br>


# Website

You can instantly launch your chatbot to your website with one click on WotNot.

Follow the steps mentioned below if you are looking to add the WotNot chatbot on your website, webpage or web application.

{% embed url="<https://youtu.be/ixXpaJI3pGY?si=oXpD-GY9JTQNeClD>" %}

## Installing the chat bubble

To install the chat bubble on all the pages of your website, follow these steps:

### Step 1: Copy the code snippet

* Goto Settings > Web > Installation
* Enter the domain where you want to launch your chatbot
* Copy the "Widget installation code"

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

{% hint style="info" %}
**NOTE:**

Each WotNot account only supports one domain.&#x20;

Sub-domains are allowed. Like blog.wotnot.io, app.wotnot.io etc.
{% endhint %}

### Step 2: Paste the code snippet on your website

Copy the JS Snippet provided in this section, and paste it anywhere in your website's code between the \<body> ... \</body> tags.&#x20;

You must include the snippet on every page you want your Chatbot to appear on.

{% hint style="info" %}
**If you DO NOT see your bot on your website:**

* Check if the bot status is "Active" i.e. switch is turned on.
* Check if your bot has a deployed version. If not, deploy it once.
  {% endhint %}

## Installing an iframe

Embeds the chat widget inside a section of a webpage. To install an iframe:

1. Goto Bot builder
2. Choose the 3 dots menu of the bot you want to iframe
3. Choose "Embed"&#x20;
4. Copy and paste the iframe code on your webpage

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

The iframe code consists of the following:

{% code title="//Sample Iframe code" overflow="wrap" %}

```javascript
<iframe width="640" height="480" src="https://embed.wotnot.io/KYi3WCJkk9if101023723428bvMtch1n/bot/cJWQqh5anku8082500522107fJTkw94W?display_header=false&history_retention=false" frameborder="0"></iframe>
```

{% endcode %}

**Width and height** — you can adjust these to meet your webpage needs.

**display\_header** — you can configure if you want to show/hide the chatbot header.

**history\_retention** — you can configure to retain the chat history on page refresh, or always start a new conversation.

## Inject data into the chatbot <a href="#inject-data-into-the-chatbot" id="inject-data-into-the-chatbot"></a>

If you want to send external data to the chatbot, you can use this option. This is pretty useful if your use case involves the chatbot being installed inside a post-login environment where the bot is supposed to have context of the user talking to it (i.e. name, email, plan, account id etc.)

{% embed url="<https://www.loom.com/share/fdb974a916004066aff4e555999e0318?sid=629fc26b-2639-4491-a305-d3e0c9cf15da>" %}

### Using Query params <a href="#using-query-params" id="using-query-params"></a>

With this method, when the WotNot snippet is loaded on the website for the first time, the defined query params and their values will be stored in the WotNot variable.

For example, if your URL is the following`www.wotnot.io?cust_id=1234&plan=9896`

You can choose to store the values of `cust_id` and `plan` on the trigger action block.

<figure><img src="https://help.wotnot.io/~gitbook/image?url=https%3A%2F%2F360969599-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FsrMxU8nO3RjusUiYuXBB%252Fuploads%252FFcGmWsh3vcRFCRd6bGsH%252FCleanShot%25202024-06-08%2520at%252011.38.13.png%3Falt%3Dmedia%26token%3D5a79f128-c032-4cf3-935a-5c002f00075d&#x26;width=768&#x26;dpr=4&#x26;quality=100&#x26;sign=85312dad&#x26;sv=2" alt=""><figcaption></figcaption></figure>

### Using JSON <a href="#using-json" id="using-json"></a>

With this method, you can inject a JSON payload inside the WotNot’s code snippet and map the objects to be stored in the trigger action block.

To do this you need to add the following object with your desired fields in the WotNot code snippet

```javascript
data-session-payload='{"field1": "value", "field2: "value"}
```

Now, let's take an example to understand this.

Assume you are using the chatbot in your web app and you already know who is the user initiating the chat. For your agents to be aware of the user details, you can add their name, email, customer\_id, plan, etc. to the WotNot code snippet.

{% code overflow="wrap" %}

```javascript
<script src="" data-session-payload='{"name": "Charles", "phone": "8164848686"}' defer></script>
```

{% endcode %}

We have stored the “name” and “phone" fields to WotNot variables on the trigger action block.

![](https://help.wotnot.io/~gitbook/image?url=https%3A%2F%2F360969599-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FsrMxU8nO3RjusUiYuXBB%252Fuploads%252FdpN4xZDKrAJ0DB5IOTK8%252FCleanShot%25202024-06-08%2520at%252011.45.53.png%3Falt%3Dmedia%26token%3D1b4bcdc4-03fa-40bf-b1eb-ef58f17cb389\&width=768\&dpr=4\&quality=100\&sign=76ddbc96\&sv=2)

{% hint style="info" %}
**NOTE**:

* WotNot reads this object only once when the code snippet is fired. Sending data after the code snippet loads will not be read.
* Dynamically add the data-session-payload object to the WotNot code snippet
  {% endhint %}

{% hint style="info" %}
**NOTE:**

Use the following object paths to store the selected button's text, payload, or text message in a variable within the trigger block for WhatsApp Meta Cloud.

* For selected button's payload
  * entry\[0]\['changes']\[0].value.messages\[0].button.payload
* For selected button's text
  * entry\[0]\['changes']\[0].value.messages\[0].button.text
* For a text message
  * entry\[0]\['changes']\[0].value.messages\[0].text.body
    {% endhint %}


# WordPress

## Step 1: Copy the code snippet

* Goto Settings > Web > Installation
* Enter the domain where you want to launch your chatbot
* Copy the "Widget installation code"

<figure><img src="/files/1hsHi5uGOId5mj081nAw" alt=""><figcaption></figcaption></figure>

## Step 2: Adding the code on WordPress

### Using a plugin

1. Go to WordPress Dashboard > Plugins > Add New.
2. Search and install Insert [Headers and Footers](https://wordpress.org/plugins/insert-headers-and-footers/).
3. Click Install Now, then Activate the plugin.
4. Navigate to Settings > Insert Headers and Footers.
5. Paste your WotNot chatbot script into the Scripts in Header section.
6. Click Save to apply the changes.
7. If the chatbot does not appear immediately, try purging your website cache. This may be required if you're using a caching plugin or a CDN like Cloudflare.

### Using Elementor

**Every page Installation**

1. Navigate to Elementor > Custom Code (Pro version required).
2. Click Add New.
3. Name your script (e.g., Chatbot).
4. Paste the chatbot script.
5. Set Location to Head and Condition to Entire Site.
6. Click Publish.

**Page-Specific Installation**

1. Edit the page using Elementor.
2. Add an HTML widget.
3. Paste your chatbot script.
4. Save and update the page.


# Framer

## Step 1: Copy the code snippet

* Goto Settings > Web > Installation
* Enter the domain where you want to launch your chatbot
* Copy the "Widget installation code"

<figure><img src="/files/1hsHi5uGOId5mj081nAw" alt=""><figcaption></figcaption></figure>

## Step 2: Add the code on Framer

### Installing on all pages

1. Open your website project on Framer
2. Goto Settings > Site Settings > General
3. Scroll down to "Custom code" and paste the code under "Start of \<body> tag".
4. Click "Save" to apply the changes
5. "Publish" your site to view the bot on your webpage

<figure><img src="/files/9cu2AxfbY6EXxbiOzbWW" alt=""><figcaption></figcaption></figure>

### Installing on selected pages

* Open your website project on Framer
* Goto Settings > Page settings > select the page
* Scroll down to "Custom code" and paste the code under "Start of \<body> tag".
* Click "Save" to apply the changes
* "Publish" your site to view the bot on your webpage

<figure><img src="/files/1EyFzLenRZVN3CcYeZsN" alt=""><figcaption></figcaption></figure>


# Google Tag Manager

## Step 1: Copy the code snippet

* Goto Settings > Web > Installation
* Enter the domain where you want to launch your chatbot
* Copy the "Widget installation code"

<figure><img src="/files/1hsHi5uGOId5mj081nAw" alt=""><figcaption></figcaption></figure>

## Step 2: Adding the code on Google Tag Manager

1. Login to your Tag Manager account
2. Click "Add a new tag"
3. Click tag configuration and select "Custom HTML"

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXcc39WikWSkol3yv4aQBWtrxXhz87ZNXAwFdzo2KcuOAJZBqWWXvVrfiRRniuedzSWX47E4NLUfDFdd_kj3wUotPJCLIvU6qpauZZD1vmZbOZ3xb24NcAr-pW-QZSAtsjlqnQHv3Q?key=wyUY9-x1mWHKiucbFcJhly8U" alt=""><figcaption></figcaption></figure>

4. Paste the widget code here
5. Click trigger and choose "All pages"&#x20;

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXd0DrNqH4MqhLloZ_s2yInbDiNCeArFtbfxn9hdY9YeMgUVmh3T4uM8kjg_12x38p3U9yNrP9rpiSuJpS9XS965u2hMFwmTlrbE_e3lV8jxjBlNqwoE3QhnuKijDpS68vHQWjgYvw?key=wyUY9-x1mWHKiucbFcJhly8U" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
**NOTE**:&#x20;

You may create a trigger to only show the chatbot on a few pages.
{% endhint %}


# Squarespace

## Step 1: Copy the code snippet

* Goto Settings > Web > Installation
* Enter the domain where you want to launch your chatbot
* Copy the "Widget installation code"

<figure><img src="/files/1hsHi5uGOId5mj081nAw" alt=""><figcaption></figcaption></figure>

## Step 2: Adding the code on Squarespace

### On the entire website

In-order to embed the chatbot on entire website, you can follow the following steps;&#x20;

1. Go to Settings > Advanced > Code Injection&#x20;
2. Scroll down until you see 'Footer' section
3. Paste the WotNot code snippet in the 'Footer' section&#x20;

### On a single page&#x20;

In-order to embed the bot on single page, you can follow the following steps;&#x20;

1. Go to 'Channel Configuration -> Web -> Configuration'&#x20;
2. Copy the WotNot 'Code Snippet'&#x20;
3. Go to desired page where you want to embed the bot
4. Hover and select the page setting (menu gear against the page name)&#x20;
5. Under the page settings screen, select 'Advanced'&#x20;
6. Click on 'Page Header Code Injection'&#x20;
7. Paste the snippet in the block editor
8. Click on 'Save' to apply changes

###


# Webflow

## Step 1: Copy the code snippet

* Goto Settings > Web > Installation
* Enter the domain where you want to launch your chatbot
* Copy the "Widget installation code"

<figure><img src="/files/1hsHi5uGOId5mj081nAw" alt=""><figcaption></figcaption></figure>

## Step 2: Adding the code on Webflow

1. Goto website account on Webflow
2. From the menu, select "Site settings"

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXfqxMwdKEcHUqx99H2lX-ueWXaKGoFA7XH5kHhR69-PC5dz-ev08NQJeE0XvDptZ-KWGdWQ9LZeXQMGsm-CvfNxTV6oyUAXli3MGS12Z0Gzi2ARF2h2lkk8DLHeXJwINuBJj1CW9g?key=wyUY9-x1mWHKiucbFcJhly8U" alt=""><figcaption></figcaption></figure>

3. Select "Custom code"

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXd9OHuGsDYNk3xvx1CnBILjni1PFSIh1VqVFKgPdjf--d1vtvlBeJoR2inCQmINRt5gr9sv1Uage0l-PT9SbYWmSvZVatrziMTQuM0ow3T_84B1XZ-J-rFh77uDQcZZ6pCnovNbjQ?key=wyUY9-x1mWHKiucbFcJhly8U" alt=""><figcaption></figcaption></figure>

4. Paste the WotNot code snippet under the "Head code" section and save changes.
5. Publish the changes


# Shopify

## Step 1: Copy the code snippet

* Goto Settings > Web > Installation
* Enter the domain where you want to launch your chatbot
* Copy the "Widget installation code"

<figure><img src="/files/1hsHi5uGOId5mj081nAw" alt=""><figcaption></figcaption></figure>

## Step 2: Adding the code on Shopify

1. Login and goto Admin dashboard
2. Select "Online Store" > Pages (Choose the pages you want to add)
3. Once the page opens, look for a small “< >” source code icon at the top-right of the content editor and click it.
4. Now, paste your WotNot chatbot code into the HTML code area.\
   After pasting it, click the Save button.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXeH_a3dLOG09soMCDpp0WioNhPCSsRRx3yY-_U-oLZ44ZYVaeerpTwlavLr2FSsZlNuhomT-r06a6xREVY7YHfNMIwFEy6eoVgByMf9HOZ1M4MCM714xkbsO8jIE1oqEUCrXKzsaw?key=wyUY9-x1mWHKiucbFcJhly8U" alt=""><figcaption></figcaption></figure>

5. Click the source code icon again to go back to the normal editor view. You should now see a preview of your chatbot on the page.
6. Your chatbot is now added to your Shopify site!


# Wix

## Step 1: Copy the code snippet

* Goto Settings > Web > Installation
* Enter the domain where you want to launch your chatbot
* Copy the "Widget installation code"

<figure><img src="/files/1hsHi5uGOId5mj081nAw" alt=""><figcaption></figcaption></figure>

## Step 2: Adding the code on Wix

1. Click on the "Design Site" button in the top-right corner to open the Wix Editor.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXeh9JOKA0Voz3r6ksGNAwV5JB0z6_yDn8oCH7M-cw0Ef2BMIs0Kcu2SPNIiV3nfCat7SFkkaBvwyv1PHSD0JoPvbmXAOC80132fw3V4UoiZeByeo89eV60K0Jy80Y3YAPxNU5rYaw?key=wyUY9-x1mWHKiucbFcJhly8U" alt=""><figcaption></figcaption></figure>

2. Scroll to the section of your website where you want the chatbot to appear.
3. Click the “+” (Add Elements) button on the left sidebar.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXfAdc75ZbbPHCdeFGCSLRzwZB99qRaY7sjVLr1GteTEjhwpsGhG9yuS1B1p2wKhlTsYQzN7t4wyXUIYevRkj3fzB1eIJjbSfX5rZqpKKblZsLo6n6QYKeyOiaDjoLMTMHuUwz4vtQ?key=wyUY9-x1mWHKiucbFcJhly8U" alt=""><figcaption></figcaption></figure>

4. Scroll down and click on “Embed Code”.

   Then select “iTunes Button” and choose “Custom Code”.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXdeK5ACLqranXtMH9LNCeHbZaR_s7UAgp3O0LiGCLrSnMxJRTaxEVQ9WXeITEUKqDEjfwu7TKXOq2PWeOtBtSKeooJt1tLppvXh0gWvzyW3EgImRPWldiLNE0I3Lf-8A2r_mIGc0w?key=wyUY9-x1mWHKiucbFcJhly8U" alt=""><figcaption></figcaption></figure>

5. Click on “+ Add Custom Code” in the top-right corner.

   Paste your WotNot chatbot embed code into the code editor.
6. Under “Add Code to Pages”, choose whether to add the chatbot to all pages or select specific ones.

   Under “Place Code In”, select where you want the code to be placed (e.g., “Body - end”).
7. Click "Apply" to save your changes.


# WhatsApp

Launching your chatbot on your WhatsApp account is a slightly complicated process.&#x20;

First, you need to get the WhatsApp Business API from a Meta approved BSP. Supported BSPs on WotNot are:

1. Meta
2. 360Dialog
3. GupShup
4. Twilio
5. TechAlpha

To learn more about getting a WhatsApp API, [read this article](/deploy/whatsapp-business-api/getting-a-whatsapp-api).

{% embed url="<https://youtu.be/YZoNanw4jxo?si=n15Gq8ELUeuzSlK6>" %}

Once you receive a API from a BSP, follow these steps:

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>Meta</td><td></td><td></td><td><a href="/pages/VZzzyOs2kedEqz6sRyGF">/pages/VZzzyOs2kedEqz6sRyGF</a></td></tr><tr><td>360Dialog</td><td></td><td></td><td><a href="/pages/KQbokzSB6nmLDXb1BEyd">/pages/KQbokzSB6nmLDXb1BEyd</a></td></tr><tr><td>Twilio</td><td></td><td></td><td><a href="/pages/9iwvIYmIDreSvShRRjE3">/pages/9iwvIYmIDreSvShRRjE3</a></td></tr><tr><td>GupShup</td><td></td><td></td><td><a href="/pages/TXofloHxhg5niDlOkpYg">/pages/TXofloHxhg5niDlOkpYg</a></td></tr><tr><td>TechAlpha</td><td></td><td></td><td><a href="/pages/NOoo9BnBZoijUAGohz6S">/pages/NOoo9BnBZoijUAGohz6S</a></td></tr></tbody></table>


# Meta

Meta is a bit complicated, as it involves navigating across multiple pages.

1. Goto Settings > Channel Configuration > WhatsApp > Configuration
2. Click “Create a configuration”
3. Enter the “Phone number”
4. Navigate to Facebook developer portal
   1. Open the “App” that you created for WhatsApp API
   2. Copy “App ID” from the header
5. From the navigation menu on the left,&#x20;
   1. Goto WhatsApp > API Setup
   2. Copy “Phone number ID”
   3. Copy “WhatsApp Business Account ID”
6. Paste the “Permanent token” (Learn how)
7. Finally, paste all the copied values on the WotNot configuration screen and hit “Save”.
8. Test by sending “Hi” to your WhatsApp number


# 360Dialog

1. Goto Settings > Channel Configuration > WhatsApp > Configuration
2. Click “Create a configuration”
3. Enter the phone number
4. Choose “360dialog Cloud” from the list
5. Enter the “API key” from your [360dialog account](https://hub.360dialog.com/auth/login)
6. Hit “Save”&#x20;
7. Test by sending “Hi” to your WhatsApp number

{% hint style="info" %}
WotNot also supports 360Dialog on-prem. Choose this option on the Provider dropdown.&#x20;
{% endhint %}


# Twilio

* Goto Settings > Channel Configuration > WhatsApp > Configuration
* Click “Create a configuration”
* Enter the “Phone number”
* Login to your [Twilio account](http://twilio/login)
* Navigate to the Account > Settings
  1. Copy the “Account SID”
  2. Copy the “Auth token”
* Paste these values on the WotNot configuration screen and hit “Save”
* Test by sending “Hi” to your WhatsApp number


# GupShup

* Goto Settings > Channel Configuration > WhatsApp > Configuration
* Click “Create a configuration”
* Enter the “Phone number”
* [Login](https://login.gupshup.io/login) to your GupShup account
* Open the App you created for WhatsApp
* Goto Settings
  1. Copy “App name”
  2. Copy “App ID”
  3. Copy “App API Key”
* Paste these values on the WotNot configuration screen and hit “Save”
* Test by sending “Hi” to your WhatsApp number


# TechAlpha

* Goto Settings > Channel Configuration > WhatsApp > Configuration
* Click “Create a configuration”
* Enter the “Phone number”
* Reach out to your Account Manager at TechAlpha
  1. Copy the “WhatsApp Business Account ID”
  2. Copy the “API Key”
* Paste these values on the WotNot configuration screen and hit “Save”
* Test by sending “Hi” to your WhatsApp number


# Instagram

To launch the chatbot you built for “Instagram” channel, follow these steps:

{% embed url="<https://youtu.be/GJo7OoFO8QI?si=lL_5Q0_adGxxWwc->" %}

## Step 1: Connect your Instagram business account

Goto Settings > Channels > Instagram and click “Connect to Instagram”.

Doing this opens the Instagram pop-up asking for permissions, here make sure you choose all the permissions listed.&#x20;

Once all permissions are granted the popup will close, and you will see your Instagram business page listed here.

<figure><img src="/files/96taIkgVzQBdRdmQgvDE" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
You will require “Admin” permissions to be able to connect the chatbot to a Instagram business page. If you do not see any pages, it means that you do not have the required permissions.
{% endhint %}

## Step 2: Connect the chatbot to the Instagram page

Now, open the Instagram bot that you built and click on the 'Trigger' action block.

On the right panel, choose the Instagram business page that you trigger the chatbot on.

Once selected, hit 'Deploy' to save this configuration. Post this all messages sent to your Instagram page will be handled by your chatbot.

<figure><img src="/files/8phVDGEcFEdeJKNnyRMT" alt=""><figcaption></figcaption></figure>

### Use keyword trigger to run a specific bot

Easily launch specific bots on your Instagram channel using keyword triggers.&#x20;

Define words or phrases like “GET OFFER” or “START”, and when a user sends them, the assigned bot will instantly take over the conversation.&#x20;

Perfect for running campaigns, sharing offers, or guiding users into the right flow.

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

### Getting an error connecting your Instagram account

If you're experiencing an issue when trying to link your Instagram account

To resolve this, please follow these steps:

1. Log out from your Instagram account in all devices.
2. Clear your browser cache and cookies.
3. Log back in to your Instagram account.

Reference to [Zapier – Session Invalid Instagram Login](https://community.zapier.com/automation-after-hours-tour-115/400-session-invalid-instagram-login-44924).


# Facebook Messenger

To launch the chatbot you built for “Facebook Messenger” channel, follow these steps:

{% embed url="<https://youtu.be/7NnDBgnUBe8?si=4it_u3IIYBx-W9KE>" %}

## Step 1: Connect your Facebook account

Goto Settings > Channels > Facebook Messenger and click “Connect to Facebook”.

<figure><img src="/files/9Lu6SQL7ayqEtV7FXb68" alt=""><figcaption></figcaption></figure>

Doing this opens the Facebook pop-up asking for permissions, here make sure you choose all the pages that you may want to add the chatbot to.&#x20;

{% hint style="info" %}
You will require “Admin” permissions to be able to connect the chatbot to a Facebook page. If you do not see any pages in the list, it means that you do not have the required permissions.
{% endhint %}

## Step 2: Connect the chatbot to the Facebook page

Once your Facebook account is successfully configured, the Facebook pop-up will auto-close, and you will be able to see all the Facebook pages in the current screen.

Click on the “Expand” icon to be able to choose the chatbot you want to connect.&#x20;

Once done, hit “Save” and your chatbot is now live on Facebook Messenger.&#x20;

{% hint style="info" %}
If the bot's status is turned on then you will see <mark style="color:green;">ACTIVE</mark> written on that page & if the bot is turned off, you will see <mark style="color:red;">INACTIVE</mark>\
\
If there is no status, that means that no bot is not connected to the page
{% endhint %}


# SMS

To launch your chatbot on your SMS channel, first, you need to get APIs from our list of SMS partners:

1. Twilio
2. TechAlpha

{% embed url="<https://youtu.be/-cP-SF9zRy4?si=uutkdDwuw-C8MSAg>" %}

Once you receive the SMS APIs, follow the steps mentioned below:

## Twilio

* Goto Settings > Channels > SMS > Configuration
* Click “Create SMS configuration”
* Enter the “Phone number”
* Login to your [Twilio account](http://twilio/login)
* Navigate to the Account > Settings
  1. Copy the “Account SID”
  2. Copy the “Auth token”
* Paste these values on the WotNot configuration screen and hit “Save”
* Test by sending “Hi” to your SMS number

***

## TechAlpha

{% hint style="info" %}
Contact sales: <sales@techalphagroup.com>
{% endhint %}

1. Goto Settings > Channels > SMS > Configuration
2. Click “Create SMS configuration”
3. Enter the “Phone number”
4. Reach out to your Account Manager at TechAlpha
   1. Copy the “Username”
   2. Copy the “Password”
   3. Copy the “ANI”
   4. Copy the "MMS account username"
   5. Copy the "MMS account password"
5. Paste these values on the WotNot configuration screen and hit “Save”
6. Test by sending “Hi” to your SMS number


# Mobile app


# Android SDK

This guide explains how to install and configure WotNot’s Android SDK to embed the native chat widget inside your Android app.

## Step 1: Add the SDK Package

### 1: Add dependency

Add the WotNot SDK and required Android libraries in your app-level `build.gradle` file:

```
dependencies {
    // WotNot Chatbot SDK
    implementation 'io.wotnot.android:chatbotsdk:1.0.3'

    // Required Android dependencies
    implementation 'androidx.core:core-ktx:1.13.1'
    implementation 'androidx.appcompat:appcompat:1.7.0'
    implementation 'com.google.android.material:material:1.12.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.8.7'
    implementation 'androidx.fragment:fragment-ktx:1.8.5'
    implementation 'androidx.activity:activity-ktx:1.9.3'
}
```

### 1.2: Sync Gradle

In Android Studio:

* File → Sync Project with Gradle Files
* Or use the toolbar sync button

### Step 3: Add required permissions

Add the following permissions to your `AndroidManifest.xml`:

```xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
```

## Step 2: SDK Configuration

### 2.1 Create a WidgetConfig

The SDK requires a `WidgetConfig` object to initialize the chat widget.

```kotlin
import com.widget.sdk.data.model.WidgetConfig
import com.widget.sdk.utils.VisitorKeyManager

// Initialize VisitorKeyManager first (optional, but recommended)
VisitorKeyManager.initialize(context)

val config = WidgetConfig(
    botId = "YOUR_BOT_ID",                    // Required: Your bot ID
    visitorKey = “VISITOR_KEY”, // Required: Visitor key (auto-generated if not set)
    accountKey = "YOUR_ACCOUNT_KEY",          // Required: Your account key
    accountId = YOUR_ACCOUNT_ID,              // Required: Your account ID (Int)
    
    // Optional Configurations
    isMessageAvatarVisible = true,            // Show/hide message avatars (default: true)
    isHeaderVisible = true,                   // Show/hide headers (default: true)
    conversationKey = null,                   // Optional: Pre-existing conversation key
    dataSessionPayload = null,                // Optional: Additional data payload
    badRequestMessage = "Bad request. Please check your configuration.",
    botNotActiveMessage = "Bot is not active."
)
```

#### Where to find these credentials

**YOUR\_BOT\_ID** — open the bot you want to embed, and copy the bot\_id from the URL.

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

**YOUR\_ACCOUNT\_ID** — goto Settings > Account Settings and copy the account\_id from the URL.

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

**YOUR\_ACCOUNT\_KEY** — Goto the bot list screen, open the embed option from context menu and copy the highlighted key.

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

#### Visitor key notes

* If you don’t provide a visitorKey, the SDK auto-generates and persists one.
* It’s recommended to provide the unique visitor key, as it helps uniquely identify each visitor and maintain their chats and session history.

***

### Step 2: Initialize the SDK

Call `wn.initialize()` in your Application class or MainActivity.

```kotlin
import com.widget.sdk.wn

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        try {
            val config = WidgetConfig(
                botId = "YOUR_BOT_ID", //String
                visitorKey = "VISITOR_KEY_32_BIT_LONG", //String
                accountKey = "YOUR_ACCOUNT_KEY", //String
                accountId = "YOUR_ACCOUNT_ID" //Number
            )

            wn.initialize(this, config)

        } catch (e: Exception) {
            Log.e("SDK", "Initialization failed: ${e.message}")
        }
    }
}
```

{% hint style="warning" %}

### IMPORTANT

* Always initialize the SDK before launching any chat screen.
* All required fields (botId, visitorKey, accountKey, accountId) must be present.
* The SDK validates config and throws an exception on failure.
  {% endhint %}

***

## Step 3: Launching the chat screen

The SDK provides built-in functions to launch chat screens.

All functions optionally support `useAnimation = true`.

### 3.1 Conversation list screen

```kotlin
// Without animation
wn.launchConversationList(this)

// With animation (bottom-to-top slide)
wn.launchConversationList(this, useAnimation = true)
```

### 3.2 Conversation detail screen without key

```
// Launch without animation
wn.launchConversationDetailScreenWithoutKey(this)

// Launch with animation
wn.launchConversationDetailScreenWithoutKey(this, useAnimation = true)

```

### 3.2 Ending the conversation

```
// Ends the conversation, so a new conversation can be started
wn.endChat()
```

## Step 4: Theme customization

You can fully customize the look of the chat widget using `WidgetTheme`.

### 4.1 Theme options

<table><thead><tr><th width="192.69879150390625">Property</th><th width="227.533935546875">Setter</th><th width="99.999267578125">Default</th><th>Used For</th></tr></thead><tbody><tr><td>accentPrimary</td><td>setAccentPrimary()</td><td>#0075ff</td><td>Buttons, headers, links</td></tr><tr><td>userMessageTextColor</td><td>setUserMessageTextColor()</td><td>#FFFFFF</td><td>User message text &#x26; timestamp</td></tr><tr><td>accentSecondary</td><td>setAccentSecondary()</td><td>#d4e3ffff</td><td>Secondary accents</td></tr><tr><td>gray8</td><td>setGray8()</td><td>#F2F5F8</td><td>Bot message background</td></tr><tr><td>botMessageTextColor</td><td>setBotMessageTextColor()</td><td>#1C1C1E</td><td>Bot text &#x26; timestamp</td></tr><tr><td>failurePrimary</td><td>setFailurePrimary()</td><td>#FF0000</td><td>Error messages</td></tr><tr><td>failureSecondary</td><td>setFailureSecondary()</td><td>#FFEBEE</td><td>Error states</td></tr></tbody></table>

### 4.2 Applying a theme

```kotlin
// After SDK initialization
val customTheme = WidgetTheme.Builder()
    .setAccentPrimary(Color.parseColor("#0075ff"))
    .setBackgroundColor(Color.WHITE)
    .build()

wn.setTheme(customTheme)
```

## Complete integration example

Below is a full working example combining all steps:

```kotlin
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import com.widget.sdk.wn
import com.widget.sdk.data.model.WidgetConfig
import com.widget.sdk.theme.WidgetTheme
import com.widget.sdk.utils.VisitorKeyManager
import android.graphics.Color
import android.util.Log

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Step 1: Initialize VisitorKeyManager
        VisitorKeyManager.initialize(this)

        // Step 2: Build WidgetConfig
        val config = WidgetConfig(
            botId = "YOUR_BOT_ID",
            visitorKey = VisitorKeyManager.getVisitorKey(),
            accountKey = "YOUR_ACCOUNT_KEY",
            accountId = YOUR_ACCOUNT_ID,
            isMessageAvatarVisible = true,
            isHeaderVisible = true
        )

        // Step 3: Initialize SDK
        try {
            wn.initialize(this, config)
        } catch (e: Exception) {
            Log.e("SDK", "Initialization failed: ${e.message}")
            return
        }

        // Step 4: Apply Theme
        val customTheme = WidgetTheme.Builder()
            .setAccentPrimary(Color.parseColor("#0075ff"))
            .setBackgroundColor(Color.WHITE)
            .setTextPrimaryColor(Color.parseColor("#1C1C1E"))
            .build()

        wn.setTheme(customTheme)

        // Step 5: Setup Launch Buttons
        findViewById<Button>(R.id.btnNewChat).setOnClickListener {
            wn.launchNewConversation(this, useAnimation = true)
        }

        findViewById<Button>(R.id.btnConversationList).setOnClickListener {
            wn.launchConversationList(this, useAnimation = true)
        }
    }
}
```


# iOS SDK

This guide walks you through installing, configuring, and launching the WotNot chat widget natively in your iOS app (SwiftUI or UIKit).

## 1. Installing the SDK

### Step 1: Add the SDK via Swift Package Manager (Recommended)

Supports Xcode 13+ for both SwiftUI and UIKit projects.

#### 1. Open Xcode → Add SPM Package

File → Add Packages…

#### 2. Enter the SDK Package URL

In the dialog box that appears, paste the WotNotSDK repository URL into the search bar/text field.

<https://github.com/wotnotbot/ios-sdk>

#### 3. Configure dependency rule

* Rule: *Up to Next Major Version*
* Set the version to the required SDK version

{% hint style="info" %}
This ensures you automatically get minor improvements without risking breaking changes.
{% endhint %}

#### 4. Add the package

Click Add Package, and Xcode will fetch and integrate the SDK.

### Step 2: Add required permissions

Add the following permission to your `Info.plist`:

```xml
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
```

### Step 3: Import the SDK

Add this import wherever you use the widget:

```swift
import SwiftUI
import WotNotSDK
```

## 2. Configuration

### Step 1: Create a WidgetConfig

This `WidgetConfig` object contains your bot credentials and optional UI settings.

```swift
import WotNotSDK

let config = WidgetConfig(
    botId: "YOUR_BOT_ID",                    // Required: Your bot ID
    visitorKey: "VISITOR_KEY",                // Required: Visitor key (32-bit long string)
    accountKey: "YOUR_ACCOUNT_KEY",           // Required: Your account key
    accountId: YOUR_ACCOUNT_ID,               // Required: Your account ID (Int)
    
    // Optional Configuration
    conversationKey: nil,                     // Optional: Pre-existing conversation key
    isMessageAvatarVisible: true,             // Show/hide message avatars (default: true)
    isHeaderVisible: true,                   // Show/hide headers (default: true)
    dataSessionPayload: nil,                 // Optional: Additional data payload
    badRequestMessage: "Bad request. Please check your configuration.",
    botNotActiveMessage: "Bot is not active."
)
```

#### Where to find these credentials

**YOUR\_BOT\_ID** — open the bot you want to embed, and copy the bot\_id from the URL.

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

**YOUR\_ACCOUNT\_ID** — goto Settings > Account Settings and copy the account\_id from the URL.

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

**YOUR\_ACCOUNT\_KEY** — Goto the bot list screen, open the embed option from context menu and copy the highlighted key.

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

### Step 2: Initialize the SDK

Initialize inside your `App` struct or `View`

```swift
import SwiftUI
import WotNotSDK

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onAppear {
                    initializeSDK()
                }
        }
    }
    
    private func initializeSDK() {
        Task {
            do {
                let config = WidgetConfig(
                    botId: "YOUR_BOT_ID",
                    visitorKey: "VISITOR_KEY_32_BIT_LONG",
                    accountKey: "YOUR_ACCOUNT_KEY",
                    accountId: "YOUR_ACCOUNT_ID"
                )
                
                try await wn.initialize(config: config)

            } catch {
                print("SDK Initialization failed: \(error.localizedDescription)")
            }
        }
    }
}
```

{% hint style="warning" %}
**IMPORTANT NOTES:**

* SDK must be initialized before launching any chat UI.
* Initialization is asynchronous (async throws), so use Task or an async context.
* All required fields (i.e. `botID`, `visitorKey`, `accountKey`, `accountID`) must be provided.
* The SDK performs validation and throws errors if credentials are invalid.
  {% endhint %}

## 3. Launching chat screens (SwiftUI)

The SDK provides several functions that return SwiftUI `View` objects. These can be presented using `NavigationLink`, `.sheet()`, or other SwiftUI presentation methods.

### 3.1 Launch conversation list (Full Screen)

Opens the conversation in a full screen mode.

```swift
do {
    let view = try wn.launchConversationListFullScreen()
    // Present the view
} catch {
    print("Failed to launch: \(error)")
}
```

### 3.2 Launch conversation list (Bottom Sheet)

Opens the conversation list in a bottom sheet.

```swift
do {
    let view = try wn.launchConversationListBottomSheet()
    // Present bottom sheet
} catch {
    print("Failed to launch: \(error)")
}
```

### 3.3 Launch conversation detail (Without Passing a Key)

Opens the conversation detail screen without passing a key. Useful when history retention logic is handled by bot preferences.

```swift
Task {
    do {
        let key = try await wn.openConversationDetailScreenWithoutKey()
        let view = try wn.launchConversation(conversationId: key)
        // Present the view
    } catch {
        print("Failed to open: \(error)")
    }
}
```

## 4. Theme customization

Customize colors for bubbles, text, accents, and error states.

### 4.1 Theme colors reference

<table><thead><tr><th width="192.69879150390625">Property</th><th width="227.533935546875">Setter</th><th width="99.999267578125">Default</th><th>Used For</th></tr></thead><tbody><tr><td>accentPrimary</td><td>accentPrimary: Color(...)</td><td>#0075ff</td><td>Buttons, headers, links</td></tr><tr><td>userMessageTextColor</td><td>visitorMessageTextColor: Color(...)</td><td>#FFFFFF</td><td>User message text &#x26; timestamp</td></tr><tr><td>botMessageBackgroundColor</td><td>botMessageBackgroundColor: Color(...)</td><td>#F2F5F8</td><td>Bot message bubble background color</td></tr><tr><td>botMessageTextColor</td><td>botMessageTextColor: Color(...)</td><td>#1C1C1E</td><td>Bot text &#x26; timestamp</td></tr><tr><td>accentSecondary</td><td>accentSecondary: Color(...)</td><td>#d4e3ffff</td><td>Secondary accents</td></tr><tr><td>gray8</td><td>setGray8()</td><td>#F2F5F8</td><td>Bot message background</td></tr><tr><td>failurePrimary</td><td>failurePrimary: Color(...)</td><td>#FF0000</td><td>Error messages</td></tr><tr><td>failureSecondary</td><td>failureSecondary: Color(...)</td><td>#FFEBEE</td><td>Error states</td></tr></tbody></table>

### 4.2 Applying a custom theme

Apply the theme after initialization:

```swift
Task {
    do {
        // 1. Initialize SDK (omitted for brevity)
        // try await wn.initialize(config: config)
        
        // 2. Apply custom theme
        let customTheme = WidgetTheme(
            // Right side (user)
            accentPrimary: Color(red: 0/255, green: 117/255, blue: 255/255), // #0075ff
            visitorMessageTextColor: Color.white,
            
            // Left side (bot)
            botMessageBackgroundColor: Color(red: 242/255, green: 245/255, blue: 248/255), // #F2F5F8
            botMessageTextColor: Color(red: 28/255, green: 28/255, blue: 30/255), // #1C1C1E
            
            // Accent colors
            accentSecondary: Color(red: 212/255, green: 227/255, blue: 255/255), // #d4e3ff
            
            // Failure colors
            failurePrimary: Color.red
        )
        
        try wn.setTheme(customTheme)
    } catch {
        print("SDK initialization or theme setup failed: \(error)")
    }
}

```

## Complete integration example

Below is a streamlined full example.

```swift
import SwiftUI
import WotNotSDK

@main
struct WotNotDemoApp: App {
    
    init() {
        Task { await initializeSDK() }
    }
    
    var body: some Scene {
        WindowGroup {
            // Embed ContentView in a NavigationView for proper UI context
            NavigationView {
                ContentView()
            }
        }
    }
    
    // Asynchronous SDK Initialization Function
    private func initializeSDK() async {
        do {
            let config = WidgetConfig(
                botId: "YOUR_BOT_ID",
                visitorKey: "YOUR_VISITOR_KEY",
                accountKey: "YOUR_ACCOUNT_KEY",
                accountId: "YOUR_ACCOUNT_ID"
            )
            
            // Set a basic theme (optional, for visual consistency)
            let theme = WidgetTheme(
                primaryBlue: Color.blue,
                primaryRed: Color.red
            )
            
            try wn.setTheme(theme)
            try await wn.initialize(config: config)

        } catch {
            print("SDK Initialization Error: \(error.localizedDescription)")
            // The ContentView status rows will reflect the failed state
        }
    }
}

// --- 2. ContentView: Launches Bottom Sheet Directly ---
struct ContentView: View {
    @State private var showingAlert = false
    @State private var alertMessage = ""
    
    var body: some View {
        VStack(spacing: 30) {
            
            // Header
            VStack(spacing: 16) {
                Image(systemName: "message.circle.fill")
                    .font(.system(size: 80))
                    // Use theme color for header icon
                    .foregroundColor(wn.getTheme()?.primaryBlue ?? Color.blue) 
                
                Text("WotNot SDK")
                    .font(.largeTitle)
                    .fontWeight(.bold)
                
                Text("Chat Integration")
                    .font(.subheadline)
                    // Use theme color for secondary text
                    .foregroundColor(wn.getTheme()?.textSecondaryColor ?? Color.secondary)
            }
            
            // SDK Status
            VStack(spacing: 12) {
                StatusRow(
                    title: "SDK Status",
                    status: wn.initializationStatus.description,
                    isSuccess: wn.isSDKInitialized()
                )
                
                StatusRow(
                    title: "Validation Status",
                    status: wn.validationStatus.description,
                    isSuccess: wn.isBotValidated()
                )
            }
            
            // Open Bottom Sheet Button - Simple SDK method call!
            Button(action: {
                openBottomSheetConversationList()
            }) {
                HStack {
                    Image(systemName: "list.bullet.rectangle")
                        .font(.title3)
                    
                    Text("Open Conversation List")
                        .fontWeight(.semibold)
                }
                // Use theme color for foreground and background
                .foregroundColor(wn.getTheme()?.white ?? Color.white)
                .frame(maxWidth: .infinity)
                .padding()
                .background(wn.getTheme()?.primaryBlue ?? Color.blue)
                .cornerRadius(12)
            }
            // Button is disabled until the SDK confirms initialization
            .disabled(!wn.isSDKInitialized()) 
            
            Spacer()
        }
        .padding()
        .navigationTitle("SDK Home")
        .alert("Alert", isPresented: $showingAlert) {
            Button("OK") { }
        } message: {
            Text(alertMessage)
        }
    }
    
    // Function to launch the SDK UI
    private func openBottomSheetConversationList() {
        do {
            // Directly calls the SDK's presentation function
            try wn.presentBottomSheetConversationList()
        } catch {
            alertMessage = "Failed to open conversation list: \(error.localizedDescription)"
            showingAlert = true
        }
    }
}


// --- 3. Helper Structs and Extensions ---

// Status Row Component
struct StatusRow: View {
    let title: String
    let status: String
    let isSuccess: Bool
    
    var body: some View {
        HStack {
            Text(title)
                .fontWeight(.medium)
            Spacer()
            Text(status)
                .foregroundColor(wn.getTheme()?.textSecondaryColor ?? Color.secondary)
            Image(systemName: isSuccess ? "checkmark.circle.fill" : "xmark.circle.fill")
                .foregroundColor(isSuccess ? (wn.getTheme()?.primaryGreen ?? Color.green) : (wn.getTheme()?.primaryRed ?? Color.red))
        }
        .padding()
        .background(wn.getTheme()?.lightGray ?? Color(.systemGray6))
        .cornerRadius(12)
    }
}

// Extension for InitializationStatus
extension InitializationStatus {
    var description: String {
        switch self {
        case .notInitialized:
            return "Not Initialized"
        case .initialized:
            return "Initialized"
        case .initializationFailed(let error):
            return "Failed: \(error)"
        @unknown default:
            return "Unknown"
        }
    }
}

// Extension for ValidationStatus
extension ValidationStatus {
    var description: String {
        switch self {
        case .notValidated:
            return "Not Validated"
        case .validating:
            return "Validating..."
        case .validated:
            return "Validated"
        case .validationFailed(let error):
            return "Failed: \(error)"
        @unknown default:
            return "Unknown"
        }
    }
}

```




---

[Next Page](/llms-full.txt/1)

