Handover API

The handover functionality in Kindly allows customer support agents to temporarily replace the bot as the user's conversation partner. From the user's perspective, the conversation with the support agent takes place in the same chat window as the conversation with the bot. While the support agent is in the chat, the bot will not respond to the user's messages, and when the support agent leaves the chat, the bot will return to the conversation.

Support agent handover can be requested by the user by clicking on a handover request button, which can be easily added to a reply like any other button. When a user requests a takover, customer support agents are notified in the platform, and can easily take over the conversation from the Conversations section in Kindly. However, if your organization has a customer service center using a different platform, it is possible to set up a connection between your current platform and Kindly to enable handover requests to be handled through your current platform.

As there does not exist a standarized protocol for this kind of functionality, you will need to do some development to create an intermediary service that can talk to both the Kindly API and the customer support platform's API. This document describes the protocol for communication between Kindly and the intermediate service.

The Handover API was previously named Takeover API, meaning event and endpoint names still reflect the legacy name.

Architecture suggestions

To handle the communication between Kindly and your customer support platform, Kindly can either communicate directly with the customer support platform or with a intermediary service that forwards messages between the platforms.

Compatibility application

The compatibility application sits between Kindly and the support platform, relaying messages from one service to the other, changing the format as necessary for the recipient.

Compatibility plugin

An alternative solution could be to implement the compatibility application as a feature in the customer support platform itself, for example as a plugin.

Configuration

In order to use handover with an external platform, you will need to go to the handover settings section in Kindly and change the configuration.

  1. Select external handover mode

  2. Set the webhook URL

    The webhook URL is where events will be POSTed by Kindly.

  3. Get API key

    The API key is only for handover services, and can't be used for other Kindly functions that use API keys.

    If the key is compromised, it is possible to generate a new key, revoking the old key in the process.

  4. Set values for messages & business hours

    You must set certain messages that the bot will reply with when the user requests handover and when the support agent enters and leaves the chat.

    You can also choose to use the Business hours feature. By doing so, requests for handover outside of your business hours will not be forwarded to the webhook, but the bot will inform the user that handover is closed.

    If you wish, you can disable the business hours settings in Kindly and manage out-of-hours responses via the compatibility app.

Protocol

The protocol is based on HTTP requests between Kindly and your service, where each type of request has a unique event name. When Kindly sends events to your service, they will all arrive at your webhook, and your service will have to decide how to handle them based on the event specified in the payload.

When you send events from your service to Kindly, you can use different API endpoints for different events. Kindly will respond with a payload that includes an event field to confirm that the request was received and that the parameters were valid.

REQUESTING TAKEOVER

When a user clicks on a request handover button in the chat, your service will receive a REQUESTING TAKEOVER event. Your service should respond with 200 OK to Kindly, then forward the request to the customer support platform.

Received payload example:

{
    "event": "REQUESTING TAKEOVER",
    "bot": {
        "id": 123,
        "name": "Test Bot"
    },
    "chat": {
        "_links": {
          "self": "https://bot.kindly.ai/api/v1/chats/5af029421a5ca5141a1ee117"
        },
        "id": "5af029421a5ca5141a1ee117",
        "language": "en",
        "source": "web"
    },
    "user": {
        "id": "53616c7465645f5f463b889c43950414f6e08e05442771013db5d3a3953bcedc4ede6c072f91f90f1c7dee18f232f478"
    }
}

TAKEOVER STARTED

When a customer service agent is ready to enter the chat, your service should POST to api/v2/takeover/start with the relevant bot_id and chat_id. If the API key and the IDs are valid, Kindly will respond with event: TAKEOVER STARTED. The bot will inform the user that an agent is entering the chat and will no longer respond to the user's messages, until handover is ended by the agent.

The "sender" field is optional and not be displayed in the legacy version of the chat bubble.

Example POST to Kindly:

curl --request POST \
  --url https://bot.kindly.ai/api/v2/takeover/start \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{
    "bot_id": 123,
    "chat_id": "5af029421a5ca5141a1ee117",
    "sender": {
        "name": "Customer support",
        "avatar": "https://api.adorable.io/avatars/285/Support.png"
    }
}'

Response:

{
    "event": "TAKEOVER STARTED",
    "chat_id": "5af029421a5ca5141a1ee117",
    "chatmessage_id": "5af17d2ee9ad1d7d0b3bf03b"
}

TAKEOVER ENDED

