Breadcrumbs

Analytics API V2

Analytics API Reference

Authentication

All public endpoints require authentication via a product token. Requests must include the token in the X-CM-PRODUCTTOKEN header:

X-CM-PRODUCTTOKEN: <product-token>

You can find your token for the Analytics endpoints by opening your HALO studio, selecting ‘Settings’ at the bottom left, and selecting ‘Account’. You will see this view:

image-20260213-084016.png

Here, you can click on ‘Create Token’, create a name for your Token, and select the ‘Analytics’ type. Then, you will be given the Token you can use for the API. Please store the token in a secured location.

Base URL

https://api.cm.com/halo

Swagger: https://api.cm.com/halo/analytics/docs


Breaking Changes

The metrics, resources and get_conversation endpoints no longer use the envelope wrapper. Previously, responses were wrapped in:

JSON
{
  "data": [],
  "meta": {
    "total_count": 0
  },
  "pagination": {
    "page_size": 0,
    "has_next": false,
    "has_previous": false,
    "next_cursor": null,
    "previous_cursor": null
  }
}

These endpoints now return the response body directly without the data, meta, and pagination wrapper.

The get_conversations endpoint is not affected by this change — it uses the envelope format with data, meta, and pagination fields.


Analytics v1

GET /analytics/v1/accounts/{account_id}/metrics

Retrieve aggregated conversation metrics for an account within a date range, optionally filtered by profile.

Path Parameters

Parameter

Type

Required

Description

account_id

UUID

Yes

The account ID

Query Parameters

Parameter

Type

Required

Default

Description

start_date

ISO 8601 datetime

No

30 days ago

Start of the date range (UTC)

end_date

ISO 8601 datetime

No

Now

End of the date range (UTC)

profile_id

integer

No

Filter metrics to a specific profile. Returns 404 if not found

Validation
  • start_date must be before end_date. Returns 422 Unprocessable Entity if violated.

  • If profile_id is provided, the profile must exist. Returns 404 Not Found otherwise.

Response 200 OK
JSON
{
  "total_conversations_count": 1520,
  "total_average_conversation_duration_seconds": 145,
  "total_average_interactions_per_conversation": 6.3,
  "average_recognition_rate": 0.87,
  "product_metrics": [
    {
      "product": "support-chat",
      "conversations_count": 980,
      "average_conversation_duration_seconds": 130,
      "average_interactions_per_conversation": 5.8,
      "average_recognition_rate": 0.91
    }
  ]
}

Field

Type

Description

total_conversations_count

integer

Total number of conversations in the date range

total_average_conversation_duration_seconds

integer

Average conversation duration across all conversations (in seconds)

total_average_interactions_per_conversation

float

Average number of interactions (messages) per conversation

average_recognition_rate

float or null

Average recognition rate across conversations (0.0–1.0)

product_metrics

array or null

Per-product breakdown (omitted if no products)

Each entry in product_metrics:

Field

Type

Description

product

string

Product name

conversations_count

integer

Number of conversations for this product

average_conversation_duration_seconds

integer

Average duration for this product (seconds)

average_interactions_per_conversation

float

Average interactions per conversation

average_recognition_rate

float or null

Average recognition rate for this product

Error Responses

Status

Description

400

Invalid query parameters

404

Account or profile not found

422

start_date is not before end_date


Analytics v2

GET /analytics/v2/accounts/{account_id}/conversations

List conversations for a profile with filtering, sorting, and pagination. Returns a paginated list of conversation overviews along with available filter options for the current date range.

Path Parameters

Parameter

Type

Required

Description

account_id

UUID

Yes

The account ID

Query Parameters

Parameter

Type

Required

Default

Description

profile_id

integer

No

The profile to list conversations for

duration_filter_in_days

integer

No

Number of days to look back from now. Overrides from_date/until_date if provided

from_date

ISO 8601 datetime

No

7 days ago

Start of the date range (UTC)

until_date

ISO 8601 datetime

No

Now

End of the date range (UTC)

languages

string (CSV)

No

Filter by languages (e.g. en,nl)

channels

string (CSV)

No

Filter by channels

products

string (CSV)

No

Filter by products

resolutions

string (CSV)

No

Filter by resolutions

feedbacks

string (CSV)

No

Filter by feedback values

search_query

string

No

Full-text search within conversation content

min_recognition_rate_percentage

float

No

Minimum recognition rate filter (0–100)

max_recognition_rate_percentage

float

No

Maximum recognition rate filter (0–100)

agent_ids

string (CSV)

No

Filter by agent IDs (comma-separated integers)

tool_ids

string (CSV)

No

Filter by tool IDs (comma-separated integers)

