Introduction

Hello there! 👋

This article explains the basic concepts behind the chat.io APIs.

The chat.io APIs let you handle online conversations. It means you can send and receive messages, exchange events and perform other actions within the chat.io system.

The communication protocol handles various kinds of information: rich messages, events or nested data structures.

APIs Overview

There are two primary APIs available:

  • Agent API
    to send chat messages as an agent,
  • Customer API
    to send chat messages as a customer (visitor) .

Both APIs have much in common. However, their use cases are different, which is reflected in their methods.

See the diagram below to understand the basic flow of information between the services. The animation explains the basic chat flow: from logging in, through starting a chat, to sending events.

Basic usage

The most basic use cases of the chat.io APIs are listing and performing chats. This section describes the general concept of both. For working examples in JavaScript, Go and Python head to the API references:

Listing chats

When you log in to the Agent or Customer API you will receive one of the following reponses:

  • chats_summary
  • last_chats_summary

These objects contain chat and thread IDs. The IDs can be used to retrieve chat history.

If you want to retrieve chats from the customer perspective, you should use Customer API. When you log in as an agent, you should go with Agent API.

Performing a chat

You can start a chat both as a customer and as an agent. If you are an agent you can also join a chat. When you are in a chat you can send events to it via send_event method.

Currently all new events and chats are sent to all agents within the license. In the future, scopes will define which groups of users have access to chats/events and other types of data.

Key Concepts

Chats and threads

A chat is a single chat conversation. Each chat is divided into threads. Every thread may contain events. You can find more about the events in the Events section.

Multiple users can participate in a single chat. Every user can have multiple chats at the same time.

New threads within a single chat are created on the server side. To learn more about the creation algorithm, see Rules and conditions.

Chats and Threads

Rules and conditions

  1. Only one of the threads within a chat may be the active thread. When you send events to a chat, they will be added to the active thread. Only the last thread can be the active one.

  2. Chats are not continuous, which means that there can be time gaps between the threads.

  3. When there is no active thread in the chat, sending an event to that chat will start a new thread. For instance, when the last active thread has been closed, sending an event to the same chat will open up a new thread. The annotation event is an exception here: it will be added at the end of the last thread.

  4. When a new chat is started, a new thread is created within this chat.

  5. The algorithm which decides how the chats are distributed between the agents is called routing. It’s documented in the Routing section.

Events

Events are portions of data which can be sent to a chat (via send_event). There are the following event types:

Incoming event push will inform you about events sent to a chat (on both agent and customer side).

Pushes

The events coming from the server to the client are called pushes. They are used to keep the application state up-to-date. Pushes are available only in the websocket transport.

If a chat or a thread is created or closed when you’re logged in, server push messages will be sent (in both Customer and Agent APIs).

Common event fields

Here are the fields shared by all events:

name puprose filled by type
id the ID of the event server string
custom_id the ID that you can set for your own purposes client string
order events with a lower order will appear first server int
author_id the ID of the sender of an event server string
text the payload that you can send whithin an event (for example message content) client string
recipients the posibble values are "all"(default) and "agents" client string
properties event properties client properties object

Event types

Message

A message is the most common event type. It allows you to send textual content to other chat users. Its data format looks like this:

{
  "id": "0affb00a-82d6-4e07-ae61-56ba5c36f743",
  "custom_id": "12345-bhdsa",
  "order": 1,
  "type": "message",
  "author_id": "b7eff798-f8df-4364-8059-649c35c9ed0c",
  "timestamp": 1473433500,
  "text": "hello there",
  "recipients": "all",
  "properties": {
    // "Properties" object
  }
}

Annotation

This event adds an annotation to the last thread. Keep in mind that sending an annotation cannot start a new thread (even if there is no active thread in a chat). It always goes to the latest thread that already exists.

{
  "id": "0affb00a-82d6-4e07-ae61-56ba5c36f743",
  "custom_id": "12312.301231238591134",
  "order": 1,
  "type": "annotation",
  "author_id": "b7eff798-f8df-4364-8059-649c35c9ed0c",
  "timestamp": 1473433500,
  "text": "Sample annotation",
  "annotation_type": "rating",
  "properties": {
    // "Properties" object
  }
}

annotation_type - type of the annotation. This field cannot be empty and is customizable, you can have your own annotation types (in the example above we used “rating” type)

Filled form

A filled form is an event containing data from a form. Let’s take a look at a practical example:

Filled Form

To send the data from this form, you can use the filled form event. In this example we introduce all currently available field types:

{
  "id": "0affb00a-82d6-4e07-ae61-56ba5c36f743",
  "custom_id": "12312.301231238591134",
  "order": 4,
  "type": "filled_form",
  "author_id": "b7eff798-f8df-4364-8059-649c35c9ed0c",
  "timestamp": 1473433500,
  "properties": {
    // "Properties" object
  }
  "fields": [{
      "type": "text",
      "name": "name",
      "label": "Your name:",
      "required": true,
      "value": "John Doe"
    },
    {
      "type": "email",
      "name": "email",
      "label": "E-mail:",
      "required": true,
      "value": "john.doe@gmail.com"
    },
    {
      "name": "Chat window title",
      "type": "title",
      "label": "Let's talk!",
    },
    {
      "name": "Chat window form info",
      "type": "information",
      "label": "Before we start, we'd like to know a few details about you.",
    }]
}