When the customer service agent is ready to let the bot take over again, your service should POST to api/v2/takeover/end with the relevant bot_id and chat_id. If the API key, and the ids are valid, Kindly will respond with event: TAKEOVER ENDED. The bot will inform the user that the agent has left the chat, and will resume responding to the user's messages.

The "sender" field is optional and not be displayed in the legacy version of the chat bubble.

Example POST to Kindly:

curl --request POST \
  --url https://bot.kindly.ai/api/v2/takeover/end \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{
    "bot_id": 123,
    "chat_id": "5af029421a5ca5141a1ee117",
    "sender": {
        "name": "Customer support",
        "avatar": "https://api.adorable.io/avatars/285/Support.png"
    }
}'

Response:

{
    "event": "TAKEOVER ENDED",
    "chat_id": "5af029421a5ca5141a1ee117",
    "chatmessage_id": "5af04d54fba4333215e4a3c7"
}

MESSAGE SENT TO USER

Messages from the support platform to the user can be forwarded to the user by POSTing to api/v2/takeover/message/. In addition to the message, you should also send a name and an avatar in the sender field, indicating to the user that the message is from an agent, not from the bot.

Optionally, you can also use buttons like in other API methods, for instance to share a link with the user.

If the POST to Kindly was correct, Kindly will respond with event: MESSAGE SENT TO USER.

POST to Kindly:

curl --request POST \
  --url https://bot.kindly.ai/api/v2/takeover/message/ \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{
    "bot_id": 123,
    "chat_id": "5af029421a5ca5141a1ee117",
    "message": "This is a message from a customer support agent.",
    "sender": {
        "name": "Customer support",
        "avatar": "https://api.adorable.io/avatars/285/Support.png"
    }
}'

Response:

{
    "event": "MESSAGE SENT TO USER",
    "chat_id": "5af029421a5ca5141a1ee117",
    "chatmessage_id": "5af04d48fba4333215e4a3c6"
}

MESSAGE FROM USER

When the chat is taken over, and the user sends a message, it will be forwarded to your webhook as a MESSAGE FROM USER event. Your service should respond 200 OK to Kindly, then forward it to the customer support platform.

Received payload example:

{
    "bot": {
        "id": 123,
        "name": "Test Bot"
    },
    "chat": {
        "_links": {
          "self": "https://bot.kindly.ai/api/v1/chats/5af029421a5ca5141a1ee117"
        },
        "id": "5af029421a5ca5141a1ee117",
        "language": "en",
        "source": "web"
    },
    "event": "MESSAGE_FROM_USER",
    "message": "hi!",
    "user": {
        "id": "53616c7465645f5f463b889c43950414f6e08e05442771013db5d3a3953bcedc4ede6c072f91f90f1c7dee18f232f478"
    }
}

USER LEAVING

In certain cases we can detect that the user has left the chat:

  • The user restarts the chat

  • The user closes the tab or browser on a bot with the Resume conversation if user leaves site and then comes back option set to Never

Note for the last case, however, that if you are testing within the Kindly platform this option is overridden and set to Forever. To test the chat as a user it is recommended to use the demo page:.

In this case Kindly will send a request to your service with the event USER ENDED TAKEOVER. The payload will thus be something like

{
    "event": "USER ENDED TAKEOVER",
    "bot": ...,
    "chat": ...,
    "user": ...
}

HMACs

The messages that are sent from Kindly are authenticated using HMACs signed with the same key you use when sending messages to Kindly. See this page for more info about authenticating HMACs.

Fetching the chatlog

When Kindly sends a REQUESTING TAKEOVER event, one of the attached values is a link to another API where you can fetch the entire chat log between the bot and the user. You can use this to show the log to the agent before starting handover, so that the user won't need to repeat themselves.

In order to use the chatlog API you need an API key with permission to read chat logs (under Connect -> API Keys). Read more on the Chat Log API.

Example GET request:

curl https://bot.kindly.ai/api/v1/chats/5add983db55cf96cc2c3f5e3 -H 'authorization: Bearer API_KEY'

System messages

It is also possible to use api/v2/takeover/message/ for other messages than those being forwarded from the customer support agent. For instance, you could have the service tell the user their place in the queue when it changes.

curl --request POST \
  --url https://bot.kindly.ai/api/v2/takeover/message/ \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{
    "bot_id": 123,
    "chat_id": "5af029421a5ca5141a1ee117",
    "message": "You are now number 3 in the queue.",
    "sender": {
        "name": "Customer service queue",
        "avatar": "https://api.adorable.io/avatars/285/Queue.png"
    }
}'

Last updated