topic_ids

string (CSV)

No

Filter by topic IDs (comma-separated integers, use -1 for pending)

has_feedback

boolean

No

true = only with feedback, false = only without

page_size

integer

No

1000

Number of conversations per page (clamped to 1–1000)

page_index

integer

No

0

0-based page index

sort_order

string

No

desc

Sort order: asc or desc

sort_by

string

No

started

Sort field: started, ended, or recognition_rate

Date Range Behavior
  • If duration_filter_in_days is provided, it takes precedence: from_date = now minus N days, until_date = now.

  • If neither duration_filter_in_days nor from_date/until_date are provided, defaults to the last 7 days.

  • If only from_date or until_date is provided, the other remains open-ended.

Pagination

This endpoint uses offset-based pagination via page_index and page_size query parameters. The response includes pagination metadata in nested meta and pagination objects:

Field

Type

Description

meta.total_count

integer

Total number of conversations matching the filters

pagination.page_size

integer

Requested page size

pagination.has_next

boolean

Whether there is a next page

pagination.has_previous

boolean

Whether there is a previous page

pagination.next_cursor

string or null

Reserved for cursor-based pagination (currently null)

pagination.previous_cursor

string or null

Reserved for cursor-based pagination (currently null)

To iterate through pages, increment page_index and check pagination.has_next.

Response 200 OK
JSON
{
  "data": [],
  "possible_language_filters": ["en", "nl", "de"],
  "possible_product_filters": ["support-chat", "sales-chat"],
  "possible_channel_filters": ["web", "whatsapp"],
  "meta": {
    "total_count": 342
  },
  "pagination": {
    "page_size": 100,
    "has_next": true,
    "has_previous": false,
    "next_cursor": null,
    "previous_cursor": null
  }
}

Field

Type

Description

data

array

List of ConversationOverview objects (see below)

possible_language_filters

string array

All distinct languages available in the current date range

possible_product_filters

string array

All distinct products available in the current date range

possible_channel_filters

string array

All distinct channels available in the current date range

meta

object

Response metadata

meta.total_count

integer

Total number of conversations matching the filters

pagination

object

Pagination details

pagination.page_size

integer

Requested page size

pagination.has_next

boolean

Whether there is a next page

pagination.has_previous

boolean

Whether there is a previous page

pagination.next_cursor

string or null

Reserved for future cursor-based pagination

pagination.previous_cursor

string or null

Reserved for future cursor-based pagination

ConversationOverview Object

Each item in data represents a summary of a single conversation.

Field

Type

Description

conversation_id

UUID

Unique conversation identifier

profile_id

integer or null

Profile the conversation belongs to

created

datetime or null

When the conversation record was created

started

datetime or null

When the first message was exchanged

ended

datetime or null

When the conversation ended

first_user_message

string or null

The first message sent by the user

most_common_language

string or null

Dominant language (2-character ISO code)

most_common_origin

string or null

Most common origin/source

most_common_channel

string or null

Most common channel (e.g. web, whatsapp)

most_common_product

string or null

Most common product

environment

string or null

Environment the conversation ran in (e.g. production, staging)

matched_items

integer

Number of user messages that were successfully recognized

total_items

integer

Total number of user messages

recognition_rate

float

Ratio of matched to total items (0.0–1.0)

visited_agent_ids

integer array

IDs of agents that handled the conversation

visited_tool_ids

integer array

IDs of tools that were invoked during the conversation

resolution

string or null