System message

A system message is an event generated by the server. It does not have “author_id”, “custom_id” and “properties” fields.

{
  "id": "0affb00a-82d6-4e07-ae61-56ba5c36f743",
  "order": 1,
  "type": "system_message",
  "timestamp": 1473433500,
  "text": "Mike joined the chat",
  "system_message_type": "agent_joined"
}

System messages can be triggered by a user action within a chat or by a router (router messages are covered in the Routing section). Each action triggers a system message with a different system_message_type and a different text message:

system_message_type text
agent_joined <agent_name> joined the chat
agent_left <agent_name> left the chat
manual_archived <agent_name> archived the chat

File

File event indicates that a file has been uploaded. It can be only generated by the server when the send file Customer API method is called.

{
  "id": "0affb00a-82d6-4e07-ae61-56ba5c36f743",
  "custom_id": "12312.301231238591134",
  "order": 1,
  "type": "file",
  "author_id": "b7eff798-f8df-4364-8059-649c35c9ed0c",
  "timestamp": 1473433500,
  "properties": {
    // "Properties" object
  }
  "name": "image25.png",
  "url": "https://domain.com/asdsfdsf.png",
  "content_type": "image/png",
  "size": 123444,
  "width": 640,
  "height": 480
}

The size field indicates the file size in bytes. It is limited to 10 MB.
The content-type field can contain any MIME media type.
Width and height fields are present only for "image/png", "image/gif" and "image/jpg" content-types. There is no limitations for width and height.

Custom event

A custom event is an event with a 100% custom payload. It can be used to send any JSON.

{
  "id": "0affb00a-82d6-4e07-ae61-56ba5c36f743",
  "custom_id": "12312.301231238591134",
  "order": 1,
  "type": "custom",
  "author_id": "b7eff798-f8df-4364-8059-649c35c9ed0c",
  "timestamp": 1473433500,
  "content": {
    //any json object
  },
  "properties": {
    // "Properties" object
  }
}

Routing

Routing is the process of assigning chats to agents. The primary goal of the routing mechanism is to distribute chats to all available agents at a single license .

This section describes chat.io default product routing. In the future it will be possible to create a custom routing mechanism and run it on chat.io platform.

In chat.io product it’s not possible for a customer to have multiple chats within a single license. The conversation within a license (i.e. a company) is continuous from the customer’s perspective and it’s not necessary to split it into multiple chats.

Agents are assigned chats either automatically or manually, depending on the routing settings.

Automatic routing

Automatic routing

Manual routing

Manual routing

System messages

While the routing switches states (as shown in the diagrams above), the router will send system messages (see Events section) to a chat.

Overview

Message text System message type
Chat is unassigned because <agent_name> hasn't replied in <minutes_number> minutes routing.unassigned
Chat assigned to <agent_name> because <agent_name> hasn't replied in <minutes_number> minutes routing.assigned
Chat archived due to long inactivity routing.archived
Chat is idle due to <minutes_number> minutes of inactivity routing.idle
Chat archived because customer was banned by <agent> for N days customer_banned

System messages: rounting.assigned

General info

Message text System message type
Chat assigned to <agent_name> routing.assigned

Use cases

Case Routing type
A new chat is started and an agent is available automatic
An agent has left the chat and another agent is available automatic
An agent got available for an unassigned chat automatic

System messages: rounting.unassigned

General info

Message text System message type
Chat is unassigned routing.unassigned

Use cases

Case Routing type
An agent has left the chat and there were no other agents are available automatic
No free agent slots available automatic
A chat is unassigned manual

BOT Agents

BOT Agents are similar to their human counterparts. They can join chats and post messages, but they also have a special feature: you can attach webhooks to them.

What can BOT Agents do?

BOT Agents are created with the Configuration API. Then, BOT Agents communicate with the Agent API by the Web API or websocket connection, listening to incoming webhooks (or pushes) and reacting to them.

Post messages and react to keywords

BOT Agents can react to specific keywords during chats. For example, if you set the keyword to “pizza”, the BOT Agent will join the chat where the keyword was used, send “Pizza is on the way!” to all agents in the chat and then leave the chat.

Differences between BOT Agents and regular Agents

  • You can’t log in to a BOT Agent account.
  • You can’t set password for a BOT Agent account.
  • BOT Agents don’t have email addresses. Their agent_id is a random hash.
  • You can assign webhooks to BOT Agents as a communication channel for pushes.

Technical notes

  • BOT Agents use the Agent API to post messages to chats as Agents, so you can use them to write your own integrations.

  • When logged in, a BOT Agent is connected to the agent SSO access token that creates and updates the BOT. A BOT Agent is logged out when the access token is revoked.

  • Each BOT Agent is a resource owned by an application (identified by client_id) in the Developers Console. “My BOT Agents” are the BOTs owned by the application with a given client_id.

