Cognigy.AI OData Analytics Endpoint - Cognigy Documentation
Documentation Index
Fetch the complete documentation index at: /llms.txt
Use this file to discover all available pages before exploring further.
Updated in 2026.14 Open Data Protocol (OData) is a standard for building and using RESTful APIs. This protocol simplifies data access for web clients by providing a consistent way to describe data models and perform CRUD operations (create, read, update, delete) using standard HTTP methods and URLs.Based on the OData protocol version 4,
Cognigy.AI offers an OData Analytics endpoint to retrieve raw data using GET requests.
This endpoint meets all your enterprise analytics needs,
enabling you to make fine-grained queries in your spreadsheets
or build rich dashboards for AI Agents with your favorite data visualization tool.Watch this video to get a quick overview of what the OData Analytics endpoint is, how it works, and in which scenarios you can use it:
Cognigy Sessions: Cognigy Insights & OData - YouTube
Tap to unmute
Cognigy Sessions: Cognigy Insights & OData NiCE Cognigy
NiCE Cognigy2.97K subscribers
To analyze your AI Agent’s performance, you can use the built-in Insights reports as an alternative to OData or in addition to it.
Limitations
OData Endpoint Field Size and Length Limitations
- By default, the OData endpoint fields have the following limitations by data type:
| Type | Limitation |
|---|---|
| String | The maximum size of a string field is 16 MB. |
| Number (double) | The maximum and minimum values for a double are approximately ±1.7976931348623157E+308. |
| Number (32-bit integer) | The maximum and minimum values for a 32-bit integer are ±2,147,483,647. |
| Number (64-bit integer) | The maximum and minimum values for a 64-bit integer are ±9,223,372,036,854,775,807. |
- The OData endpoint fields in the following table have a maximum length that differs from the default limitations:
| Fields | Maximum length |
|---|---|
| endpointName, localeName, projectName, snapshotName, flowReferenceId | 200 characters |
| state, userType, channel, flowLanguage, intent, intentFlow, flowName | 256 characters |
| custom1, custom2, custom3, custom4, custom5, custom6, custom7, custom8, custom9, custom10 | 512 characters |
| label, stepLabel | 128 characters |
| entityReferenceId | 36 characters |
Restrictions
- The Cognigy.AI OData endpoint supports only the OData protocol version 4.
- The Cognigy.AI OData endpoint only supports
GETrequests and doesn’t support any other request types, such asPATCH,DELETE, orPOST. - The data retrieved through the Cognigy.AI OData endpoint isn’t updated in real time and may not reflect the current state.
- The Cognigy.AI OData endpoint supports a limited set of system query options, operators, and query functions. For detailed information about the query syntax, refer to the OData Query Syntax section.
Supported Versions
| Cognigy.AI version | Cognigy.AI OData endpoint version | Status |
|---|---|---|
| 4.65 and later | 2.4 | Supported |
| 4.48 and later | 2.3 | Supported; deprecation in February, 2026 |
| 4.31-4.47 | 2.0–2.3 | Not supported |
| 4.30 and earlier | 2.0–2.2 | Not supported |
Data Protection
You can control the data available through the OData endpoint at the Endpoint, Flow, and Node levels:
Endpoint — go to the Data Protection & Analytics section in the Endpoint settings:
If you disable the Collect Analytics setting, no analytics data is logged or available in OData.
- If you enable the Mask Sensitive Analytics setting, the
inputTextandinputDatafields are masked.
- If you enable the Mask Sensitive Analytics setting, the
Flow — add a Blind Mode Node to your Flow. This Node disables or masks analytics data available to the OData endpoint.
Node — use the Mask and keep analytics data parameter in the Delete Profile Node and the Keep analytics records, mask personal data option in the Deactivate Profile Node. These Nodes can mask personal data while including analytics data across the Analytics, Conversations, and Sessions collections. By default, rows with masked personal data in these collections are included in OData results. To exclude rows where personal data has been masked:
For SaaS installations, contact Cognigy technical support.
- For on-premises installations, set
ODATA_FILTER_MASKED_ROWS=trueinvalues.yaml.
- For on-premises installations, set
OData Endpoint Access
You can access the OData endpoint through a different domain than the one from Cognigy.AI:
Cognigy
NiCE CXone
Depending on the type of Cognigy installation you have, the OData endpoint domain is as follows:
- Trial —
https://odata-trial.cognigy.ai. - Shared SaaS —
https://odata-<your-domain>.cognigy.ai. - Dedicated SaaS — contact your Customer Success Manager or Cognigy.AI Support to get the OData endpoint URL.
- On-premises —
https://odata-<backend-url>, where<backend-url>refer to the URL assigned to theBACKEND_BASE_URL_WITH_PROTOCOLinvalues.yaml.
Use the following pattern: https://cognigy-odata-<region>.nicecxone.com, where <region> matches your NiCE CXone cluster. For example:
https://cognigy-odata-na1.nicecxone.comhttps://cognigy-odata-na3.nicecxone.comhttps://cognigy-odata-eu1.nicecxone.com
For a full list of available regions, refer to NiCE CXone Shared SaaS.
Authentication
To connect to the OData endpoint, you need to have the odata global role and an API Key.To authenticate your API requests to the OData endpoint, you need the following parameters:
- The Cognigy.AI OData base domain. It is the root URL where your OData service is hosted.
- The API version of the Cognigy.AI OData endpoint. Currently, Cognigy.AI supports OData 2.3 and 2.4.
- The collection in the OData service you want to access.
- The API key that authenticates and authorizes the API access. Generate the API key in your profile.
Authentication Methods
You can use the following methods to authenticate your requests to the OData endpoint:
- HTTP Headers — this method provides more security to access the OData endpoint. HTTP header authentication prevents API keys from exposure in the URL, server access logs, and other security risks. This method doesn’t support Microsoft Excel and Power BI integrations.
- Query Parameters — allows for Microsoft Excel and Power BI integrations. For this method, ensure appropriate access controls and security measures to prevent security risks.
Examples
The following examples use the following parameters:
Cognigy.AI OData base domain —
odata-trial.cognigy.aiCognigy.AI OData endpoint version —
v2.4OData collection —
AnalyticsAPI key —
123abcHTTP Headers
Query Parameters
cURL
JavaScript
Python
Node.js
curl -H "apikey: 123abc" \
"https://odata-trial.cognigy.ai/v2.4/Analytics"
fetch('https://odata-trial.cognigy.ai/v2.4/Analytics', {
headers: {
'apikey': '123abc'
}
});
import requests
requests.get('https://odata-trial.cognigy.ai/v2.4/Analytics', headers={'apikey': '123abc'})
const axios = require('axios');
axios.get('https://odata-trial.cognigy.ai/v2.4/Analytics', { headers: { 'apikey': '123abc' } });
https://odata-trial.cognigy.ai/v2.4/Analytics?apikey=123abc
If you are using the query parameters method to authenticate your requests to the OData endpoint, you can migrate to the HTTP headers method without breaking changes as follows:
Migrate from Query Parameters to HTTP Headers
If you currently use query parameters authentication with https://odata-trial.cognigy.ai/v2.4/Analytics?apikey=123abc, you can migrate to HTTP headers authentication by using the following HTTP headers:
cURL
JavaScript
Python
Node.js
curl -H "apikey: 123abc" \
"https://odata-trial.cognigy.ai/v2.4/Analytics"
fetch('https://odata-trial.cognigy.ai/v2.4/Analytics', {
headers: {
'apikey': '123abc'
}
});
import requests
requests.get('https://odata-trial.cognigy.ai/v2.4/Analytics', headers={'apikey': '123abc'})
const axios = require('axios');
axios.get('https://odata-trial.cognigy.ai/v2.4/Analytics', { headers: { 'apikey': '123abc' } });
Authentication for Microsoft Excel and Power BI
When using Microsoft Excel and Power BI, you might be prompted to authenticate. In this case, select Anonymous Authentication.
OData Query Syntax
The following rules define how OData queries must be structured when using system query options, operators, and string functions.These syntax requirements ensure that requests are valid, predictable, and compatible with the OData v4 protocol. They apply to all Cognigy.AI OData endpoint Collections and must be followed when creating query expressions.
List of Requirements
| Topic | Details |
|---|---|
| Date Format | Dates must use ISO 8601 format. Base format: YYYY-MM-DDThh:mm:ssZ. Milliseconds are supported using YYYY-MM-DDThh:mm:ss.sssZ. Example: 2024-01-01T00:00:00.000Z. .sss represents milliseconds (3 digits), and Z indicates UTC time. |
| Case Sensitivity | OData system query options ($filter, $select) and operators (eq, gt, and) are case-sensitive. |
| String Literals | String values inside $filter must be enclosed in single quotes. Example: userId eq '12345'. |
System Query Options
The Cognigy.AI OData endpoint supports a limited set of system query options:
| Query Option | Purpose |
|---|---|
$filter |
Filters results based on conditions. |
$skip |
Skips a number of records. The $skip query at high values, such as 10000, may impact performance and cause API timeouts. In these cases, use keyset pagination, for example, with the timestamp or _id field. |
$top |
Limits the number of returned records. |
$orderby |
Sorts the returned results by one or more fields. You can specify ascending (asc) or descending (desc) order. If no direction is provided, ascending order is used by default. |
$select |
Selects specific fields. |
$count1 |
Returns total count. |
Supported Operators and Query Functions
The Cognigy.AI OData endpoint supports a limited set of operators and query functions that you can use in the $filter system query option to create more complex queries.
Comparison Operators
These operators allow you to compare field values against specific criteria to filter your data effectively.
| Operator | Meaning | Example |
|---|---|---|
eq |
Equal | userId eq '12345' |
ne |
Not equal | status ne 'active' |
gt |
Greater than | timestamp gt 2024-01-01T00:00:00Z |
ge |
Greater or equal | value ge 10 |
lt |
Less than | value lt 100 |
le |
Less or equal | value le 100 |
Logical Operators
These operators allow you to combine multiple conditions for creating complex queries.
The not logical operator isn’t supported in the Cognigy.AI OData endpoint. Expressions such as not startswith(field, 'value'), not contains(field, 'value'), or startswith(field, 'value') eq false won’t work.
| Operator | Meaning | Example |
|---|---|---|
and |
Logical AND | status eq 'active' and channel eq 'web' |
or |
Logical OR | status eq 'active' or status eq 'pending' |
Query Functions
These functions allow you to perform complex filtering based on string patterns.
- Query functions may affect the performance of your requests. Use them with caution, especially on large datasets.
- Query functions don’t work in fields of type
text[](array of text values). Use exact match filtering (eq) or filter in a different supported field.
| Function | Purpose | Example |
|---|---|---|
contains |
Checks if string contains value. | contains(userId,'admin') |
startswith |
Checks if string starts with value. | startswith(userId,'user_') |
endswith |
Checks if string ends with value. | endswith(email,'.com') |
Examples
The tables contain examples of requests using system query options and operators. Select the OData endpoint version compatible with your Cognigy.AI version.
OData 2.4
OData 2.3
| Request Description | OData 2.4 Request |
|---|---|
| Returns total count of Analytics records (not supported in Microsoft Excel or Power BI). | https://odata-trial.cognigy.ai/v2.4/Analytics/$count?apikey=<your-api-key> |
| Returns all Analytics records for the given API Key. | https://odata-trial.cognigy.ai/v2.4/Analytics?apikey=<your-api-key> |
| Returns the first 10 Analytics records. | https://odata-trial.cognigy.ai/v2.4/Analytics/?$top=10&apikey=<your-api-key> |
Returns the top 5 Analytics records where executionTime is less than 50ms, ordered by executionTime. |
https://odata-trial.cognigy.ai/v2.4/Analytics/?$filter=executionTime lt 50&$top=5&$orderby=executionTime&apikey=<your-api-key> |
Returns all Analytics records for a specific Cognigy.AI Project filtered by projectId. |
https://odata-trial.cognigy.ai/v2.4/Analytics/?$filter=projectId eq '<project-id>'&apikey=<your-api-key> |
Returns Project and session IDs for a specific Cognigy.AI project. The request filters the data based on the projectId field and selects only the projectId and sessionId for each matching entry. |
https://odata-trial.cognigy.ai/v2.4/Analytics/?$filter=projectId eq '<project-id>'&$select=projectId,sessionId&apikey=<your-api-key> |
| Returns all Analytics records between two dates, for example, 1st Jan 2021 and 1st July 2021. | https://odata-trial.cognigy.ai/v2.4/Analytics/?$filter=timestamp gt '2021-01-01T00:00:00.000Z' and timestamp lt '2021-07-01T00:00:00.000Z'&apikey=<your-api-key> |
| Returns Analytics records where a field contains a specific string value. | https://odata-trial.cognigy.ai/v2.4/Analytics/?$filter=contains(userId,'admin')&apikey=<your-api-key> |
| Returns Analytics records where a field starts with a specific string value. | https://odata-trial.cognigy.ai/v2.4/Analytics/?$filter=startswith(userId,'user_')&apikey=<your-api-key> |
| Returns Analytics records where a field ends with a specific string value. | https://odata-trial.cognigy.ai/v2.4/Analytics/?$filter=endswith(userId,'_admin')&apikey=<your-api-key> |
| Request Description | OData 2.3 Request |
|---|---|
| Returns total count of Analytics records (not supported in Microsoft Excel or Power BI). | https://odata-trial.cognigy.ai/v2.3/Analytics/$count?apikey=<your-api-key> |
| Returns all Analytics records for the given API Key. | https://odata-trial.cognigy.ai/v2.3/Analytics?apikey=<your-api-key> |
| Returns the first 10 Analytics records. | https://odata-trial.cognigy.ai/v2.3/Analytics/?$top=10&apikey=<your-api-key> |
Returns the top 5 Analytics records where executionTime is less than 50ms, ordered by executionTime. |
https://odata-trial.cognigy.ai/v2.3/Analytics/?$filter=executionTime lt 50&$top=5&$orderby=executionTime&apikey=<your-api-key> |
Returns all Analytics records for a specific Cognigy.AI Project filtered by projectId |
https://odata-trial.cognigy.ai/v2.3/Analytics/?$filter=projectId eq '<project-id>'&apikey=<your-api-key> |
Returns Project IDs and session IDs for a specific Cognigy.AI project. The request filters the data based on the projectId field and selects only the projectId and sessionId for each matching entry. |
https://odata-trial.cognigy.ai/v2.3/Analytics/?$filter=projectId eq '<project-id>'&$select=projectId,sessionId&apikey=<your-api-key> |
| Returns all Analytics records between two dates, for example, 1st Jan 2021 and 1st July 2021. | https://odata-trial.cognigy.ai/v2.3/Analytics/?$filter=timestamp gt '2021-01-01T00:00:00.000Z' and timestamp lt '2021-07-01T00:00:00.000Z'&apikey=<your-api-key> |
For a full reference, refer to the extensive collection of resources at OData.org and the Oasis OData URL Convention documentation.
Cognigy.AI OData Collections
The OData endpoint provides access to several data collections containing information about your interactions and workflows. A collection is similar to a database table or a set of entities containing data. The set of collections varies depending on which version you are using:
Version 2.4
Version 2.3
The current version of the OData endpoint is v2.4. In this version, the following OData collections are available:
- Analytics (
/Analytics) - Conversations (
/Conversations) - Steps (
/Steps) - ExecutedSteps (
/ExecutedSteps) - Sessions (
/Sessions) - LiveAgentEscalations (
/LiveAgentEscalations) - Goals (
/Goals) - GoalSteps (
/GoalSteps) - GoalStepMetrics (
/GoalStepMetrics) - GoalEvents (
/GoalEvents)
The URL for accessing the OData endpoint 2.4 is as follows:
https://<odata-domain>/v2.4/<collection>?apikey=<your-api-key>
The previous version of the OData endpoint is 2.3. In this version, the following OData collections are available:
The URL for accessing the OData endpoint 2.3 is as follows:
https://<odata-domain>/v2.3/<collection>?apikey=<your-api-key>
Each collection can be filtered by its fields, which are often retrieved directly from the Input object results.
Analytics
The Analytics collection offers a log of comprehensive details such as organizational information, Project identifiers, Flow specifics, and essential performance metrics. Each chat or voice AI Agent session in Cognigy.AI creates an Analytics record for an interaction. Each interaction is logged as a single record. The information is saved only after the end of the session. You can change this data using the Overwrite Analytics Node.RequestsSelect an API request to extract data from the collection. The API version in the request must match your Cognigy.AI version.
OData 2.4
OData 2.3
https://odata-trial.cognigy.ai/v2.4/Analytics?apikey=<your-api-key>
https://odata-trial.cognigy.ai/v2.3/Analytics?apikey=<your-api-key>
ResponseWhen retrieving this collection, the endpoint returns the following fields:
Response Fields
| Field Name | Description | Type | Example |
|---|---|---|---|
| id | The unique ID of the record. Applicable to the OData endpoint 2.4 or later. | String | 5a91d194fde28b0011ce2423 |
| _id | The unique ID of the record. Applicable to the OData endpoint 2.3 or earlier. | String | 5a91d194fde28b0011ce2423 |
| organisation | The name of your organization. | String | cognigy |
| projectId | The ID of the Project related to the record. | String | 5a91d194fde28b0011ce2422 |
| flowReferenceId | The ID of the Flow. | String | 66ceb9cc-ac5b-4cdd-9f4b-8a48dfbb35d9 |
| entrypoint | The ID of the Project or Snapshot used by the Endpoint. | String | 621d3deb87016d3855ec0c92 |
| ip | The IP address from which the request originated. | String | 78.143.45.111 |
| contactId | The hash of the user ID. | String | 99ea95befe61812656bf963ba7d44ab7 |
| sessionId | The session ID. | String | 5a91d194fde28b0011ce2425 |
| inputId | The ID of the input message. | String | 5a91d194fde28b0011ce2424 |
| inputText | The input text. | String | Hello World! |
| inputData | The input data object as a string. | String | {"key":"value"} |
| state | The state of the Flow at input. | String | default |
| mode | The mode of the input. | String | TextOnly |
| userType | The type of the connecting user. Either external for external user or admin for admin user. |
String | external |
| channel | The channel through which the record was received. | String | |
| flowLanguage | The language of the Flow. | String | en-EN |
| intent | The found Intent. This field can be empty. | String | orderFood |
| intentFlow | The Parent ID of the Flow in which the Intent was found. This field can be empty. | String | 5e33b160e6236da3aa54221461a53f04 |
| intentScore | The numerical score of the input against a recognized Intent. This field can be empty. | Number | 0.836322430892043 |
| completedGoalsList | A list of completed tasks in this session. If you have the goals feature enabled, use the Goals collection through the OData 2.4 endpoint. | String | orderedFood |
| foundSlots | Found Slot tags. | String | DATE |
| foundSlotDetails | Found Slot tags with details. | String | DATE[2018-2-25T12:32:32.000] |
| timestamp | The date and time of the input. | DateTime | 2018-2-25T12:32:32.000Z |
| executionTime | The time it took to execute the Flow in milliseconds. | Number | 32 |
| execution | The Flow execution count. | Number | 3 |
| custom1 | The custom value created by the Flow. The custom field has a maximum character limit of 1024. | String | custom value |
| custom2 | The custom value created by the Flow. The custom field has a maximum character limit of 1024. | String | custom value |
| custom3 | The custom value created by the Flow. The custom field has a maximum character limit of 1024. | String | custom value |
| custom4 | The custom value created by the Flow. The custom field has a maximum character limit of 1024. | String | custom value |
| custom5 | The custom value created by the Flow. The custom field has a maximum character limit of 1024. | String | custom value |
| custom6 | The custom value created by the Flow. The custom field has a maximum character limit of 1024. | String | custom value |
| custom7 | The custom value created by the Flow. The custom field has a maximum character limit of 1024. | String | custom value |
| custom8 | The custom value created by the Flow. The custom field has a maximum character limit of 1024. | String | custom value |
| custom9 | The custom value created by the Flow. The custom field has a maximum character limit of 1024. | String | custom value |
| custom10 | The custom value created by the Flow. The custom field has a maximum character limit of 1024. | String | custom value |
| localeReferenceId | The reference ID for the locale. | String | 4bfdcf40-a605-4686-8e92-b17fa9f178af |
| localeName | The name of the locale. | String | English |
| endpointUrlToken | The URL token for the Endpoint. | String | ea30b8f20db52f9d86ea36fd55a7d66bd2c4c60eb24ac7ad52f1c9e173dd4cdb |
| endpointName | The name of the Endpoint. | String | MyEndpoint |
| rating | The rating for the session: -1 for a negative rating or 1 for a positive rating. | Number | 1 |
| ratingComment | The comment left when given a rating. | String | Great service! |
| snapshotName | The name for the Snapshot used by the Endpoint. | String | Bot Release 2.2 |
The Analytics step label can be updated from the Cognigy.AI UI at any time.
Therefore, to ensure compatibility between past and future data records, the entityReferenceId field is used.
This field corresponds to either the Node ID or Intent ID assigned as an Analytics step.
The current Analytics step label can be retrieved
by mapping the entityReferenceID field to the Steps record.
Conversations
The Conversations collection offers a log of all session messages, including messages from the end user, AI Agent, and human agent. Each time one of these sources sends a message to a Flow, Cognigy.AI creates a record to log the interaction. Each interaction is logged as a single record.RequestsSelect an API request to extract data from the collection. The API version in the request must match your Cognigy.AI version.
OData 2.4
OData 2.3
https://odata-trial.cognigy.ai/v2.4/Conversations?apikey=<your-api-key>
https://odata-trial.cognigy.ai/v2.3/Conversations?apikey=<your-api-key>
ResponseWhen retrieving this collection, the endpoint returns the following fields:
Response Fields
| Field Name | Description | Type | Example |
|---|---|---|---|
| id | The unique ID of the record. Applicable to the OData endpoint 2.4 or later. | String | 5a91d194fde28b0011ce2423 |
| _id | The unique ID of the record. Applicable to the OData endpoint 2.3 or earlier. | String | 5a91d194fde28b0011ce2423 |
| projectId | The ID of the Project related to the record. | String | 5a91d194fde28b0011ce2422 |
| projectName | The name of the Project. | String | Project 1 |
| inputId | The ID of the input message. | String | 5a91d194fde28b0011ce2424 |
| sessionId | The session ID. | String | 5a91d194fde28b0011ce2425 |
| contactId | The ID of the connecting user. | String | myContactID |
| organisation | The name of your organization. | String | cognigy |
| inputText | The input text. | String | Hello World! |
| inputData | The input data object as a string. | String | {"key":"value"} |
| type | Whether the message is an input or output of the Flow. | String | ”input” or “output” |
| source | The source of the message. | String | ”user” or “bot” or “agent” or “suggestion” |
| timestamp | The date and time of the input. | DateTime | 2018-2-25T12:32:32.000Z |
| flowName | The name of the Flow. | String | MainFlow |
| flowParentId | The Parent ID of the Flow. | String | 5e33b160e6236da3aa54221461a53f04 |
| channel | The channel through which the record was received. | String | |
| inHandoverRequest | A flag indicating whether the session is in a handover request. | Boolean | false |
| inHandoverConversation | A flag indicating whether the session is in a handover session. | Boolean | true |
| outputId | The output ID. | String | f514b7b2-7dc0-4e75-be62-a53fed5b2bb7 |
| inputAttachments | The list of attachments that the end user uploads to the chat. Each attachment will contain the URL of the file, file name, and file type. When a human agent uploads a file, it will be recorded in the OData format as follows, without any specific information about the file: [{"*****":"*****"}]. |
Object | {"url":"https://files-api-trial.cognigy.ai/v1.0/63babf6e92add771923e87b7/","name":"abandon-rate.png","type":"image"} |
| reference | The Reference ID. For example, to reference a suggestion. | String | null |
| localeReferenceId | The ID of the locale. | String | 7eff993c-b801-4556-b111-1c319e8577cf |
| endpointUrlToken | The URL token for the Endpoint. | String | ea30b8f20db52f9d86ea36fd55a7d66bd2c4c60eb24ac7ad52f1c9e173dd4cdb |
| endpointName | The name of the Endpoint. | String | MyEndpoint |
| snapshotId | The ID of the Snapshot. | String | 63ff0cc47a466cab278fd19b |
| snapshotName | The name of the Snapshot. | String | Bot Release 2.2 |
| rating | The rating for the session: -1 for a negative rating or 1 for a positive rating. | Number | 1 |
| ratingComment | The comment left when given a rating. | String | Great service! |
Steps
The Steps collection provides a list of all entities, which are either Nodes or Intents, assigned as Analytics Steps within any Flow. An Analytics step appear in this OData collection only after it has been triggered at least once in a session within the Flow. Each step is logged as a single record.RequestsSelect an API request to extract data from the collection. The API version in the request must match your Cognigy.AI version.
OData 2.4
OData 2.3
https://odata-trial.cognigy.ai/v2.4/Steps?apikey=<your-api-key>
https://odata-trial.cognigy.ai/v2.3/Steps?apikey=<your-api-key>
ResponseWhen retrieving this collection, the endpoint returns the following fields:
Response Fields
| Field Name | Description | Type | Example |
|---|---|---|---|
| id | The unique ID of the record. Applicable to the OData endpoint 2.4 or later. | String | 5a91d194fde28b0011ce2423 |
| _id | The unique ID of the record. Applicable to the OData endpoint 2.3 or earlier. | String | 5a91d194fde28b0011ce2423 |
| label | The Analytics step label defined for the entity (Node or Intent) in Cognigy.AI. | String | Question (2) |
| type | The type of entity. | String | node or intent |
| entityReferenceId | The unique ID for the entity (Node ID or Flow ID). | String | 5a91d194fde28b0011ce2423 |
| flowReferenceId | The ID of the Flow. | String | 5a91d194fde28b0011ce2423 |
| flowName | The name of the Flow where the Analytics step is configured. | String | Main Flow |
| projectName | The name of the Project. | String | Project 1 |
| snapshotId | The ID of the Snapshot. | String | 5e33b160e6236da3aa54221461a53f04 |
| snapshotName | The name of the Snapshot. | String | Bot Release 2.2 |
The Step Monitoring with OData article explains how these records can be manipulated in BI software to build insightful session path analytics.
ExecutedSteps
The ExecutedSteps collection logs all step events in sessions, including a reference to the prior (parent) step. Whenever a Node or Intent with an assigned step is executed, the collection creates a record for that step. Each step is logged as a single record.
OData 2.4
OData 2.3
https://odata-trial.cognigy.ai/v2.4/ExecutedSteps?apikey=<your-api-key>
https://odata-trial.cognigy.ai/v2.3/ExecutedSteps?apikey=<your-api-key>
ResponseWhen retrieving this collection, the endpoint returns the following fields:
Response Fields
| Field Name | Description | Type | Example |
|---|---|---|---|
| id | The unique ID of the record. Applicable to the OData endpoint 2.4 or later. | String | 5a91d194fde28b0011ce2423 |
| _id | The unique ID of the record. Applicable to the OData endpoint 2.3 or earlier. | String | 5a91d194fde28b0011ce2423 |
| userId | The ID of the connecting user. | String | myContactID |
| sessionId | The session ID. | String | 5a91d194fde28b0011ce2425 |
| inputId | The ID of the input message. | String | 5a91d194fde28b0011ce2425 |
| stepLabel | The Analytics step label defined for the entity (Node or Intent) | String | Question (2) |
| parentStep | The ID of the step that occurred prior to this step. | String | 5a91d194fde28b0011ce2425 |
| type | The type of entity. | String | node or intent |
| entityReferenceId | The unique ID for the entity (Node ID or Intent ID). | String | 5a91d194fde28b0011ce2423 |
| flowReferenceId | The ID of the Flow. | String | 5a91d194fde28b0011ce2423 |
| flowName | The name of the Flow where the step exists. | String | Main Flow |
| timestamp | The date and time when the step was executed. | DateTime | 2018-2-25T12:32:32.000Z |
| projectName | The name of the Project. | String | Project 1 |
| projectId | The ID of the Project related to the record. | String | 6067352c18887e471da4e392 |
| organisationId | The ID of the organization associated with the record. | String | 5f8833dae72b850ad2ed4d53 |
| snapshotId | The ID of the Snapshot. | String | 5e33b160e6236da3aa54221461a53f04 |
| snapshotName | The name of the Snapshot. | String | Bot Release 2.2 |
| localeReferenceId | The ID of the locale. | String | 7eff993c-b801-4556-b111-1c319e8577cf |
| localeName | The name of the locale. | String | English |
| endpointUrlToken | The URL token for the Endpoint. | String | ea30b8f20db52f9d86ea36fd55a7d66bd2c4c60eb24ac7ad52f1c9e173dd4cdb |
| endpointName | The name of the Endpoint. | String | MyEndpoint |
Sessions
The Sessions collection contains a list of all sessions that have occurred.
The primary objective of this collection is
to provide a list of the Analytics steps that took place in any given session, along with the order of execution.
This information is included as a comma-separated list within a field called stepPath.
Each session is logged as a single record.
OData 2.4
OData 2.3
https://odata-trial.cognigy.ai/v2.4/Sessions?apikey=<your-api-key>
https://odata-trial.cognigy.ai/v2.3/Sessions?apikey=<your-api-key>
ResponseWhen retrieving this collection, the endpoint returns the following fields:
Response Fields
| Field Name | Description | Type | Example |
|---|---|---|---|
| id | The unique ID of the record. Applicable to the OData endpoint 2.4 or later. | String | 5a91d194fde28b0011ce2423 |
| _id | The unique ID of the record. Applicable to the OData endpoint 2.3 or earlier. | String | 5a91d194fde28b0011ce2423 |
| goals | All the goals that were achieved in the session. | String | Goal1, Goal2 |
| stepPath | A comma-separated list of executed steps. | String | 9ac4f679-beae-4461-b9e3-43aece8b3430,f1e72fe3-f04b-48f5-b862-1e35ad253f18, … |
| stepsCount | The count of the number of steps. | Number | 10 |
| handoverEscalations | The number of times the session triggered a handover. | Number | 3 |
| startedAt | The date and time when first message was received. | DateTime | 2018-2-25T12:32:32.000Z |
| userId | The ID of the connecting user. | String | myContactID |
| sessionId | The session ID. | String | 5a91d194fde28b0011ce2425 |
| localeReferenceId | The ID of the locale. | String | 7eff993c-b801-4556-b111-1c319e8577cf |
| localeName | The name of the locale. | String | English |
| endpointReferenceId | The ID of the Endpoint. | String | 5e33b160e6236da3aa54221461a53f04 |
| endpointName | The name of the Endpoint. | String | Webchat |
| projectName | The name of the Project. | String | Project 1 |
| projectId | The ID of the Project related to the record. | String | 6067352c18887e471da4e392 |
| organisationId | The ID of the organization associated with the record. | String | 5f8833dae72b850ad2ed4d53 |
| snapshotId | The ID of the Snapshot. | String | 5e33b160e6236da3aa54221461a53f04 |
| snapshotName | The name of the Snapshot. | String | Bot Release 2.2 |
| endpointUrlToken | The URL token for the Endpoint. | String | ea30b8f20db52f9d86ea36fd55a7d66bd2c4c60eb24ac7ad52f1c9e173dd4cdb |
| rating | The rating for the session: -1 for a negative rating or 1 for a positive rating. | Number | 1 |
| ratingComment | The comment left when given a rating. | String | Great service! |
LiveAgentEscalations
The LiveAgentEscalations collection contains records from Cognigy Live Agent and includes the related data about handovers to Live Agent. Each handover (escalation) is logged as a single record.
OData 2.4
OData 2.3
https://odata-trial.cognigy.ai/v2.4/LiveAgentEscalations?apikey=<your-api-key>
https://odata-trial.cognigy.ai/v2.3/LiveAgentEscalations?apikey=<your-api-key>
ResponseWhen retrieving this collection, the endpoint returns the following fields:
Response Fields
| Field Name | Description | Type | Example |
|---|---|---|---|
| id | The unique ID of the record. Applicable to the OData endpoint 2.4 or later. | String | 5a91d194fde28b0011ce2423 |
| _id | The unique ID of the record. Applicable to the OData endpoint 2.3 or earlier. | String | 5a91d194fde28b0011ce2423 |
| organisationId | The ID of the organization associated with the record. | String | 5eb4a49d426cd3d05f2892a9 |
| projectId | The ID of the Project related to the record. | String | 6409b6c53c9687b5e78e6403 |
| sessionId | The session ID. | String | session-2a38246e-0395-49a5-876d-dd5133fd5418 |
| timestamp | The date and time when the record was created. | DateTime | 2023-06-28T07:59:04.628Z |
| localeName | The name of the locale. | String | en |
| status | The current status of the escalated conversation in Live Agent. The possible statures are: opened, assigned, resolved, and abandoned. |
String | opened |
| inboxId | The ID of the inbox associated with the record. | String | 7983 |
| inboxName | The name of the inbox. | String | LA Chatbot-default |
| teamId | The ID of the team assigned to the conversation. | String | 8 |
| teamName | The name of the team assigned to the conversation. | String | IT Support |
| labels | The list of labels assigned to the conversation. | Array | [Hardware] |
| agentId | The ID of the human agent assigned to the conversation. | String | 618cf7687614774ba028dcac |
| agentName | The name of the human agent assigned to the conversation. This field is supported from Cognigy.AI 4.80. | String | John Doe |
| contactId | The ID of the connecting user. | String | 649ba8450d5df5cadf8b75b8 |
| endpointName | The name of the Endpoint. | String | LA Chatbot |
| endpointType | The type of the Endpoint. | String | webchat2 |
| endpointUrlToken | The URL token for the Endpoint. | String | ea30b8f20db52f9d86ea36fd55a7d66bd2c4c60eb24ac7ad52f1c9e173dd4cdb |
| channel | The channel through which the record was received. | String | admin-webchat |
| localeReferenceId | The ID of the locale. | String | 7eff993c-b801-4556-b111-1c319e8577cf |
| snapshotId | The ID of the Snapshot. | String | 63ff0cc47a466cab278fd19b |
| snapshotName | The name of the Snapshot. | String | Prod-Snapshot 26.7.23 |
Goals
The Goals collection contains records from goals. Each goal is logged as a single record.
- OData 2.4
https://odata-trial.cognigy.ai/v2.4/Goals?apikey=<your-api-key>
ResponseWhen retrieving this collection, the endpoint returns the following fields:
Response Fields
| Field Name | Description | Field Type | Example |
|---|---|---|---|
| goalId | The goal ID. | String | 66ebf71693dfb26c3ca4c827 |
| name | The name of the goal. | String | Goal_07 |
| version | The UUID for tracking the current version of the goal configuration. Each update or change of the goal configuration creates a new version. | String | 8ec4de84-71e2-4c98-a7c3-b18173f36223 |
| description | The description of the goal. | String | The goal is to gather metrics for a flight booking use case. |
| referenceId | The Reference ID associated with the goal. | String | 04dd272f-6c8c-4957-9714-937e6f0847c2 |
| projectId | The ID of the Project related to the record. | String | 5a91d194fde28b0011ce2422 |
| organisationId | The ID of the organization associated with the record. | String | 5eb4a49d426cd3d05f2892a9 |
| createdAt | Timestamp indicating when the goal was created. | Timestamp | 2024-09-19T10:04:06.000Z |
| lastChanged | Timestamp of the last update to the goal. | Timestamp | 2024-09-19T10:04:06.000Z |
| createdBy | The identifier for the user who created the goal. | String | 63bff78cd74f7c7f7dd12944 |
| lastChangedBy | The identifier for the user who last modified the goal. | String | 63bff78cd74f7c7f7dd12944 |
GoalSteps
The GoalSteps collection contains records about a specific Goal step from goals. Each goal is logged as a single record.
- OData 2.4
https://odata-trial.cognigy.ai/v2.4/GoalSteps?apikey=<your-api-key>
ResponseWhen retrieving this collection, the endpoint returns the following fields:
Response Fields
| Field Name | Description | Field Type | Example |
|---|---|---|---|
| goalStepId | The goal step ID. | String | 66eac7950dc3fd6e4b3bcd8c |
| name | The name of the goal step. | String | Start |
| version | The UUID for tracking step the version of the specific step configuration within the goal. Each update or change of the goal configuration creates a new version. | String | 6cb467d0-9f79-4df0-ad31-991d1bb91910 |
| description | The description of the goal step. | String | The goal is to gather metrics for a flight booking use case. |
| order | The order of the step within the goal configuration. | Integer | null |
| text | Additional text information for the goal step | String | null |
| type | The type of the goal step: start — the initial (first) step of the goal. It shows the beginning of the process.completion — the completion (last) step of the goal. It shows that the objectives are met. |
String | start |
| goalId | The goal ID for the goal associated with the step. | String | 66eac7950dc3fdb39c3bcd8b |
| projectId | The ID of the Project related to the record. | String | 5a91d194fde28b0011ce2422 |
| organisationId | The ID of the organization associated with the record. | String | 5eb4a49d426cd3d05f2892a9 |
GoalStepMetrics
The GoalStepMetrics collection contains records about specific goal-related events from goals. Each metric is logged as a single record.
- OData 2.4
https://odata-trial.cognigy.ai/v2.4/GoalStepMetrics?apikey=<your-api-key>
ResponseWhen retrieving this collection, the endpoint returns the following fields:
Response Fields
| Field Name | Description | Field Type | Example |
|---|---|---|---|
| goalStepMetricId | The metric ID for the goal step. | String | 66ebf5a2cabacf6ecb0b5a81 |
| name | The name of the metric. | String | null |
| version | The UUID for tracking step the version of the specific metric configuration within the goal. Each update or change of the goal configuration creates a new version. | String | 6cb467d0-9f79-4df0-ad31-991d1bb91910 |
| description | The description of the metric. | String | null |
| type | The category of metrics that can be tracked for goals: - duration — time in minutes or hours.- currency — currency specified in the Project settings. |
String | currency |
| value | The value of the metric. | Integer | 20 |
| goalId | The goal ID. | String | 66ebf5a2cabacf2ac70b5a7e |
| goalStepId | The goal step ID. | String | 66ebf5a2cabacf7c810b5a80 |
| projectId | The ID of the Project related to the record. | String | 5a91d194fde28b0011ce2422 |
| organisationId | The ID of the organization associated with the record. | String | 5eb4a49d426cd3d05f2892a9 |
GoalEvents
The GoalEvents collection contains records about specific goal-related events from goals. Each event is logged as a single record.
- OData 2.4
https://odata-trial.cognigy.ai/v2.4/GoalEvents?apikey=<your-api-key>
ResponseWhen retrieving this collection, the endpoint returns the following fields:
Response Fields
| Field Name | Description | Field Type | Example |
|---|---|---|---|
| id | The unique ID of the record. Applicable to the OData endpoint 2.4 or later. | String | 5a91d194fde28b0011ce2423 |
| version | The UUID for tracking the current version of the goal configuration. Each update or change of the goal configuration creates a new version. | String | 8ec4de84-71e2-4c98-a7c3-b18173f36223 |
| timestamp | The date and time indicating when a specific event related to the goal occurred. | Timestamp | 2024-09-19T10:00:02.322Z |
| goalCycleId | The ID of the goal cycle to track each iteration of a goal. The cycle groups different goal tracking events into one attempt to complete a goal. | String | a0da54a5-ee2e-43be-b743-23d4bccf513c |
| stepId | The ID of the specific goal step. | String | 66ebeca3cabacf41170b4a6d |
| goalId | The goal ID. | String | 66ebeca3cabacf6c820b4a6c |
| sessionId | The session ID. | String | session-2a38246e-0395-49a5-876d-dd5133fd5418 |
| projectId | The ID of the Project related to the record. | String | 5a91d194fde28b0011ce2422 |
| organisationId | The ID of the organization associated with the record. | String | 5eb4a49d426cd3d05f2892a9 |
| expiresAt | The expiration date for the goal record. After that time, the goal record will be removed from the Analytics database. | Timestamp | null |
| localeName | The name of the locale. | String | English |
| endpointName | The name of the Endpoint. | String | LA Chatbot |
| endpointType | The type of the Endpoint. | String | webchat2 |
| endpointUrlToken | The URL token for the Endpoint. | String | ea30b8f20db52f9d86ea36fd55a7d66bd2c4c60eb24ac7ad52f1c9e173dd4cdb |
| channel | The channel through which the record was received. | String | admin-webchat |
| localeReferenceId | The ID of the locale. | String | 7eff993c-b801-4556-b111-1c319e8577cf |
| snapshotId | The ID of the Snapshot. | String | 63ff0cc47a466cab278fd19b |
| snapshotName | The name for the Snapshot used by the Endpoint. | String | Bot Release 2.2 |
Cognigy.AI OData Collections: Entity Relationship Diagram (ERD)
The Entity Relationship Diagram (ERD) describes the relationships between the collection entities.
logs messages
executes
summarized by
escalates via
tracks goals via
executed as
parentStep (self)
has
measured by
tracked by
measured by
Sessions
string
id
PK
string
sessionId
UK
string
userId
string
goals
string
stepPath
number
stepsCount
datetime
startedAt
string
projectId
string
organisationId
string
more
...
Conversations
string
id
PK
string
sessionId
FK
string
inputId
string
type
string
source
string
inputText
datetime
timestamp
string
projectId
string
organisation
string
more
...
ExecutedSteps
string
id
PK
string
sessionId
FK
string
parentStep
FK
string
entityReferenceId
FK
string
flowReferenceId
string
stepLabel
datetime
timestamp
string
projectId
string
organisationId
string
more
...
Analytics
string
id
PK
string
sessionId
FK
string
flowReferenceId
string
organisation
string
projectId
string
intent
string
completedGoalsList
datetime
timestamp
number
executionTime
string
more
...
LiveAgentEscalations
string
id
PK
string
sessionId
FK
string
organisationId
string
projectId
string
status
string
teamName
string
agentName
datetime
timestamp
string
more
...
GoalEvents
string
id
PK
string
goalId
FK
string
sessionId
FK
string
stepId
string
goalCycleId
string
version
datetime
timestamp
string
projectId
string
organisationId
string
more
...
Steps
string
id
PK
string
entityReferenceId
UK
string
flowReferenceId
string
label
string
type
string
flowName
string
projectName
string
more
...
Goals
string
goalId
PK
string
name
string
version
string
referenceId
string
projectId
string
organisationId
datetime
createdAt
string
more
...
GoalSteps
string
goalStepId
PK
string
goalId
FK
string
name
string
type
int
order
string
projectId
string
organisationId
string
more
...
GoalStepMetrics
string
goalStepMetricId
PK
string
goalId
FK
string
goalStepId
FK
string
name
string
type
int
value
string
projectId
string
organisationId
string
more
...
Legend
string
info
One-to-Many: ||--o{ (1..*)
string
info2
One-to-One: O--O (1..1)
string
info3
Many-to-Many: }o--o{ ( ..)
string
info4
Optional-to-One: |o--|| (0..1)
string
info5
Strong One-to-One: ||--||
string
abbr
PK=Primary Key, FK=Foreign Key, UK=Unique Key
Integrations
The Cognigy.AI OData endpoint can integrate with all tools compatible with the OData protocol version 4. The table outlines popular integration tools, including data visualization tools, recommended for integration.
| Tool | Description |
|---|---|
| Microsoft Excel | Microsoft Excel is a spreadsheet application widely used for data analysis and reporting. When connecting from Microsoft Excel 2016, use the PowerQuery feature, which can be found under Data > Get & Transform > New Query > From Other Sources > From OData Feed. |
| Microsoft Power BI | Microsoft Power BI is a business analytics service that provides interactive visualizations and business intelligence capabilities. For integrating with the Cognigy.AI OData endpoint, refer to the Microsoft Power BI documentation. |
| OData Consumer Ecosystem | The OData Consumer Ecosystem encompasses a variety of tools and applications that support the consumption of OData services. For a full list of available OData Consumer options, refer to the OData documentation. |
| Client Libraries in .NET, Java, JavaScript, C++ and other platforms | Client libraries are available in multiple programming languages and platforms, providing developers with OData protocol implementations. For a full list of available libraries, refer to the OData documentation. |
If you want to use another tool not listed in the table, verify its compatibility with the OData endpoint on the OData website and in the tool’s documentation before integrating. For example, the data visualization tool Tableau can’t be used for integration because it doesn’t support the OData protocol version 4 on which the OData endpoint is based.
Keyset Pagination
Keyset pagination is a more efficient way to retrieve data from large datasets where you need to set $skip to high values, such as 10000. To use keyset pagination, follow these steps:
Keyset Pagination
- Retrieve the first page with the
$topand$orderbyquery options, for example,https://odata-trial.cognigy.ai/v2.4/Conversations?apikey=<your-api-key>&$top=10000&$orderby=timestamp asc. - Use the last
timestampvalue from the previous page in the next page request, for example,https://odata-trial.cognigy.ai/v2.4/Conversations?apikey=<your-api-key>&$filter=timestamp gt <LAST_TIMESTAMP_FROM_PREVIOUS_PAGE>&$top=10000&$orderby=timestamp asc. - Repeat step 2 until you have retrieved all the records.
More Information
1: Microsoft Excel and Power BI do not support for the $count query. Use Postman or other options. To perform this query, consider using tools such as Postman or other applications that support advanced API querying.
Last modified onJune 29, 2026
Previous Call TracingRecord and debug voice AI Agent calls with the Call Tracing feature.\ \ Next
Ctrl+I
ChatVoice
Click the call button to start talking.
Cognigy AssistantReady to talk
Connecting…
Powered by Cognigy.AI
Cookie Consent
We use cookies to recognize your repeated visits and preferences, as well as to measure the effectiveness of our documentation and whether users find what they're searching for.
With your consent, you're helping us make our documentation better. To find out more about the cookies we use, see our Privacy Policy.
Accept
'; cachedClickBlockingCode = css + js; return cachedClickBlockingCode; }
// Helper: Inject click-blocking code into iframe function injectClickBlocking(iframeDoc) { if (!iframeDoc || !iframeDoc.head) return false;
try { const style = iframeDoc.createElement('style'); style.textContent = 'a,button,input,select,textarea,[onclick],[role="button"],input[type="button"],input[type="submit"],[href],[tabindex]:not([tabindex="-1"]){pointer-events:none!important;cursor:default!important}a:hover,button:hover{cursor:default!important;opacity:0.7!important}'; iframeDoc.head.appendChild(style);
const script = iframeDoc.createElement('script'); script.textContent = '(function(){var preventClick=function(e){e.preventDefault();e.stopPropagation();e.stopImmediatePropagation();return false;};document.addEventListener("click",preventClick,true);document.addEventListener("mousedown",preventClick,true);document.addEventListener("mouseup",preventClick,true);document.addEventListener("touchstart",preventClick,true);document.addEventListener("touchend",preventClick,true);document.addEventListener("contextmenu",preventClick,true);window.addEventListener("beforeunload",function(e){e.preventDefault();e.returnValue="";return "";},true);try{Object.defineProperty(window,"location",{value:{href:"#",replace:function(){},assign:function(){}},writable:false,configurable:false});}catch(e){}var originalPushState=history.pushState;history.pushState=function(){return false;};var originalReplaceState=history.replaceState;history.replaceState=function(){return false;};var originalOpen=window.open;window.open=function(){return null;};var allElements=document.querySelectorAll("*");for(var i=0;i 0 || replacedViewers.length > 0) { const currentUrl = window.location.href; if (!processedUrls.has(currentUrl)) { processedUrls.add(currentUrl); lastUrl = currentUrl; } return; }
const currentUrl = window.location.href; if (currentUrl === lastUrl && lastUrl !== null && processedUrls.has(currentUrl)) { return; }
// Optimized: Use cached viewer query const viewers = getUninitializedViewers();
if (viewers.length === 0) { if (periodicCheckInterval) { clearInterval(periodicCheckInterval); periodicCheckInterval = null; } return; }
// Final safety check if (viewers.length > 0) { if (currentUrl === lastUrl && lastUrl !== null && processedUrls.has(currentUrl)) { viewers.forEach(function(viewer) { viewer.setAttribute('data-initialized', 'true'); }); return; }
if (currentUrl === lastUrl && lastUrl !== null) { if (existingContainers.length > 0) { processedUrls.add(currentUrl); viewers.forEach(function(viewer) { viewer.setAttribute('data-initialized', 'true'); }); return; } } }
isInitializing = true; let processedAny = false;
// Optimized: Process viewers in batch viewers.forEach(function(viewer) { if (processedElements.has(viewer) || viewer.hasAttribute('data-initialized')) { return; }
if (viewer.closest('.single-page-viewer-container')) { return; }
if (!viewer.parentNode) { return; }
const isInContentArea = contentArea === document.body || contentArea.contains(viewer); if (!isInContentArea) { return; }
const src = viewer.getAttribute('data-src'); const hint = viewer.getAttribute('data-hint') || ''; const defaultZoom = parseFloat(viewer.getAttribute('data-zoom')) || DEFAULT_ZOOM; const dataHeight = viewer.getAttribute('data-height'); const height = dataHeight ? parseFloat(dataHeight) : null;
if (!src) { // Don't set isInitializing = false here - it affects all viewers in the loop return; }
processedElements.add(viewer); viewer.setAttribute('data-initialized', 'true');
let zoom = defaultZoom;
// Optimized: Use document fragment for DOM construction const fragment = document.createDocumentFragment(); const container = document.createElement('div'); container.className = 'single-page-viewer-container';
const wrapper = document.createElement('div'); wrapper.className = 'single-page-viewer-wrapper';
const controlsBar = document.createElement('div'); controlsBar.className = 'single-page-viewer-controls';
if (hint) { const hintDiv = document.createElement('div'); hintDiv.className = 'single-page-viewer-hint'; hintDiv.innerHTML = '' + hint + ''; controlsBar.appendChild(hintDiv); }
const iframeWrapper = document.createElement('div'); iframeWrapper.className = 'single-page-viewer-iframe-wrapper'; iframeWrapper._scrollHandlerAdded = false;
// Optimized: Get height without temporary DOM manipulation const baseHeightFromCSS = height || NORMAL_HEIGHT;
const scaleDiv = document.createElement('div'); scaleDiv.className = 'single-page-viewer-scale'; const initialHeight = baseHeightFromCSS; scaleDiv.style.cssText = 'transform: scale(' + zoom + '); transform-origin: top left; width: ' + (100 / zoom) + '%; height: ' + initialHeight + 'px; transition: transform 0.2s ease;';
const iframe = document.createElement('iframe'); let iframeSrc = src; if (iframeSrc && !iframeSrc.startsWith('http') && !iframeSrc.startsWith('//')) { if (!iframeSrc.startsWith('/')) { iframeSrc = '/' + iframeSrc; } }
iframe.title = 'Single Page Viewer'; iframe.className = 'single-page-viewer-iframe'; iframe.style.width = '100%'; iframe.style.height = initialHeight + 'px'; iframe.loading = 'lazy'; iframe.setAttribute('scrolling', 'no'); iframe.setAttribute('sandbox', 'allow-same-origin allow-scripts allow-forms allow-popups allow-modals');
const clickBlocker = document.createElement('div'); clickBlocker.className = 'single-page-viewer-click-blocker';
if (iframeSrc.endsWith('.html') && !iframeSrc.startsWith('http')) { fetch(iframeSrc) .then(function(response) { return response.text().then(function(htmlContent) { if (htmlContent.includes('Page Not Found') || (htmlContent.includes('__next') && htmlContent.includes('mintlify') && !htmlContent.includes('Page saved with SingleFile'))) { throw new Error('Received 404 page instead of HTML file.'); } const blockingCode = getClickBlockingCode(); if (htmlContent.includes('')) { htmlContent = htmlContent.replace('', blockingCode + ''); } else if (htmlContent.includes('')) { htmlContent = htmlContent.replace('', '' + blockingCode); } else { if (htmlContent.includes('')) { htmlContent = htmlContent.replace('', '' + blockingCode + ''); } else { htmlContent = blockingCode + htmlContent; } } iframe.srcdoc = htmlContent; }); }); } else { iframe.src = iframeSrc; }
iframe.addEventListener('load', function() { setTimeout(function() { updateIframeDimensions(iframeWrapper, scaleDiv, iframe, zoom); }, 100);
try { const iframeDoc = iframe.contentDocument || iframe.contentWindow.document; injectClickBlocking(iframeDoc); } catch (e) { // Cross-origin iframe - cannot block clicks } }, { once: true });
iframe.addEventListener('error', function() { // Iframe failed to load - error handling is silent }, { once: true });
scaleDiv.appendChild(iframe); iframeWrapper.appendChild(scaleDiv); if (!iframeSrc.endsWith('.html') || iframeSrc.startsWith('http')) { iframeWrapper.appendChild(clickBlocker); }
if (hint) { wrapper.appendChild(controlsBar); } wrapper.appendChild(iframeWrapper); container.appendChild(wrapper); fragment.appendChild(container);
try { if (viewer.parentNode) { if (viewer === contentArea || viewer.id === 'content-area') { isInitializing = false; return; }
const viewerId = 'viewer-' + Date.now() + '-' + Math.random().toString(36).slice(2, 11); viewer.id = viewerId; viewer.setAttribute('data-viewer-id', viewerId); container.setAttribute('data-viewer-id', viewerId);
// Optimized: Single DOM insertion using fragment if (viewer.nextSibling) { viewer.parentNode.insertBefore(fragment, viewer.nextSibling); } else { viewer.parentNode.appendChild(fragment); }
// Batch style updates Object.assign(viewer.style, { display: 'none', visibility: 'hidden', position: 'absolute', width: '1px', height: '1px', overflow: 'hidden', opacity: '0', pointerEvents: 'none', margin: '0', padding: '0' });
viewer.setAttribute('data-initialized', 'true'); viewer.setAttribute('data-viewer-replaced', 'true');
processedAny = true; invalidateQueryCache();
requestAnimationFrame(function() { updateIframeDimensions(iframeWrapper, scaleDiv, iframe, zoom); }); } } catch (e) { isInitializing = false; return; } });
if (processedAny) { const currentUrl = window.location.href; processedUrls.add(currentUrl); lastUrl = currentUrl; invalidateQueryCache(); }
isInitializing = false; }
// Wait for content area to be available function waitForContentArea(callback, maxAttempts, attempt) { attempt = attempt || 0; maxAttempts = maxAttempts || 20;
const contentArea = document.querySelector('#content-area') || document.querySelector('.mdx-content');
if (contentArea && document.contains(contentArea)) { cachedContentArea = contentArea; callback(); } else if (attempt < maxAttempts) { setTimeout(function() { waitForContentArea(callback, maxAttempts, attempt + 1); }, 500); } else { cachedContentArea = document.body; callback(); } }
// Optimized: Initialize with better state management function initialize() { const currentUrl = window.location.href; if (lastUrl !== currentUrl && lastUrl !== null) { lastUrl = currentUrl; processedUrls.clear(); invalidateQueryCache(); }
if (typeof window !== 'undefined') { window.__lastFullUrl = window.location.href; }
if (lastThemeClass === null && document.documentElement) { lastThemeClass = document.documentElement.className; }
if (!themeObserver && document.documentElement) { themeObserver = new MutationObserver(function(mutations) { for (let i = 0; i < mutations.length; i++) { const mutation = mutations[i]; if (mutation.type === 'attributes' && mutation.attributeName === 'class') { const currentThemeClass = document.documentElement.className; if (lastThemeClass !== null && lastThemeClass !== currentThemeClass) { themeToggleInProgress = true;
// Optimized: Lock containers synchronously const contentArea = getContentArea(); if (contentArea) { const containers = getContainers(true); containers.forEach(function(container) { if (container.getAttribute('data-position-locked') !== 'true') { const rect = container.getBoundingClientRect(); Object.assign(container.style, { position: 'fixed', top: rect.top + 'px', left: rect.left + 'px', width: rect.width + 'px', zIndex: '9999', margin: '0' }); container.setAttribute('data-position-locked', 'true'); containerPositions.set(container, { top: rect.top, left: rect.left, width: rect.width, height: rect.height }); } }); }
let repositionAttempts = 0; const maxRepositionAttempts = 30;
const repositionInterval = setInterval(function() { repositionAttempts++; repositionContainersAfterThemeToggleCore(); // Use core function for immediate repositioning if (repositionAttempts >= maxRepositionAttempts) { clearInterval(repositionInterval); } }, 100);
setTimeout(function() { clearInterval(repositionInterval); themeToggleInProgress = false; repositionContainersAfterThemeToggleCore(); // Use core function for final repositioning unlockContainers(); }, 3000); } lastThemeClass = currentThemeClass; } } });
themeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] }); }
if (typeof MutationObserver !== 'undefined') { setupObserver(); }
waitForContentArea(function() { setTimeout(function() { initSinglePageViewers(); setTimeout(function() { const remaining = getUninitializedViewers(true); if (remaining.length > 0) { initSinglePageViewers(); } }, INIT_DELAY); }, INIT_DELAY); }); }
// Optimized: Lock/unlock containers function lockContainersInPlace() { const contentArea = getContentArea(); if (!contentArea) return;
const containers = getContainers(true); containerPositions.clear();
requestAnimationFrame(function() { containers.forEach(function(container) { if (container.getAttribute('data-position-locked') !== 'true') { const rect = container.getBoundingClientRect(); Object.assign(container.style, { position: 'fixed', top: rect.top + 'px', left: rect.left + 'px', width: rect.width + 'px', zIndex: '9999', margin: '0' }); container.setAttribute('data-position-locked', 'true'); containerPositions.set(container, { top: rect.top, left: rect.left, width: rect.width, height: rect.height }); } }); }); }
function unlockContainers() { const contentArea = getContentArea(); if (!contentArea) return;
const containers = Array.from( contentArea.querySelectorAll('.single-page-viewer-container[data-position-locked="true"]') );
containers.forEach(function(container) { Object.assign(container.style, { position: '', top: '', left: '', width: '', zIndex: '', margin: '' }); container.removeAttribute('data-position-locked'); // Clean up container position from Map to prevent memory leak containerPositions.delete(container); });
containerPositions.clear(); }
// Optimized: Reposition containers with better DOM operations // Core repositioning function (not debounced for immediate use) function repositionContainersAfterThemeToggleCore() { const contentArea = getContentArea(); if (!contentArea) return;
const containers = getContainers(true);
containers.forEach(function(container) { const viewerId = container.getAttribute('data-viewer-id'); if (!viewerId) return;
let viewer = document.getElementById(viewerId);
if (!viewer) { const iframe = container.querySelector('iframe'); if (iframe && iframe.src) { const allViewers = contentArea.querySelectorAll('[data-single-page-viewer]'); for (let i = 0; i < allViewers.length; i++) { const v = allViewers[i]; if (v.getAttribute('data-src') === iframe.src) { viewer = v; viewer.id = viewerId; viewer.setAttribute('data-viewer-id', viewerId); Object.assign(viewer.style, { display: 'none', visibility: 'hidden', position: 'absolute', width: '1px', height: '1px', overflow: 'hidden', opacity: '0', pointerEvents: 'none', margin: '0', padding: '0' }); viewer.setAttribute('data-initialized', 'true'); viewer.setAttribute('data-viewer-replaced', 'true'); break; } } } }
if (viewer && viewer.parentNode) { if (container.getAttribute('data-position-locked') === 'true') { unlockContainers(); }
const viewerIndex = Array.from(viewer.parentNode.children).indexOf(viewer); const containerIndex = Array.from(viewer.parentNode.children).indexOf(container);
if (containerIndex !== viewerIndex + 1) { // CRITICAL: Check if container is actually a child before removing if (container.parentNode && container.parentNode.contains(container)) { try { container.parentNode.removeChild(container); } catch (e) { return; // Skip repositioning if removal failed } } if (viewer.nextSibling) { viewer.parentNode.insertBefore(container, viewer.nextSibling); } else { viewer.parentNode.appendChild(container); } } else if (container.parentNode !== viewer.parentNode) { // CRITICAL: Check if container is actually a child before removing if (container.parentNode && container.parentNode.contains(container)) { try { container.parentNode.removeChild(container); } catch (e) { return; // Skip repositioning if removal failed } } if (viewer.nextSibling) { viewer.parentNode.insertBefore(container, viewer.nextSibling); } else { viewer.parentNode.appendChild(container); } } } });
invalidateQueryCache(); }
// Debounced version for non-critical repositioning const repositionContainersAfterThemeToggle = debounce(repositionContainersAfterThemeToggleCore, REPOSITION_DEBOUNCE);
// Optimized: Observer setup with better filtering let observer = null; let containerPositionObserver = null; let fallbackObserver = null; // Track fallback observer for cleanup
function setupContainerPositionObserver() { if (typeof MutationObserver === 'undefined') return;
const contentArea = getContentArea(); if (!contentArea || !document.contains(contentArea)) { setTimeout(setupContainerPositionObserver, 500); return; }
if (containerPositionObserver) { containerPositionObserver.disconnect(); }
containerPositionObserver = new MutationObserver(function(mutations) { if (themeToggleInProgress) { // Use core function (not debounced) for immediate repositioning during theme toggle requestAnimationFrame(repositionContainersAfterThemeToggleCore); return; }
let needsReposition = false; for (let i = 0; i < mutations.length && !needsReposition; i++) { if (mutations[i].type === 'childList') { needsReposition = true; } }
if (needsReposition) { clearTimeout(containerPositionObserver._timeout); containerPositionObserver._timeout = setTimeout(repositionContainersAfterThemeToggle, REPOSITION_DEBOUNCE); } });
containerPositionObserver.observe(contentArea, { childList: true, subtree: true, attributes: false, characterData: false });
containerPositionObserver._timeout = null; }
// Optimized: Main observer with better early exits function setupObserver() { if (typeof MutationObserver === 'undefined') return;
const contentArea = getContentArea(); if (!contentArea || !document.contains(contentArea)) { setTimeout(setupObserver, 500); return; }
if (contentArea === document.documentElement || contentArea === document.body) { return; }
if (observer) { const currentObserved = observer._observedElement; if (currentObserved === contentArea && document.contains(contentArea)) { return; } if (currentObserved) { observer.disconnect(); } observer = null; }
observer = new MutationObserver(function(mutations) { if (themeToggleInProgress) return;
let hasNewViewer = false; for (let i = 0; i < mutations.length && !hasNewViewer; i++) { const mutation = mutations[i]; if (mutation.addedNodes && mutation.addedNodes.length > 0) { for (let j = 0; j < mutation.addedNodes.length && !hasNewViewer; j++) { const node = mutation.addedNodes[j]; if (node.nodeType === 1 && node.hasAttribute && node.hasAttribute('data-single-page-viewer') && !node.hasAttribute('data-initialized') && !node.hasAttribute('data-viewer-replaced')) { hasNewViewer = true; } } } }
if (hasNewViewer) { // Use core function for immediate repositioning when new viewer detected repositionContainersAfterThemeToggleCore(); setTimeout(repositionContainersAfterThemeToggleCore, 10); setTimeout(repositionContainersAfterThemeToggleCore, 50); setTimeout(repositionContainersAfterThemeToggleCore, 200); }
clearTimeout(observerTimeout); observerTimeout = setTimeout(function() { if (themeToggleInProgress) return;
let hasNewViewer = false; for (let i = 0; i < mutations.length && !hasNewViewer; i++) { const mutation = mutations[i];
if (mutation.target === document.documentElement || mutation.target === document.body) { continue; }
if (mutation.type === 'attributes' && mutation.attributeName === 'class' && mutation.target === document.documentElement) { continue; }
if (mutation.type === 'attributes' && mutation.attributeName === 'data-initialized') { const target = mutation.target; if (target && target.hasAttribute && target.hasAttribute('data-single-page-viewer') && !target.hasAttribute('data-initialized')) { hasNewViewer = true; } }
if (mutation.addedNodes && mutation.addedNodes.length > 0) { for (let j = 0; j < mutation.addedNodes.length && !hasNewViewer; j++) { const node = mutation.addedNodes[j]; if (node.nodeType === 1 && node.hasAttribute && node.hasAttribute('data-single-page-viewer') && !node.hasAttribute('data-initialized')) { hasNewViewer = true; } } } }
if (hasNewViewer) { invalidateQueryCache(); initSinglePageViewers(); } }, OBSERVER_DEBOUNCE); });
observer.observe(contentArea, { childList: true, subtree: true, attributes: true, attributeFilter: ['data-initialized'], characterData: false });
observer._observedElement = contentArea; setupContainerPositionObserver(); }
function start() { setupObserver(); initialize(); }
function checkAndInitialize() { if (isInitializing) return;
const currentUrl = window.location.href; if (currentUrl === lastUrl && lastUrl !== null) { return; }
const contentArea = document.querySelector('#content-area') || document.querySelector('.mdx-content'); if (contentArea) { const viewers = getUninitializedViewers(true); if (viewers.length > 0) { cachedContentArea = contentArea; setupObserver(); initialize(); } } }
if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', start); } else { setTimeout(start, 100); }
if (typeof window !== 'undefined' && window.next) { let initialLoadAttempts = 0; const maxInitialAttempts = 4; const attemptDelays = [200, 500, 1000, 2000]; const initialUrl = window.location.href;
attemptDelays.forEach(function(delay) { setTimeout(function() { if (initialLoadAttempts < maxInitialAttempts) { initialLoadAttempts++; if (window.location.href === initialUrl) { checkAndInitialize(); } } }, delay); }); }
window.addEventListener('popstate', function(e) { const currentUrl = window.location.href; if (currentUrl !== lastUrl) { handleNavigation(); } });
if (typeof window !== 'undefined') { if (window.next && window.next.router && window.next.router.events) { window.next.router.events.on('routeChangeComplete', function(url) { lastUrl = window.location.href; isInitializing = false; pendingInitCall = false; if (navigationTimeout) { clearTimeout(navigationTimeout); navigationTimeout = null; } invalidateContentAreaCache(); invalidateQueryCache(); setTimeout(function() { setupObserver(); initialize(); }, 300); });
window.next.router.events.on('routeChangeStart', function(url) { isInitializing = false; pendingInitCall = false; }); }
if (!window.next || !window.next.router) { const originalPushState = history.pushState; const originalReplaceState = history.replaceState;
history.pushState = function() { originalPushState.apply(history, arguments); setTimeout(function() { if (window.location.href !== lastUrl) { handleNavigation(); } }, 0); };
history.replaceState = function() { originalReplaceState.apply(history, arguments); setTimeout(function() { if (window.location.href !== lastUrl) { handleNavigation(); } }, 0); }; } }
document.addEventListener('visibilitychange', function() { if (!document.hidden) { isInitializing = false; startPeriodicCheck(); if (!pendingInitCall) { pendingInitCall = true; setTimeout(function() { pendingInitCall = false; initSinglePageViewers(); }, INIT_DELAY / 2); } } });
function startPeriodicCheck() { if (periodicCheckInterval) return;
periodicCheckInterval = setInterval(function() { const uninitialized = getUninitializedViewers(true); if (uninitialized.length === 0) { clearInterval(periodicCheckInterval); periodicCheckInterval = null; } else if (!isInitializing) { initSinglePageViewers(); } }, 2000); }
setTimeout(startPeriodicCheck, INIT_DELAY * 2);
window.__singlePageViewerInit = function() { const currentUrl = window.location.href; if (currentUrl === lastUrl) { return; }
isInitializing = false; pendingInitCall = false; lastUrl = currentUrl; invalidateContentAreaCache(); invalidateQueryCache(); setupObserver(); initialize(); };
window.__singlePageViewerCheck = function() { invalidateQueryCache(); initSinglePageViewers(); }; })();
// Optimized: Second IIFE for navigation handling (function() { 'use strict';
let lastPathname = window.location.pathname; let lastInitializedPathname = window.location.pathname;
function checkAndInit() { const currentPathname = window.location.pathname; if (currentPathname === lastInitializedPathname) { return; }
lastInitializedPathname = currentPathname; if (typeof window !== 'undefined') { window.__lastFullUrl = window.location.href; }
if (window.__singlePageViewerInit) { window.__singlePageViewerInit(); } }
function runInit() { if (window.__singlePageViewerInit) { setTimeout(checkAndInit, 100); } else { let attempts = 0; const maxAttempts = 50; const checkInterval = setInterval(function() { attempts++; if (window.__singlePageViewerInit) { clearInterval(checkInterval); setTimeout(checkAndInit, 100); } else if (attempts >= maxAttempts) { clearInterval(checkInterval); } }, 100); } }
if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', runInit); } else { setTimeout(runInit, 100); }
if (typeof window !== 'undefined' && window.next && window.next.router && window.next.router.events) { window.next.router.events.on('routeChangeComplete', function(url) { lastPathname = window.location.pathname; setTimeout(checkAndInit, 300); }); }
setInterval(function() { const currentPathname = window.location.pathname; if (currentPathname !== lastPathname) { lastPathname = currentPathname; setTimeout(checkAndInit, 300); } }, 500);
if (typeof MutationObserver !== 'undefined') { let fallbackObserverTimeout = null; // Store in outer scope for cleanup tracking fallbackObserver = new MutationObserver(function(mutations) { if (fallbackObserverTimeout) { clearTimeout(fallbackObserverTimeout); } fallbackObserverTimeout = setTimeout(function() { const contentArea = document.querySelector('#content-area'); if (contentArea) { const uninitialized = contentArea.querySelectorAll( '[data-single-page-viewer]:not([data-initialized]):not(.single-page-viewer-container [data-single-page-viewer])' ); if (uninitialized.length > 0) { const currentPathname = window.location.pathname; if (currentPathname !== lastInitializedPathname) { setTimeout(checkAndInit, 200); } } } }, 500); });
if (document.body) { fallbackObserver.observe(document.body, { childList: true, subtree: true }); } else { document.addEventListener('DOMContentLoaded', function() { if (document.body) { fallbackObserver.observe(document.body, { childList: true, subtree: true }); } }); } } })();