Resolution status (see https://cmcom.atlassian.net/wiki/spaces/KCENTER/pages/edit-v2/2925264909#Resolutions )

resolution_reasoning

string or null

AI-generated reasoning for the resolution classification

summary

string or null

AI-generated conversation summary

feedback

string

User feedback rating (see https://cmcom.atlassian.net/wiki/spaces/KCENTER/pages/edit-v2/2925264909#Feedback)

feedback_comment

string or null

Free-text comment left with feedback

topic

object or null

Assigned topic (see https://cmcom.atlassian.net/wiki/spaces/KCENTER/pages/edit-v2/2925264909#Topics)

subtopic

object or null

Assigned subtopic (see https://cmcom.atlassian.net/wiki/spaces/KCENTER/pages/edit-v2/2925264909#Subtopics)

manual_resolution

object or null

Manual resolution override (see https://cmcom.atlassian.net/wiki/spaces/KCENTER/pages/edit-v2/2925264909#Manual-Resolutions)

external_handover

object or null

Handover metadata if conversation was transferred to a human agent

messages

array

Simplified message list (see https://cmcom.atlassian.net/wiki/spaces/KCENTER/pages/edit-v2/2925264909#Messages)


GET /analytics/v2/accounts/{account_id}/conversations/{conversation_id}

Retrieve a single conversation by ID with full calculated analytics, including detailed message history.

Path Parameters

Parameter

Type

Required

Description

account_id

UUID

Yes

The account ID

conversation_id

UUID

Yes

The conversation ID

Response 200 OK
JSON
{
  "most_common_channel": "web",
  "most_common_language": "en",
  "most_common_origin": "website",
  "most_common_product": "support-chat",
  "started": "2025-01-15T10:30:00Z",
  "ended": "2025-01-15T10:45:00Z",
  "total_user_items": 8,
  "num_matched_user_items": 7,
  "recognition_rate": 0.875,
  "messages": [],
  "resolution": "RESOLUTION_SUCCESSFUL",
  "resolution_reasoning": "The user's question was answered completely.",
  "summary": "User asked about order status and received tracking info.",
  "feedback": "FEEDBACK_SATISFIED",
  "version": 2,
  "visited_agent_ids": [1, 3],
  "visited_tool_ids": [2],
  "topic": { "id": 5, "name": "Order Status", "definition": "Questions about order tracking and delivery" },
  "subtopic": { "id": 12, "name": "Tracking", "definition": "Requests for tracking information" },
  "manual_resolution": null
}

Field

Type

Description

most_common_channel

string or null

Dominant channel

most_common_language

string or null

Dominant language

most_common_origin

string or null

Dominant origin

most_common_product

string or null

Dominant product

started

datetime

Conversation start time

ended

datetime

Conversation end time

total_user_items

integer

Total number of user messages

num_matched_user_items

integer

Number of recognized user messages

recognition_rate

float

Recognition rate (0.0–1.0)

messages

array

Full message history with detailed content (see https://cmcom.atlassian.net/wiki/spaces/KCENTER/pages/edit-v2/2925264909#Message-Types)

resolution

string

Resolution status

resolution_reasoning

string or null

AI reasoning for resolution

summary

string or null

AI-generated summary

feedback

string

User feedback rating

version

integer

Response format version (currently 2)

visited_agent_ids

integer array

Agent IDs visited

visited_tool_ids

integer array

Tool IDs invoked

topic

object or null

Assigned topic

subtopic

object or null

Assigned subtopic

manual_resolution

object or null

Manual resolution override, if any

Error Responses

Status

Description

404

Conversation not found, or conversation has no items/metadata


Analytics v1 — Resources

These endpoints return the available agents and tools for an account. They are used to populate filter options in analytics UIs.

Note: For profiles, use the Core API profiles endpoint at /core/v1/accounts/{account_id}/profiles (permission: HALO.Core_Profiles_Read).

GET /analytics/v1/accounts/{account_id}/agents

Retrieve agents for an account, optionally filtered by profile.

Path Parameters

Parameter

Type

Required

Description

account_id

UUID

Yes

The account ID

Query Parameters

Parameter

Type

Required

Description

profile_id

integer

No

Filter agents by profile ID

Response 200 OK
JSON
[
  { "id": 1, "name": "Sales Agent" },
  { "id": 2, "name": "Support Agent" }
]

Field

Type

Description

id

integer

Agent ID

name

string

Agent name

Error Responses

Status

Description

400

Invalid account ID

404

Account not found

500

Internal server error


GET /analytics/v1/accounts/{account_id}/tools

Retrieve tools for an account, optionally filtered by profile.

Permission: HALO.Analytics_API

Path Parameters

Parameter

Type

Required

Description

account_id

UUID

Yes

The account ID

Query Parameters

Parameter

Type

Required

Description

profile_id

integer

No

Filter tools by profile ID

Response 200 OK
JSON
[
  { "id": 1, "name": "Knowledge Search", "description": "Searches the knowledge base" },
  { "id": 2, "name": "Order Lookup", "description": "Looks up order status" }
]

Field

Type

Description

id

integer

Tool ID

name

string

Tool name

description

string

Tool description

Error Responses

Status

Description

400

Invalid account ID

404

Account not found

500

Internal server error


Content Types

Messages

Messages in the conversation list endpoint (ConversationItemSummary) are a simplified view:

Field

Type

Description

id

integer

Item ID

profile_id

integer or null

Profile ID

interaction_id

UUID or null

Interaction ID

role

string or null

Message role (e.g. user, halo, assistant)

name

string or null

Sender name

text_content

string or null

Plain text content of the message

match

boolean or null

Whether the message was recognized

language

string or null

Detected language

created

datetime or null

Timestamp

image_carousel

object or null

Carousel content (only present if the message contains one)

media

array or null

Media attachments (images, files)

buttons

array or null

Conversation option buttons

show_feedback

string or null

Feedback prompt text

json_content

array or null

Structured JSON content

Messages in the single conversation detail endpoint use the full Message type, which is a tagged union with the following variants: USER, HALO, ASSISTANT, CUSTOMER_SERVICE_AGENT, CUSTOMER_SERVICE_AGENT_INSTRUCTION, and EXTERNAL_HANDOVER. Each variant contains content parts that can be of type text, json, media, buttons, image_carousel, or show_feedback.

Topics

Topics represent the subject matter of a conversation, classified automatically by AI analysis of the conversation content. They form the parent level of a two-level taxonomy representing broad subject areas (e.g. "Billing", "Technical Support", "Account Management").

Field

Type

Description

id

integer

Topic ID

name

string

Human-readable topic name

definition

string

Description of what the topic covers

Use the topic_ids query parameter in the conversations list endpoint to filter by topic. A value of -1 matches conversations where topic classification is still pending.

Subtopics

Subtopics are child categories within a topic, providing more granular classification. They represent specific subjects within a broader topic area (e.g. under "Billing": "Invoice Dispute", "Payment Method", "Refund Request"). Every classified conversation has a subtopic; the parent topic is derived from the subtopic's position in the taxonomy.

Field

Type

Description

id

integer

Subtopic ID

name

string

Human-readable subtopic name

definition

string

Description of what the subtopic covers

Resolutions

Resolution indicates the outcome of a conversation. It is determined using the following priority order:

  1. External handover — if the conversation was handed over to a human agent, it is automatically classified as RESOLUTION_HANDOVER.

  2. Manual resolution — if an analyst has manually overridden the resolution, the manual label takes precedence.

  3. AI resolution — if neither of the above apply, the AI-determined resolution is used.

  4. Pending — if none of the above are available, the resolution defaults to RESOLUTION_PENDING.

Value

Description

RESOLUTION_SUCCESSFUL

The user's question or request was resolved successfully

RESOLUTION_HANDOVER

The conversation was transferred to a human agent

RESOLUTION_UNSUCCESSFUL

The conversation ended without the user's issue being resolved

RESOLUTION_UNDETERMINED

The AI could not confidently determine the outcome

RESOLUTION_PENDING

Resolution has not yet been classified (e.g. conversation is still ongoing or classification is pending)

The resolution_reasoning field (string or null) contains the AI's explanation of why it assigned a particular resolution label. This is only present when the resolution was determined by AI.

Manual Resolutions

A manual resolution is an override applied by an analyst or reviewer to correct or adjust the AI-assigned resolution. When a manual resolution is active, it takes precedence over the AI resolution in the priority chain described above.

Field

Type

Description

id

integer

Manual resolution record ID

profile_id

integer or null

Profile ID the resolution was applied to

conversation_id

UUID

Conversation this resolution applies to

user_name

string or null

Name of the user who applied the override

original_label

string or null

The resolution label before the override (null if no prior label existed)

new_label

string

The new resolution label applied by the reviewer

reasoning

string or null

Free-text explanation of why the resolution was changed

is_active

boolean

Whether this manual resolution is currently active

created

datetime

When the manual resolution was created

user_email

string

Email of the user who applied the override

original_label can be any value from the https://cmcom.atlassian.net/wiki/spaces/KCENTER/pages/edit-v2/2925264909#Resolutions section (or null if no prior label existed). new_label is restricted to:

  • RESOLUTION_SUCCESSFUL

  • RESOLUTION_UNSUCCESSFUL

Feedback

Feedback represents the end-user's satisfaction rating for a conversation, mapped from a 1–5 numeric score.

Value

Numeric Score

Description

FEEDBACK_VERY_SATISFIED

5

Very satisfied

FEEDBACK_SATISFIED

4

Satisfied

FEEDBACK_NEUTRAL

3

Neutral

FEEDBACK_UNSATISFIED

2

Unsatisfied

FEEDBACK_VERY_UNSATISFIED

1

Very unsatisfied

FEEDBACK_NOT_GIVEN

No feedback provided

Message Types

The single conversation detail endpoint returns full message objects. Each message is a tagged union with a type field:

Type

Description

USER

Message from the end user

HALO

AI assistant response with full reasoning and metadata

ASSISTANT

Generic assistant message

CUSTOMER_SERVICE_AGENT

Message from a human customer service agent

CUSTOMER_SERVICE_AGENT_INSTRUCTION

Instruction message from a customer service agent

EXTERNAL_HANDOVER

Handover event with transfer details

All message types share a common base containing content (array of content parts), timestamp, is_message_before_halo, and interaction_id.