Configuring BOT agents

You can create and manage BOT agents using the Configuration API.

Currently chat.io doesnt's support group management. All agents belong to group 0 by default.

A sample BOT Agent

We have created a sample Pizza Bot to illustrate the concept of BOT Agents.

Webhooks

Chat.io provides a number of webhooks. You can manage them via the Configuration API.

Properties

Properties are simple key-value storages. They can be set within a chat, a thread or an event. They appear in these objects in the following format:

{
    "properties": {
        "routing": {
            "pinned": true,
            "count": 3
        }
    }
}

In this example routing is a namespace, while pinned and count are properties names.

Configuration

Properties are configurable via Configuration API. They can be created whithin a license and they are grouped in namespaces, which help distinguish which property belongs to a given integration. Your namespace will be named after your application id.

There are several things that you can configure:

Property types

There are three property types:

  • int (int32)
  • bool
  • string
  • tokenized_string

Note about tokenized_string

tokenized_string is string that is split to tokens before indexing in our search engine. This can be useful if you want to use that property as a filter in the methods like get_archives.

Property locations

Properties can be set within three locations:

  • chat
  • thread
  • event

You can configure access to properties within those locations. You can, for example, create a property that is visible for agents within a chat and a thread, and not visible within an event. For more details, see Configuration API docs.

Property domain

Property domain is a set of values that property can be assigned to.

Property domain can be configured in 2 different ways:

  • by defining a set of values allowed in this property explicitly (for example [1, 2, 3])
  • by defining a range, all values in this range are allowed in this property, this setting works only for numeric types (for example range from 1 to 3)

Example

In this example we want to use properties to create a basic chat rating. For this purpose we need two properties: rating_score and rating_comment. Those properties should be writable by customer, and readable by agent within a chat.

First we need to create our properties configuration using Configuration API.

curl -v https://api.chat.io/configuration/properties/create_properties \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer c5e4f61e1a6c3b1521b541bc5c5a2ac5" \
    -X POST -d '
{
    "rating_score" : {
        "type" : "int",
        "locations" : {
            "chat" : {
                "access" : {
                    "agent" : {
                        "read" : true,
                        "write" : false
                    },
                    "customer" : {
                        "read" : true,
                        "write" : true
                    }
                }
            }
        }
    },
    "rating_comment" : {
        "type" : "string",
        "locations" : {
            "chat" : {
                "access" : {
                    "agent" : {
                        "read" : true,
                        "write" : false
                    },
                    "customer" : {
                        "read" : true,
                        "write" : true
                    }
                }
            }
        }
    }
}'

Now you have properties rating_score and rating_comment in namespace named after your application id. If you don’t know your application id you can check it with this request:

curl https://accounts.labs.chat.io/info -H "Authorization: Bearer c5e4f61e1a6c3b1521b541bc5c5a2ac5"
{
    "access_token":"c5e4f61e1a6c3b1521b541bc5c5a2ac5",
    "client_id":"58737b5829e65621a45d598aa6f2ed8e",
    ...
}

client_id is your application id.

Now, you can set those properties within the existing chat from customer perspective via agent/customer api method update_chat_properties

curl -v https://api.chat.io/customer/v0.5/action/update_chat_properties \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer c5e4f61e1a6c3b1521b541bc5c5a2ac5" \
    -X POST -d ' \
    {
        "chat_id": "a0c22fdd-fb71-40b5-bfc6-a8a0bc3117f5",
        "properties": {
            "58737b5829e65621a45d598aa6f2ed8e": {
                "rating_score": 10,
                "rating_comment": "This guy is a support hero, he helped me a lot."
            }
        }
    }'

And they will appear from the agent’s perspective either in chat object as a return element (in the sample response from get_archives method)

{
	"chats": [{
		"chat": {
			"id": "a0c22fdd-fb71-40b5-bfc6-a8a0bc3117f5",
			"users": [
				// array of "User" objects
			],
			"thread": {
				// "Thread" object
			},
            "properties": {
                "58737b5829e65621a45d598aa6f2ed8e": {
                    "rating_score": 10,
                    "rating_comment": "This guy is a support hero, he helped me a lot."
                }
                //other namespaces
            }
		}
	}],
	"pagination": {
		"page": 1,
		"total": 3
	}
}

or in push chat_properties_updated

{
    "chat_id": "a0c22fdd-fb71-40b5-bfc6-a8a0bc3117f5",
	"properties": {
		"58737b5829e65621a45d598aa6f2ed8e": {
            "rating_score": 10,
            "rating_comment": "This guy is a support hero, he helped me a lot.",
        }
	}
}

Glossary

agent
a person who handles incoming chats; usually a member of a customer service or support team
chat
the main conversation object; every chat contains threads
customer
a visitor; a person who visits a website;
routing
the process of assigning chats to agents
thread
a part of the chat object; there are multiple threads within a single chat