Introduction
Our Analytics JSON API allows you to easily integrate Userlike with your favorite third-party tracking software, CRM, or your own custom tracking solutions. Each API provides a download interface for all our tracked Analytics events, allowing you to enhance our data with your own. Also, you can create customized reports that incorporate your company setup or build aggregations and generate new insights by combining multiple data vectors. Below you find our general documentation as well as a detailed description of each API resource available. Please note that based on the timeouts defined for chats, some events might appear in your API requests with a short delay.
We prepared some cURL-based examples. With the help of the cURL tool you can test drive our API quickly from the command line. This should give you a straightforward understanding how to use our API.
Resource endpoints
Currently, the following resource endpoints are available via the Analytics JSON API:
https://api.userlike.com
Resource endpoints | Description | Allowed methods |
/api/um/v1/analytics/um_conversation_first_message/ | Received first message in a conversation | GET |
/api/um/v1/analytics/um_conversation_first_message_assignment_update/ | Received first message in a conversation | GET |
/api/um/v1/analytics/um_conversation_duration/ | Conversation duration, guaranteed to be unique per conversation | GET |
/api/um/v1/analytics/um_chat_messages_total/ | Number of messages sent and received in a conversation session | GET |
/api/um/v1/analytics/um_chat_messages_ct/ | Messages sent in a conversation session | GET |
/api/um/v1/analytics/um_chat_messages_co/ | Messages received in a conversation session | GET |
/api/um/v1/analytics/um_operator_status/ | Change of operator status | GET |
/api/um/v1/analytics/um_operator_slot_usage/ | Operator chat slot utilization | GET |
/api/um/v1/analytics/um_operator_response_time_first/ | First response time in a conversation session | GET |
/api/um/v1/analytics/um_operator_response_time_first_service_time/ | First response time in a conversation session (service times considered) | GET |
/api/um/v1/analytics/um_operator_response_time_conversation_first/ | First response time in the first session of a conversation | GET |
/api/um/v1/analytics/um_operator_response_time_conversation_first_service_time/ | First response time in the first session of a conversation (service times considered) | GET |
/api/um/v1/analytics/um_operator_response_time/ | Response times per operator | GET |
/api/um/v1/analytics/um_operator_response_time_service_time/ | Response times per operator (service times considered) | GET |
/api/um/v1/analytics/um_operator_response_time_to_unanswered_session_first/ | First response time in an unanswered conversation session with no previous operator messages | GET |
/api/um/v1/analytics/um_operator_response_time_to_unanswered_session_first_service_time/ | First response time in an unanswered conversation session with no previous operator messages (service times considered) | GET |
/api/um/v1/analytics/um_operator_response_time_to_unanswered_session/ | Response time in any unanswered conversation session | GET |
/api/um/v1/analytics/um_operator_response_time_to_unanswered_session_service_time/ | Response time in any unanswered conversation session (service times considered) | GET |
/api/um/v1/analytics/um_conversation_rating/ | A contact leaves a conversation rating, the actual value will be returned | GET |
/api/um/v1/analytics/um_conversation_feedback/ | A contact leaves feedback | GET |
/api/um/v1/analytics/um_conversation_unanswered_live/ | A live conversation reaches the timeout without an operator’s reply | GET |
/api/um/v1/analytics/um_conversation_unanswered_ended/ | A conversation ends without without a single operator message | GET |
/api/um/v1/analytics/um_conversation_goal_reached/ | A conversation goal is reached | GET |
/api/um/v1/analytics/um_missed_opportunity/ | A contact tries to start a new conversation while no operator is available | GET |
/api/um/v1/analytics/um_conversation_topic/ | A topic or a combination of topics is changed for a conversation | GET |
/api/um/v1/analytics/um_conversation_topic_change/ | Topic(s) were changed for a conversation | GET |
/api/um/v1/analytics/um_conversation_pre_survey/ | A pre-conversation survey is answered | GET |
/api/um/v1/analytics/um_conversation_post_survey/ | A post-conversation survey is answered | GET |
/api/um/v1/analytics/um_contact_unique_visit/ | A unique visitor is identified via cookie and starts a conversation | GET |
/api/um/v1/analytics/um_contact_country/ | A contact starts or resumes a conversation, their country is tracked once | GET |
/api/um/v1/analytics/um_contact_browser/ | A contact starts or resumes a conversation, their browser is tracked once | GET |
/api/um/v1/analytics/um_contact_response_time_backchannel/ | Contact response time to offline replies from operators | GET |
/api/um/v1/analytics/um_contact_response_time_backchannel_service_time/ | Contact response time to offline replies from operators (service times considered) | GET |
/api/um/v1/analytics/um_conversation_category/ | A conversation starts, its status is tracked based on the availability status of operator and contact | GET |
/api/um/v1/analytics/um_conversation_part_category/ | A conversation starts, its state is tracked based on the availability status of operator and contact | GET |
/api/um/v1/analytics/um_chat_session_bot_forward_received/ | A chatbot reassigns a conversation, the event is attributed to the receiving operator. | GET |
You find the specifics of each resource further below, after our introduction of the Analytics JSON API’s general features.
API versioning
Currently we only offer one version of our Analytics JSON API:
/v1/
You can access all endpoints either without version scheme or as described above by explicitly using the version in the URLs like this:
/api/um/v1/analytics/um_conversation_duration/
/api/um/v1/analytics/um_chat_messages_total/
/api/um/v1/analytics/um_conversation_first_message/
/api/um/v1/analytics/um_conversation_first_message_assignment_update/
/api/um/v1/analytics/um_chat_messages_ct/
/api/um/v1/analytics/um_chat_messages_co/
/api/um/v1/analytics/um_operator_status/
/api/um/v1/analytics/um_operator_slot_usage/
/api/um/v1/analytics/um_operator_response_time_first/
/api/um/v1/analytics/um_operator_response_time_first_service_time/
/api/um/v1/analytics/um_operator_response_time_conversation_first/
/api/um/v1/analytics/um_operator_response_time_conversation_first_service_time/
/api/um/v1/analytics/um_operator_response_time/
/api/um/v1/analytics/um_operator_response_time_service_time/
/api/um/v1/analytics/um_operator_response_time_to_unanswered_session_first/
/api/um/v1/analytics/um_operator_response_time_to_unanswered_session_first_service_time/
/api/um/v1/analytics/um_operator_response_time_to_unanswered_session/
/api/um/v1/analytics/um_operator_response_time_to_unanswered_session_service_time/
/api/um/v1/analytics/um_conversation_rating/
/api/um/v1/analytics/um_conversation_feedback/
/api/um/v1/analytics/um_conversation_unanswered_live/
/api/um/v1/analytics/um_conversation_unanswered_ended/
/api/um/v1/analytics/um_conversation_goal_reached/
/api/um/v1/analytics/um_conversation_reopen/
/api/um/v1/analytics/um_missed_opportunity/
/api/um/v1/analytics/um_conversation_topic/
/api/um/v1/analytics/um_conversation_topic_change/
/api/um/v1/analytics/um_conversation_pre_survey/
/api/um/v1/analytics/um_conversation_post_survey/
/api/um/v1/analytics/um_contact_unique_visit/
/api/um/v1/analytics/um_contact_country/
/api/um/v1/analytics/um_contact_browser/
/api/um/v1/analytics/um_contact_response_time/
/api/um/v1/analytics/um_contact_response_time_service_time/
/api/um/v1/analytics/um_conversation_category/
/api/um/v1/analytics/um_conversation_part_category/
/api/um/v1/analytics/um_chat_session_bot_forward_received/
Future new versions will be described here and follow the naming scheme "v{integer}", for example:
/v2/
. Endpoint URLs without version scheme will always default to the latest version.Our APIs are constantly evolving, but we are striving to implement any new features in a backwards compatible way. If breaking changes are necessary, we will introduce a new API version. Examples for breaking changes are:
Removing, renaming, or moving API entities.Changing or removing functionality.Making optional parameters or properties mandatory.
Non-breaking changes, like new endpoints or new optional properties, can happen anytime.When we deprecate older versions of the API, we will provide at least 90 days of notice.
Authentication
All API requests must be authenticated with an API token, that means the API token must be passed as an authorization header with each request:
javascriptcurl --header "Authorization: e56fb4ac-f430-3cff-a297-d531f772edaf" \ "https://api.userlike.com/api/um/v1/analytics/um_operator_status/"
Userlike offers two types of authentication tokens: the “customer authentication token,” allowing access to the resources of all organizations, and the “organization authentication token,” allowing access to the resources of a single organization.
Organization authentication token
The organization authentication token gives you access to the resources of Analytics data of a single organization. You find it in your Dashboard under Chat tools > API token:
Customer authentication token
The customer authentication token gives you access to the resources of Analytics data for all organizations. You find it in your Dashboard under Account > API:
API rate limits
You can send up to 10 API requests per minutes to our Analytics API. After the resource limit is reached, you’ll receive a response with HTTP status code 429 (too many requests).
https://api.userlike.com
Resource (per organization) | Methods | combined requests/minute |
/api/um/v1/analytics/um_conversation_first_message/ | GET | 10 |
/api/um/v1/analytics/um_conversation_first_message_assignment_update/ | GET | 10 |
/api/um/v1/analytics/um_conversation_duration/ | GET | 10 |
/api/um/v1/analytics/um_chat_messages_total/ | GET | 10 |
/api/um/v1/analytics/um_chat_messages_ct/ | GET | 10 |
/api/um/v1/analytics/um_chat_messages_co/ | GET | 10 |
/api/um/v1/analytics/um_operator_status/ | GET | 10 |
/api/um/v1/analytics/um_operator_slot_usage/ | GET | 10 |
/api/um/v1/analytics/um_operator_response_time_first/ | GET | 10 |
/api/um/v1/analytics/um_operator_response_time_first_service_time/ | GET | 10 |
/api/um/v1/analytics/um_operator_response_time_conversation_first/ | GET | 10 |
/api/um/v1/analytics/um_operator_response_time_conversation_first_service_time/ | GET | 10 |
/api/um/v1/analytics/um_operator_response_time/ | GET | 10 |
/api/um/v1/analytics/um_operator_response_time_service_time/ | GET | 10 |
/api/um/v1/analytics/um_operator_response_time_to_unanswered_session_first/ | GET | 10 |
/api/um/v1/analytics/um_operator_response_time_to_unanswered_session_first_service_time/ | GET | 10 |
/api/um/v1/analytics/um_operator_response_time_to_unanswered_session/ | GET | 10 |
/api/um/v1/analytics/um_operator_response_time_to_unanswered_session_service_time/ | GET | 10 |
/api/um/v1/analytics/um_conversation_rating/ | GET | 10 |
/api/um/v1/analytics/um_conversation_feedback/ | GET | 10 |
/api/um/v1/analytics/um_conversation_unanswered_live/ | GET | 10 |
/api/um/v1/analytics/um_conversation_unanswered_ended/ | GET | 10 |
/api/um/v1/analytics/um_conversation_inactivity_action/ | GET | 10 |
/api/um/v1/analytics/um_conversation_goal_reached/ | GET | 10 |
/api/um/v1/analytics/um_conversation_reopen/ | GET | 10 |
/api/um/v1/analytics/um_missed_opportunity/ | GET | 10 |
/api/um/v1/analytics/um_conversation_topic/ | GET | 10 |
/api/um/v1/analytics/um_conversation_topic_change/ | GET | 10 |
/api/um/v1/analytics/um_conversation_pre_survey/ | GET | 10 |
/api/um/v1/analytics/um_conversation_post_survey/ | GET | 10 |
/api/um/v1/analytics/um_contact_unique_visit/ | GET | 10 |
/api/um/v1/analytics/um_contact_country/ | GET | 10 |
/api/um/v1/analytics/um_contact_browser/ | GET | 10 |
/api/um/v1/analytics/um_contact_response_time_backchannel/ | GET | 10 |
/api/um/v1/analytics/um_contact_response_time_backchannel_service_time/ | GET | 10 |
/api/um/v1/analytics/um_conversation_session_count/ | GET | 10 |
/api/um/v1/analytics/um_conversation_session_duration_live/ | GET | 10 |
/api/um/v1/analytics/um_conversation_session_duration_offline/ | GET | 10 |
/api/um/v1/analytics/um_conversation_session_duration_re_engage/ | GET | 10 |
/api/um/v1/analytics/um_conversation_status_duration/ | GET | 10 |
/api/um/v1/analytics/um_conversation_unassigned_duration/ | GET | 10 |
/api/um/v1/analytics/um_chat_session_manual_forward_live/ | GET | 10 |
/api/um/v1/analytics/um_chat_session_manual_forward_offline/ | GET | 10 |
/api/um/v1/analytics/um_chat_session_manual_forward_re_engage/ | GET | 10 |
/api/um/v1/analytics/um_chat_session_manual_forward_group_live/ | GET | 10 |
/api/um/v1/analytics/um_chat_session_manual_forward_group_offline/ | GET | 10 |
/api/um/v1/analytics/um_chat_session_manual_forward_group_re_engage/ | GET | 10 |
Filtering
You can filter the results of each resource’s endpoint. The filters you choose apply to all resources. Here we’ll highlight the details of each Analytics filter.
Organization filter
By default, the resources returned by all Analytics endpoints are returned for all organizations.
javascript# fetch operator status events for the defined organization curl --header "Authorization: e56fb4ac-f430-3cff-a297-d531f772edaf" \ "https://api.userlike.com/api/um/v1/analytics/um_operator_status/?organization_id=3" # Operator status events, for the current day { "results": [ { 'operator_group_id': 2, 'operator_id': 5, 'organization_id': 3, 'time': '2020-05-05T01:25:33', 'um_widget_id': [7, 8], 'value': None, 'value_str': 'offline', 'conversation_id': None, 'conversation_part_id': None, 'conversation_session_id': None 'is_chatbot_metric': False, 'human_interaction': None, 'chatbot_interaction': None, }, ... ] }
Widget filter
By default, the resources returned by all Analytics endpoints are returned for all Widgets.
javascript# fetch operator status events for the defined widget curl --header "Authorization: e56fb4ac-f430-3cff-a297-d531f772edaf" \ "https://api.userlike.com/api/um/v1/analytics/um_operator_status/?um_widget_id=7" # Operator status events, for the defined widget { "results": [ { 'operator_group_id': 2, 'operator_id': 5, 'organization_id': 3, 'time': '2020-05-05T01:25:33', 'um_widget_id': [7, 8], 'value': None, 'value_str': 'offline', 'conversation_id': None, 'conversation_part_id': None, 'conversation_session_id': None 'is_chatbot_metric': False, 'human_interaction': None, 'chatbot_interaction': None, }, ... ] }
Operator filter
By default, the resources returned by all Analytics endpoints are returned for all operators.
javascript# fetch operator status events for the defined operator curl --header "Authorization: e56fb4ac-f430-3cff-a297-d531f772edaf" \ "https://api.userlike.com/api/um/v1/analytics/um_operator_status/?operator_id=5" # Operator status events, the defined operator { "results": [ { 'operator_group_id': 2, 'operator_id': 5, 'organization_id': 3, 'time': '2020-05-05T01:25:33', 'um_widget_id': [7, 8], 'value': None, 'value_str': 'offline', 'conversation_id': None, 'conversation_part_id': None, 'conversation_session_id': None 'is_chatbot_metric': False, 'human_interaction': None, 'chatbot_interaction': None, }, ... ] }
Operator group filter
By default, the resources returned by all Analytics endpoints are returned for all operator groups.
javascript# fetch operator status events for the defined operator group curl --header "Authorization: e56fb4ac-f430-3cff-a297-d531f772edaf" \ "https://api.userlike.com/api/um/v1/analytics/um_operator_status/?operator_group_id=2" # Operator status events, for the defined operator group { "results": [ { 'operator_group_id': 2, 'operator_id': 5, 'organization_id': 3, 'time': '2020-05-05T01:25:33', 'um_widget_id': [7, 8], 'value': None, 'value_str': 'offline', 'conversation_id': None, 'conversation_part_id': None, 'conversation_session_id': None 'is_chatbot_metric': False, 'human_interaction': None, 'chatbot_interaction': None, }, ... ] }
Date and time filter
By default, the resources returned by all Analytics endpoints are returned for the current day. If only one of the date filters is used, it will default to that single day. The required format for all date filters is
YYYY-mm-dd
expected to be in UTC time zone.javascript# fetch operator status events for the defined day curl --header "Authorization: e56fb4ac-f430-3cff-a297-d531f772edaf" \ "https://api.userlike.com/api/um/v1/analytics/um_operator_status/?event_date=2020-05-05" # Operator status events, for the defined day { "results": [ { 'operator_group_id': 2, 'operator_id': 5, 'organization_id': 3, 'time': '2020-05-05T01:25:33', 'um_widget_id': [7, 8], 'value': None, 'value_str': 'offline' }, ... ] } # fetch operator status events for the defined day curl --header "Authorization: e56fb4ac-f430-3cff-a297-d531f772edaf" \ "https://api.userlike.com/api/um/v1/analytics/um_operator_status/?event_date_from=2020-05-05" # Operator status events, for the defined day { "results": [ { 'operator_group_id': 2, 'operator_id': 5, 'organization_id': 3, 'time': '2020-05-05T01:25:33', 'um_widget_id': [7, 8], 'value': None, 'value_str': 'offline' }, ... ] } # fetch operator status events for the defined day curl --header "Authorization: e56fb4ac-f430-3cff-a297-d531f772edaf" \ "https://api.userlike.com/api/um/v1/analytics/um_operator_status/?event_date_to=2020-05-05" # Operator status events, for the defined day { "results": [ { 'operator_group_id': 2, 'operator_id': 5, 'organization_id': 3, 'time': '2020-05-04T01:25:33', 'um_widget_id': [7, 8], 'value': None, 'value_str': 'offline' }, ... ] } # fetch operator status events for the defined daterange curl --header "Authorization: e56fb4ac-f430-3cff-a297-d531f772edaf" \ "https://api.userlike.com/api/um/v1/analytics/um_operator_status/?event_date_from=2020-05-05&event_date_to=2020-05-07" # Operator status events, for the defined daterange { "results": [ { 'operator_group_id': 2, 'operator_id': 5, 'organization_id': 3, 'time': '2020-05-05T01:25:33', 'um_widget_id': [7, 8], 'value': None, 'value_str': 'offline' }, ... ] }
If needed, the filters 'event_date_from' and 'event_date_to' can be enhanced with time filters in the format
YYYY-mm-ddTHH:MM:SS
. Please note that it is not possible to request data for a time period larger than 93 days with a single request.javascript# fetch operator status for the defined timerange curl --header "Authorization: e56fb4ac-f430-3cff-a297-d531f772edaf" \ "https://api.userlike.com/api/um/v1/analytics/um_operator_status/?event_date_from=2020-05-05T12:30:00&event_date_to=2020-05-07T12:00:00" # Operator status events, for the defined timerange { "results": [ { 'operator_group_id': 2, 'operator_id': 5, 'organization_id': 3, 'time': '2020-05-05T01:25:33', 'um_widget_id': [7, 8], 'value': None, 'value_str': 'offline', 'conversation_id': None, 'conversation_part_id': None, 'conversation_session_id': None 'is_chatbot_metric': False, 'human_interaction': None, 'chatbot_interaction': None, }, { 'operator_group_id': 2, 'operator_id': 5, 'organization_id': 3, 'time': '2020-05-05T01:25:33', 'um_widget_id': [7, 8], 'value': None, 'value_str': 'available', 'conversation_id': 13, 'conversation_part_id': 226, 'conversation_session_id': 221 'is_chatbot_metric': False, 'human_interaction': None, 'chatbot_interaction': None, }, ... ] }
Chatbot filter
By default, the resources returned by all Analytics endpoints are returned for operators.
If needed, the 'operator_mode' filter can be applied to limit the data set to only data points that have been logged while a human operator (operator_mode=human) or chatbot (operator_mode=bot) operator was involved. Please note that you cannot use this filter with multiple keywords.
javascript# fetch operator status events for all operators (default) curl --header "Authorization: e56fb4ac-f430-3cff-a297-d531f772edaf" \ "https://api.userlike.com/api/um/v1/analytics/um_operator_status/?operator_mode=hybrid" # Operator status events, the all operators { "results": [ { 'operator_group_id': 2, 'operator_id': 5, 'organization_id': 3, 'time': '2020-05-05T01:25:33', 'um_widget_id': [7, 8], 'value': None, 'value_str': 'offline', 'conversation_id': None, 'conversation_part_id': None, 'conversation_session_id': None 'is_chatbot_metric': False, 'human_interaction': None, 'chatbot_interaction': None, }, ... ] } # fetch operator status events for all human operators curl --header "Authorization: e56fb4ac-f430-3cff-a297-d531f772edaf" \ "https://api.userlike.com/api/um/v1/analytics/um_operator_status/?operator_mode=human" # Operator status events, the human operators { "results": [ { 'operator_group_id': 2, 'operator_id': 5, 'organization_id': 3, 'time': '2020-05-05T01:25:33', 'um_widget_id': [7, 8], 'value': None, 'value_str': 'offline', 'conversation_id': None, 'conversation_part_id': None, 'conversation_session_id': None 'is_chatbot_metric': False, 'human_interaction': None, 'chatbot_interaction': None, }, ... ] } # fetch operator status events for all chat_bot operators curl --header "Authorization: e56fb4ac-f430-3cff-a297-d531f772edaf" \ "https://api.userlike.com/api/um/v1/analytics/um_operator_status/?operator_mode=bot" # Operator status events, the chatbot operators { "results": [ { 'operator_group_id': 2, 'operator_id': 101, 'organization_id': 3, 'time': '2020-05-05T01:25:33', 'um_widget_id': [7, 8], 'value': None, 'value_str': 'offline', 'conversation_id': None, 'conversation_part_id': None, 'conversation_session_id': None 'is_chatbot_metric': True, 'human_interaction': None, 'chatbot_interaction': None, }, ... ] }
Combining filters
You can also apply several filters to an API request. Just connect additional filters with an “and”, the selection will return all resource items that match each filter criterion.
javascript# filter all conversations for a certain operator and a certain contact curl --header "Authorization: e56fb4ac-f430-3cff-a297-d531f772edaf" \ "https://api.userlike.com/api/um/v1/analytics/um_operator_status/?um_widget_id=7&operator_id=5" # filtered results that match um_widget_id and operator_id { "results": [ { 'operator_group_id': 2, 'operator_id': 5, 'organization_id': 3, 'time': '2020-05-05T01:25:33', 'um_widget_id': [7, 8], 'value': None, 'value_str': 'offline', 'conversation_id': None, 'conversation_part_id': None, 'conversation_session_id': None }, ... ] }
The more filters you add, the more specific your request will be and chances are that there are no items matching all criteria.
Multiple keywords
You can search for multiple keywords in one request by providing the parameter with a white-space-separated value. Since you cannot use literal whitespaces in your request URLs, use one of the following encodings:
Encoding | Value | Example |
"Percent" encoding | %20 | ?um_widget_id=3%204 |
"Plus" encoding | + | ?um_widget_id=3+4 |
You can use multiple keywords by connecting them with a “+”. Still, they’ll follow an “or” logic, which means that a search for um_widget_id “3+4” will return results that match either the first or the second Widget ID:
Data point format
Each resource yields a list of data points in the following format:
Key | Data type | Remarks |
um_widget_id | list of numbers | |
organization_id | number | |
operator_id | number | Not available for um_missed_opportunity |
operator_group_id | number | Not available for um_missed_opportunity |
time | list of numbers | |
value | number | Relevance depends on accessed resource |
value_str | string | Relevance depends on accessed resource |
conversation_id | number | Only available if the metric was tracked based on a conversation event (this will also include some but not all entries for um_operator_statusum_operator_slot_usage ) |
conversation_part_id | number | Only available if the metric was tracked based on an individual conversation session event (this also includes some but not all entries for um_operator_statusum_operator_slot_usage ) |
conversation_session_id | number | Only available if the metric was tracked based on an individual conversation session event (this also includes some but not all entries for um_operator_statusum_operator_slot_usage ) |
is_chatbot_metric | boolean | True if the associated operator while tracking this data point was a chatbot, a detailed explanation on how to interpret is_chatbot_metric , chatbot_interaction and human_interaction can be found in the examples |
chatbot_interaction | boolean | Shows the progression in an individual conversation. Only available if the metric was tracked for a conversation event. |
human_interaction | boolean | Shows the progression in an individual conversation. Only available if the metric was tracked for a conversation event. |
Resources
Resource | Description | 'value' | 'value_str' | Remarks |
um_operator_status | Operator status changes, due to an explicit operator action or slot change | onlineslots_fullawayoffline | ||
um_operator_slot_usage | An operator’s number of occupied chat slots changes | Current chat slot utilization of the operator in percent | Exact number of occupied slots and maximum number of slots set for the operator, in the form: 'current_slots':'total_slots' | |
um_conversation_topic | Latest topic(s) set for a specific conversation | IDs of set topic(s) | Verbose names of topic(s) | Counts only 1 event per conversation (the latest change) |
um_conversation_pre_survey | A pre-conversation survey is answered | Index ID of selected option | Verbose label of selected option | |
um_conversation_post_survey | A post-conversation survey is answered | Index ID of selected option | Verbose label of selected option | |
um_contact_browser | A contact’s browser is identified during a conversation | Browser identification | ||
um_contact_country | A contact’s country is identified during a conversation | Country identification | ||
um_conversation_duration | The duration of a conversation when it ends | Duration in seconds | Multiple events can occur if a conversation is resumed and ends again | |
um_conversation_first_message | The first message in a conversation is sent | Message could be from operator or contact | ||
um_conversation_first_message_assignment_update | The first message in a conversation is sent | Message could be from operator or contact. This metric is identical to um_conversation_first_message but the assigned operator will be updated according to the state of the corresponding conversation. | ||
um_conversation_rating | A contact rates a conversation | Rating value selected by contact | Only tracks the latest rating in a conversation | |
um_conversation_feedback | A contact leaves feedback in a conversation | 1 | Only tracks the occurrence of the feedback not its content | |
um_chat_messages_total | A message is sent or received in a conversation | Message count | Tracked at the end of a conversation session | |
um_chat_messages_ct | An operator sends a message in a conversation session | Message count | Tracked at the end of a conversation session | |
um_chat_messages_co | Counts all messages received in a conversation session | Message count | Tracked at the end of a conversation session | |
um_conversation_unanswered_live | A live conversation session times out without an operator reply | 1 | Only tracks 1 event per conversation, even if the contact made another conversation attempt. Counts only if an operator was online, ignores slot status | |
um_conversation_unanswered_ended | A conversation ends without an operator reply | 1 | Only tracks 1 event per conversation | |
um_conversation_inactivity_action | The system triggers an inactivity prevention action for a conversation based on the Widget’s settings under Chat > Behavior > Inactivity prevention. | 1 | status_unassignstatus_reassign_failstatus_reassignactive_notificationactive_reassign_failactive_reassignoffline_reassign_failoffline_reassign | |
um_conversation_goal_reached | A conversation goal is reached | ID of goal reached | Name of the actual goal reached | |
um_conversation_reopen | An ended conversation is resumed | 1 | New status after conversation is resumed | |
um_missed_opportunity | A contact tries to start a new conversation while no operator is available | 1 | ID of the relevant conversation as text value | |
um_contact_unique_visit | A unique visitor is identified via cookie and starts a conversation | 1 | ID of the relevant conversation as text value | Event is registered at the end of the conversation session |
um_operator_response_time_first | The first response time of an operator in a conversation session | Response time in seconds | Tracked at the first operator response | |
um_operator_response_time_first_service_time | The first response time of an operator in a conversation session (service times considered) | Response time in seconds | Tracked at the first operator response. Service time needs to be enabled. | |
um_operator_response_time_conversation_first | The first response of an operator in the first session of a conversation | Response time in seconds | Tracked at the first operator response | |
um_operator_response_time_conversation_first_service_time | The first response of an operator in the first session of a conversation (service times considered) | Response time in seconds | Tracked at the first operator response. Service time needs to be enabled. | |
um_operator_response_time | Response time of an operator in a conversation session | Response time in seconds | Tracked for all but the first operator response. | |
um_operator_response_time_service_time | Response time of an operator in a conversation session (service times considered) | Response time in seconds | Tracked for all but the first operator response. Service time needs to be enabled. | |
um_operator_response_time_to_unanswered_session_first | Response time in the first session of a conversation started while no operator was available | Response time in seconds | ||
um_operator_response_time_to_unanswered_session_first_service_time | Response time in the first session of a conversation started while no operator was available (service times considered) | Response time in seconds | Service time needs to be enabled. | |
um_operator_response_time_to_unanswered_session | Response time in a conversation session started while no operator was available | Response time in seconds | ||
um_operator_response_time_to_unanswered_session_service_time | Response time in a conversation session started while no operator was available (service times considered) | Response time in seconds | Service time needs to be enabled. | |
um_conversation_part_category | A conversation starts, its status is tracked based on the availability status of operator and contact | 1 | liveofflinere-engage | |
um_contact_response_time_backchannel | Response time of a contact to an asynchronous operator reply. | Response time in seconds | ||
um_contact_response_time_backchannel_service_time | Response time of a contact to an asynchronous operator reply (service times considered) | Response time in seconds | Service time needs to be enabled. | |
um_conversation_session_count | Number of sessions in a conversation | Number of conversation sessions | The value is updated with each new session, while the event time remains that of the first session. | |
um_conversation_session_duration_live | Duration of a conversation session in which operator and contact were active at the same time | Session duration in seconds | live | |
um_conversation_session_duration_offline | Duration of a conversation session in which only the contact was active | Session duration in seconds | offline | Please note that the Analytics dashboard aggregates “offline” and “re_engage” into a single graph. |
um_conversation_session_duration_re_engage | Duration of a conversation session in which only operators was active | Session duration in seconds | re-engage | Please note that the Analytics dashboard aggregates “offline” and “re_engage” into a single graph. |
um_conversation_status_duration | Duration that a conversation stays in any active status (“New”, “Open”, “Pending”). | Duration in seconds | Status value | There is one record for each of the status values per conversation. |
um_conversation_unassigned_duration | Duration that a conversation stays unassigned while in an active status (“New”, “Open”, “Pending”). | Duration in seconds | The values are only recorded and updated when the conversation is assigned to an operator or ended without assignee. Only one value per conversation per status value is recorded. | |
um_chat_session_manual_forward_live | Number of times a live conversation session was reassigned to an operator | 1 | Textual compound containing operator ids for 'from', 'to' and 'by' | To categorize the event as 'live' the session state at moment of the reassignement is considered |
um_chat_session_manual_forward_offline | Number of times an offline conversation session was reassigned to an operator | 1 | Textual compound containing operator ids for 'from', 'to' and 'by' | To categorize the event as 'offline' the session state at moment of the reassignement is considered |
um_chat_session_manual_forward_re_engage | Number of times a re-engage conversation session was reassigned to an operator | 1 | Textual compound containing operator ids for 'from', 'to' and 'by' | To categorize the event as 're-engage' the session state at moment of the reassignement is considered |
um_chat_session_manual_forward_group_live | Number of times a live conversation session was reassigned to an operator group | 1 | Textual compound containing operator ids for 'from', 'to' and 'by' | To categorize the event as 'live' the session state at moment of the reassignement is considered |
um_chat_session_manual_forward_group_offline | Number of times an offline conversation session was reassigned to an operator group | 1 | Textual compound containing operator ids for 'from', 'to' and 'by' | To categorize the event as 'offline' the session state at moment of the reassignement is considered |
um_chat_session_manual_forward_re_group_engage | Number of times a re-engage conversation session was reassigned to an operator group | 1 | Textual compound containing operator ids for 'from', 'to' and 'by' | To categorize the event as 're-engage' the session state at moment of the reassignement is considered |
um_chat_session_bot_forward_received | A conversation is initially assigned to a chatbot and then reassigned to another operator. | 1 |
Resource Details
Resource | Resource value | Description |
um_operator_status | online | Operator is available and has open slots |
um_operator_status | slots_full | Operator is available but all slots are full |
um_operator_status | away | Operator is set to away |
um_operator_status | offline | Operator is offline |
um_operator_status | removed_widget | Operator is removed from Widget routing |
um_conversation_inactivity_action | status_reassign | A conversation remained in the “New” or “Open” status for too long (based on your Widget settings) without the assigned operator reacting to it. To not keep the contact waiting, the respective conversation was unassigned, indicating to all available operators that an action is required. |
um_conversation_inactivity_action | status_unassign | A conversation remained in the “New” or “Open” status for too long (based on your Widget settings) without the assigned operator reacting to it. To not keep the contact waiting, the respective conversation was assigned to a different, available operator. |
um_conversation_inactivity_action | status_reassign_fail | A conversation remained in the “New” or “Open” status for too long (based on your Widget settings) without the assigned operator reacting to it. Still, the conversation could not be reassigned as none of the other operators had any free chat slots. If this event occurs more frequently, we suggest to increase your overall availability by adding more operators or increasing the existing operators’ number of chat slots. |
um_conversation_inactivity_action | active_notification | The assigned operator of a live conversation did not reply in time (based on your Widget settings). The respective contact was notified about this. |
um_conversation_inactivity_action | active_reassign | The assigned operator did not reply in time (based on your Widget settings). To not keep the contact waiting, the respective conversation was assigned to a different, available operator. Please note that this event is also triggered if the event Inactivity message sent was triggered before. |
um_conversation_inactivity_action | active_reassign_fail | The assigned operator did not reply in time (based on your Widget settings). Still, the conversation could not be reassigned as none of the other operators had any free chat slots. |
um_conversation_inactivity_action | offline_reassign | A contact resumed a conversation while the last assigned operator was not available. |
um_conversation_inactivity_action | offline_reassign_fail | A contact resumed a conversation while the last assigned operator was not available. Still, the conversation could not be reassigned as none of the other operators had any free chat slots. |
um_conversation_category | live | Conversation is started by operator or contact while both are available |
um_conversation_category | offline | Conversation is started by contact while operator is unavailable |
um_conversation_category | re-engage | Conversation is started by operator while contact is unavailable |
um_conversation_part_category | live | Conversation part is started while both operator and contact are online and a slot is reserved |
um_conversation_part_category | offline | Conversation part is started either while only the contact is online or contact and operator are online while no slot is reserved |
um_conversation_part_category | re-engage | Conversation part is started while only the contact is online |
Python examples
We prepared a few examples on how to access the Userlike Analytics API using Python. It’s pretty straightforward, we use the Python library “requests” for the HTTP requests, always adding the required Authorization headers.
More complex example: Calculate 'online', 'away', 'offline' durations for a single operator in a defined timeframe
This larger example shows you how to combine and interpret the data, to access individual operator IDs, please refer to our JSON API tutorial
javascriptimport os import datetime import requests API_TOKEN = os.environ.get("API_TOKEN") or "e56fb4ac-f430-3cff-a297-d531f772edaf" API_HOST = os.environ.get("API_HOST") or "https://api.userlike.com" headers = {"Authorization": API_TOKEN} ACTIVE_STATES = ["online", "slots_full"] AWAY_STATES = ["away"] OFFLINE_STATES = ["offline"] def get_operator_availability(date_from, date_to, operator_id): filter_params = { "event_date_from": date_from, "event_date_to": date_to, "operator_id": "%s" % operator_id, } metric = "um_operator_status" resp = requests.get( "{}/api/um/v1/analytics/{}/".format(API_HOST, metric), headers=headers, params=filter_params, verify=False, ) assert resp.status_code == 200 result_data = sorted(resp.json()["results"], key=lambda i: i["time"]) online_duration = 0 away_duration = 0 offline_duration = 0 # this script assumes that the operator begins the day by logging in and entering the UMC # therefore the first expected resp_item will be the switch to online # depending on the usage this needs to be adjusted or calculated based on previous events last_state = "offline" last_timestamp = datetime.datetime.strptime(date_from, "%Y-%m-%d") for resp_item in result_data: assert int(resp_item["operator_id"]) == int(operator_id) cur_state = resp_item["value_str"] event_time = datetime.datetime.strptime(resp_item["time"], "%Y-%m-%dT%H:%M:%S") frame_duration = None # we register a state change if last_state not in ACTIVE_STATES and cur_state in ACTIVE_STATES: frame_duration = (event_time - last_timestamp).total_seconds() elif last_state not in AWAY_STATES and cur_state in AWAY_STATES: frame_duration = (event_time - last_timestamp).total_seconds() elif last_state not in OFFLINE_STATES and cur_state in OFFLINE_STATES: frame_duration = (event_time - last_timestamp).total_seconds() if frame_duration is not None: if last_state in ACTIVE_STATES: online_duration += frame_duration elif last_state in AWAY_STATES: away_duration += frame_duration elif last_state in OFFLINE_STATES: offline_duration += frame_duration last_state = cur_state last_timestamp = event_time day_end = datetime.datetime.strptime(date_to, "%Y-%m-%d") + datetime.timedelta(1) # add remaining time after last event if last_state in ACTIVE_STATES: online_duration += (day_end - last_timestamp).total_seconds() if last_state in AWAY_STATES: away_duration += (day_end - last_timestamp).total_seconds() if last_state in OFFLINE_STATES: offline_duration += (day_end - last_timestamp).total_seconds() online_duration /= 60.0 # convert duration from seconds to minutes away_duration /= 60.0 # convert duration from seconds to minutes offline_duration /= 60.0 # convert duration from seconds to minutes print( "Operator with id: {} was {} minutes available from {} to {}".format( operator_id, online_duration, date_from, date_to ) ) print( "Operator with id: {} was {} minutes set to away from {} to {}".format( operator_id, away_duration, date_from, date_to ) ) print( "Operator with id: {} was {} minutes offline from {} to {}".format( operator_id, offline_duration, date_from, date_to ) ) if __name__ == "__main__": operator_id = 455 date_from = "2020-01-05" date_to = "2020-01-10" get_operator_availability(date_from, date_to, operator_id)
This larger example shows you how to cluster data and interpret various data points with respect to chatbot and/or human interactions.
javascriptimport os import datetime import requests API_TOKEN = os.environ.get("API_TOKEN") or "e56fb4ac-f430-3cff-a297-d531f772edaf" API_HOST = os.environ.get("API_HOST") or "https://api.userlike.com" headers = {"Authorization": API_TOKEN} # SAMPLE_DATA = [ # # This datapoint was tracked for a conversation where human and chatbot operators interacted # # chatbot_interaction = True # # human_interaction = True # # and we know the currently assigned operator is a human (at the moment this event was recorded) # # is_chatbot_metric = False # { # "operator_id": 1004, # "operator_group_id": 929, # "organization_id": 628, # "conversation_id": 877, # "conversation_part_id": 1163, # "conversation_session_id": 1163, # "um_widget_id": [768], # "time": "2021-01-05 20:00:00", # "human_interaction": True, # "chatbot_interaction": True, # "is_chatbot_metric": False, # "value": 5, # "value_str": None, # }, # # This datapoint was tracked for a conversation where only chatbot operators interacted # # chatbot_interaction = True # # human_interaction = False # # and we know the currently assigned operator is a chatbot (at the moment this event was recorded) # # is_chatbot_metric = True # { # "operator_id": 1005, # "operator_group_id": 929, # "organization_id": 628, # "conversation_id": 878, # "conversation_part_id": 1164, # "conversation_session_id": 1164, # "human_interaction": False, # "um_widget_id": [768], # "time": "2021-01-05 21:00:00", # "chatbot_interaction": True, # "is_chatbot_metric": True, # "value": 7, # "value_str": None, # }, # # This datapoint was tracked for a conversation where human and chatbot operators interacted # # chatbot_interaction = True # # human_interaction = True # # and we know the currently assigned operator is a human (at the moment this event was recorded) # # is_chatbot_metric = False # { # "operator_id": 1006, # "operator_group_id": 929, # "organization_id": 628, # "conversation_id": 879, # "conversation_part_id": 1165, # "conversation_session_id": 1165, # "human_interaction": True, # "um_widget_id": [768], # "time": "2021-01-05 22:00:00", # "chatbot_interaction": True, # "is_chatbot_metric": False, # "value": 11, # "value_str": None, # }, # # This datapoint was tracked for a conversation where only human operators interacted # # chatbot_interaction = False # # human_interaction = True # # and we know the currently assigned operator is a human (at the moment this event was recorded) # # is_chatbot_metric = False # { # "operator_id": 1004, # "operator_group_id": 929, # "organization_id": 628, # "conversation_id": 880, # "conversation_part_id": 1166, # "conversation_session_id": 1166, # "um_widget_id": [768], # "time": "2021-01-05 20:00:00", # "human_interaction": True, # "chatbot_interaction": False, # "is_chatbot_metric": False, # "value": 13, # "value_str": None, # }, # # This datapoint was tracked for a conversation where only define that only humans interacted # # chatbot_interaction = False # # human_interaction = True # # operator_id = None # # this can be because the operator was unassigned or no operator could be routed successfull # # (in which case it showed up in a human operator unassigned inbox, so a human must have either unassigned it # # or ignored it until this event was recorded) # # and we know the currently assigned operator is a human (at the moment this event was recorded) # # is_chatbot_metric = False # { # "operator_id": None, # "operator_group_id": None, # "organization_id": 628, # "conversation_id": 881, # "conversation_part_id": 1167, # "conversation_session_id": 1167, # "um_widget_id": [768], # "time": "2021-01-05 20:00:00", # "human_interaction": True, # "chatbot_interaction": False, # "is_chatbot_metric": False, # "value": 3, # "value_str": None, # }, # ] def download_data(date_from, date_to): filter_params = { "event_date_from": date_from, "event_date_to": date_to, } metric = "um_chat_messages_co" resp = requests.get( "{}/api/um/v1/analytics/{}/".format(API_HOST, metric), headers=headers, params=filter_params, verify=False, ) assert resp.status_code == 200 result_data = sorted(resp.json()["results"], key=lambda i: i["time"]) return result_data def cluster_data(data_set): data_cluster = {} for itm in data_set: cluster_name = "" if itm["chatbot_interaction"] and itm["human_interaction"]: cluster_name = "Conversation where human and chatbot operators interacted" elif itm["chatbot_interaction"] and not itm["human_interaction"]: cluster_name = "Conversation where only chatbot operators interacted" elif not itm["chatbot_interaction"] and itm["human_interaction"]: cluster_name = "Conversation where only human operators interacted" if cluster_name not in data_cluster.keys(): data_cluster[cluster_name] = [itm["value"]] else: data_cluster[cluster_name].append(itm["value"]) return data_cluster def print_average(clustered_data): for key, value in clustered_data.items(): averaged = sum(value) / len(value) print("{}: {}".format(key, averaged)) def get_average_co_messages_per_interaction_type(date_from, date_to): data_set = download_data(date_from, date_to) clustered_data = cluster_data(data_set) print_average(clustered_data) if __name__ == "__main__": date_from = "2021-01-05" date_to = "2021-01-10" get_average_co_messages_per_interaction_type(date_from, date_to)