NICE CXone Integration
Architecture Overview
The following diagram illustrates the end-to-end flow from the Chat Point of Contact within NICE CXone to your NeuralSeek mAIstro Agent via the Custom Exchange Endpoint.
Chat Point of Contact
The entry point where the customer initiates a conversation, typically via webchat, mobile app, or messaging platforms, connecting directly to NICE CXone.
Studio Script
NICE CXone Studio Script controls the flow of interactions, integrating the Custom Exchange Endpoint to send and receive user messages dynamically.
Custom Exchange Endpoint
Acts as the HTTP interface between CXone and external services, forwarding user requests to your Proxy Tunnel and handling responses from the Virtual Agent.
Proxy Tunnel
A secure communication channel used to connect NICE CXone’s environment to your backend services and Virtual Agent without exposing public endpoints.
Virtual Agent
Your AI-based chatbot or Virtual Assistant that processes user inputs and returns context-aware responses, integrated with NICE CXone through the Proxy Tunnel.
CXone Configuration
This section outlines the required CXone configuration settings for the Point of Contact integration.
NICE CXone Studio script
For the NeuralSeek integration test, you will use the standard VAHSampleChatScript
provided by NICE CXone. This script handles the communication between CXone Studio and your Virtual Agent via the Virtual Agent Hub (VAH) Custom Exchange Endpoint.
You can download the Studio Script from the official NICE CXone resources here:
The script manages:
- Handling inbound chat requests via ACD Chat channel.
- Exchanging messages with your NeuralSeek Virtual Agent through the VAH endpoint.
- Managing session flow and error handling within the CXone Studio environment.
The first part of the flow handles the welcome message intent, and the latter handles the following conversational flow between the user and the NeuralSeek mAIstro agent.
Studio script for production
No custom modifications to the script are required for basic integration testing with NeuralSeek. For production environments, you can extend or modify the script based on your specific business logic.
ACD Chat Configuration
Sample Configuration
Campaign:
- Campaign Name: Hospital Patient Digital Engagement
Skill:
- Media Type: Chat
- Skill Name: Chat - Appointment Scheduling
- Campaign: Hospital Patient Digital Engagement
Chat Profile:
- Profile Name: Chat Widget V2
- Interface: V2 (HTML5)
Point of Contact:
- Media Type: Chat
- Name: Chat - Home Page
- Point of Contact:
- Skill: Chat - Appointment Scheduling
- Script: VAHSampleChatScript
- Chat Profile: Chat Widget V2
Service Endpoint Authorization
The authorization mechanism for accessing the NeuralSeek Virtual Agent service endpoint is based on an API key passed through a custom request header.
Authorization Method
Header-based API Key authentication is used. This ensures secure and straightforward access control.
Required Header
apiKey
:<your-neuralseek-api-key>
The API key value will vary depending on the client and environment (staging or production).
No additional authentication mechanisms (such as OAuth) are required. This simplifies integration while maintaining secure access through per-client API key management.
Virtual Agent Hub Configuration
This section defines the necessary configuration for the Virtual Agent Hub (VAH) to connect with your NeuralSeek mAIstro Agent.
Webhook URL
Endpoint Parameters
- None required.
Custom Headers (Required for NeuralSeek)
apiKey
:<your-neuralseek-api-key>
overrideschema
:"true"
– Accepts the request schema coming from Virtual Agent Hub.overrideagent
:proxy_tunnel_v3_agent
– The mAistro agent.debug
:"true"
– Recommended during setup to include debug details; disable for production.
Timeout
- No change needed.
Integration Version
- Version 3.0.0 is recommended for this integration.
Authorization and OAuth
- No authorization header or OAuth configuration required.
Note
Make sure that each TextBot Exchange action in your NICE CXone script is linked to the Neuralkseek virtual agent. You’ll know it’s selected when you see the green check mark next to its name in the Virtual Agent Hub.
Proxy Tunnel
The NeuralSeek integration uses a pre-configured proxy tunnel agent called proxy_tunnel_v3_agent
.
This agent is designed to be compatible with CXone Textbot Exchange version 3.0, and also supports versions 1.0 and 2.0.
Version 3.0 is recommended for optimal flexibility and feature support.
Hosting
The proxy tunnel is hosted directly within NeuralSeek as a no-code Maistro agent, requiring no additional infrastructure from the client side.
This setup reduces maintenance overhead and allows for rapid customization.
Customization and Expansion
The proxy_tunnel_v3_agent
can be customized and extended within NeuralSeek to accommodate specific client use cases and workflows.
Failover Strategy
As the proxy tunnel is managed within NeuralSeek's cloud infrastructure, standard cloud resilience applies.
Clients do not need to set up a separate failover mechanism.
NeuralSeek Template Language (NTL)
NTL (NeuralSeek Template Language) is a simple, declarative language used to define NeuralSeek agents.
It allows you to easily share, customize, and extend agent behavior without writing complex code.
Below is the NTL configuration for the proxy_tunnel_v3_agent
used in this integration:
NTL Code Example
Below is an example of NeuralSeek Template Language (NTL) code.
You can copy it easily using the button provided.
Proxy tunnel mAIstro agent NTL (NeuralSeek Template Language)
<< name: botSessionState, prompt: false >>=>{{ jsonToVars }}
{{ condition | value: "'<< name: userInputType >>' == '5'" }}=>{{ variable | name: "nextPromptSequence" | value: "{\"prompts\":[{\"transcript\":\"Welcome to CareHaven Health, What can I do for you?\"}]}" }}=>{{ variable | name: "intentInfo" | value: "{\"Slots\": {},\"intent\":\"Welcome\",\"intentConfidence\":\"100\"}" }}
{{ condition | value: "'<< name: userInputType >>' == '1'" }}=>{{ seek | query: "<< name: followUpCategory, prompt: false >>
<< name: followUpQuery, prompt: false >><< name: userInput, prompt: false >>
<< name: followUpContext, prompt: false >><< name: dataPoints, prompt: false >>" }}=>{{ variable | name: "seekResult" }}
<< name: seekResult, prompt: false >>=>{{ jsonToVars }}
{{ condition | value: "'<< name: intentInfo.Slots, prompt: false >>' == '[object Object]'" }}=>{{ variable | name: "Slots" | value: "{}" }}
{{ condition | value: "'<< name: botSessionState.dataPoints, prompt: false >>' == '[object Object]'" }}=>{{ variable | name: "dataPoints" | value: "''" }}
{{ condition | value: "'<< name: botSessionState.isCompleted, prompt: false >>' = ''" }}=>{{ variable | name: "isCompleted" | value: "false" }}
{{ varsToJSON | path: "botSessionState.dataPoints" | variable: "botSessionStateDataPoints" | includePath: "false" | output: "" }}
{{ varsToJSON | path: "botSessionState.isCompleted" | variable: "botSessionStateIsCompleted" | includePath: "false" | output: "" }}
{{ condition | value: "'<< name: seek.categoryName >>' == 'FAQ'" }}=>{{ variable | name: "nextPromptSequence" | value: "{\"prompts\":[{\"transcript\":\"<< name: seekResult>>\",\"textToSpeech\":\"<< name: seekResult >>\"}]}" }}=>{{ variable | name: "intentInfo" | value: "{\"Slots\": {},\"intent\":\"NLU_NEEDED\",\"intentConfidence\":\"100\"}" }}
{{ condition | value: "<< name: seek.category >> == 706287" }}=>{{ variable | name: "nextPromptSequence" | mode: "" | value: "{\"prompts\":[{\"transcript\":\"<< name: nextPromptSequence.prompts[0].transcript, prompt: false >>\",\"textToSpeech\":\"<< name: nextPromptSequence.prompts[0].textToSpeech, prompt: false >>\"}]}" }}=>{{ variable | name: "intentInfo" | value: "{\"Slots\": {},\"intent\":\"NLU_NEEDED\",\"intentConfidence\":\"100\"}" }}=>{{ variable | name: "botSessionState" | value: "{\"lastIntent\":\"<< name: seek.intent, prompt: false >>\",\"followUpQuery\":\"<< name: botSessionState.followUpQuery, prompt: false >>\",\"followUpCategory\":\"<< name: botSessionState.followUpCategory, prompt: false >>\",\"followUpTurn\":\"<< name: botSessionState.followUpTurn, prompt: false >>\",\"dataPoints\":\"<< name: botSessionStateDataPoints, prompt: false >>\",\"isCompleted\":\"<< name: botSessionState.isCompleted, prompt: false >>\"}" | mode: "overwrite" }}
{{ condition | value: "'<< name: userInputType >>' == '2'" }}=>{{ condition | value: "AND('<< name: base64WavFile >>' == '')" }}=>
TREATMENT: base64 audio=>{{ variable | name: "nextPromptSequence" | value: "{\"prompts\":[{\"transcript\":\"No audio found\"}]}" }}
{{ condition | value: "'<< name: userInputType >>' == '0'" }}=>{{ condition | value: "AND('<< name: mediaType >>' == 'voip')" }}=>
TREATMENT: no input=>{{ variable | name: "nextPromptSequence" | value: "{\"prompts\":[{\"base64EncodedG711ulawWithWavHeader\":\"<< name: base64WavFile >>\"}]}" }}
{{ condition | value: "'<< name: userInputType >>' == '0'" }}=>{{ condition | value: "AND('<< name: mediaType >>' != 'voip')" }}=>
TREATMENT: no input=>{{ variable | name: "intentInfo" | value: "{\"Slots\": {},\"intent\":\"NLU_NEEDED\",\"intentConfidence\":\"100\"}" }}
{{ condition | value: "'<< name: botSessionState, prompt: false >>' == ''" }}=>{{ variable | name: "botSessionState" | value: "{}" }}
{{ variable | name: "errorDetails" | value: "{\"errorBehaviour\":0,\"errorPromptSequence\":{\"prompts\":[{}]}}" }}=>{{ variable | name: "nextPromptBehaviours" | value: "null" }}=>{{ variable | name: "customPayload" | value: "{}" }}
{{ variable | name: "branchName" | value: "PromptAndCollectNextResponse" }}
{"branchName":"<< name: branchName, prompt: false >>",
"nextPromptSequence":<< name: nextPromptSequence, prompt: false >>,
"intentInfo":<< name: intentInfo, prompt: false >>,
"nextPromptBehaviours":<< name: nextPromptBehaviours, prompt: false >>,
"errorDetails":<< name: errorDetails, prompt: false >>,
"customPayload":<< name: customPayload, prompt: false >>,
"botSessionState":<< name: botSessionState, prompt: false >>}
NeuralSeek mAIstro Agent use case
The NeuralSeek mAIstro Agent demonstrates how CXone can orchestrate multi‑turn conversations using NeuralSeek’s agentic AI framework. In this use case, the agent is configured to handle appointment scheduling by collecting all required user inputs, maintaining session state, and generating structured JSON outputs compatible with Virtual Agent Hub. The workflow leverages NeuralSeek Template Language (NTL) to define conversation logic, enforce required fields, and determine when the session is complete, ensuring the Virtual Agent can pass validated data back to downstream CXone systems.
The diagram and accompanying NTL example illustrate how the mAIstro Agent manages the full appointment scheduling workflow. Incoming user input is evaluated, missing fields are requested in a single prompt to minimize conversation turns, and session state is continuously updated in botSessionState. When all required fields are collected, the agent generates a final JSON response that includes a structured summary for CXone, while clearing the session state to prepare for the next interaction.
Appointment scheduling Agent NTL (NeuralSeek Template Language)
{{ seekIn }}=>{{ variable | name: "seekInput" | value: "<< name: seekIn.originalQuery, prompt: false >>" | mode: "overwrite" }}
{{ LLM | prompt: "You are CareHaven Health's virtual scheduling assistant. Your job is to collect all required patient details to book healthcare appointments.
**Required Fields**: Email, DoctorSpecialty, PreferredDate, PreferredTime
**Response**: Return valid JSON (no markdown).
**Schema**:
{
\"nextPromptSequence\":{\"prompts\":[{\"transcript\":\"\",\"textToSpeech\":\"\"}]},
\"intentInfo\":{\"Slots\":{},\"intent\":\"\"},
\"botSessionState\":{\"lastIntent\":\"<< name: seek.intent, prompt: false >>\",\"followUpQuery\":\"User input: \",\"followUpCategory\":\"Category: Appointments\",\"followUpTurn\":\"Last collected data: \",\"dataPoints\":{},\"isCompleted\":false}
}
**Instructions**:
- Always return valid JSON matching the type.
- Use dataPoints to pre-fill Slots.
- Do not modify the values of followUpQuery, followUpCategory, or followUpTurn.
- **CRITICAL**: If ANY fields are missing, ask for ALL missing fields in a SINGLE message in the transcript. Do not ask for fields one by one - gather all missing information at once to minimize conversation turns.
- Only set isCompleted: true when ALL required fields (Email, DoctorSpecialty, PreferredDate, PreferredTime) are provided.
- If all fields are filled, isCompleted: true and transcript confirms booking.
**Input**:
<< name: seekInput, prompt: false >>
**Important**
- Always return a complete JSON with all closed braces.
- Ask for multiple missing fields together, not individually." | cache: "true" | stream: "disable_streaming" | modelCard: "ns-claude3.5-haiku" }}=>{{ variable | name: "llmResponse" }}
<< name: llmResponse, prompt: false >>=>{{ jsonToVars }}
{{ condition | value: "'<< name: botSessionState.isCompleted, prompt: false >>' == 'true'" }}=>{{ LLM | prompt: "Create a clean summary with the appointment details provided below. Return the summary in the required JSON format.
**Response**: Return valid JSON (no markdown).
**Schema**:
{
\"nextPromptSequence\":{\"prompts\":[{\"transcript\":\"\",\"textToSpeech\":\"\"}]},
\"intentInfo\":{\"Slots\":{},\"intent\":\"\"},
\"botSessionState\":{}
}
**Instructions**:
- Always return valid JSON matching the exact schema above.
- Put the appointment summary in the transcript field
- Format the summary with each detail on a separate line: Email, Doctor Specialty, Preferred Date, Preferred Time
- Use the format: \"Email: [value]\" for each line
- Leave botSessionState as an empty object {}
- Leave intentInfo.Slots and intentInfo.intent as empty
<< name: botSessionState.dataPoints.Email, prompt: false >>
<< name: botSessionState.dataPoints.PreferredDate, prompt: false >>
<< name: botSessionState.dataPoints.PreferredTime, prompt: false >>
<< name: botSessionState.dataPoints.DoctorSpecialty, prompt: false >>
**Important**
- Always return a complete JSON with all closed braces.
- The summary goes in the transcript field, not as separate text.
- botSessionState must be empty: {}" | cache: "true" | stream: "disable_streaming" | modelCard: "ns-claude3.5-haiku" }}=>{{ variable | name: "llmResponse" }}
<< name: llmResponse, prompt: false >>
Governance and guardrails
The NeuralSeek mAIstro Agent demonstrates a reference implementation of an agent-driven workflow using NeuralSeek’s NTL (NeuralSeek Template Language). This use case focuses on an appointment scheduling scenario, where the agent manages multi-turn conversations, captures required data fields, and maintains session state across interactions. The mAIstro Agent executes LLM-driven responses under strict governance controls, including PII redaction, prompt injection detection, semantic scoring, and length constraints. All collected data is structured in JSON for compatibility with CXone’s Virtual Agent Hub, enabling downstream automation such as scheduling, logging, or analytics.
In this Agentic AI architecture, Governance configurations and guardrail settings can be modified for each agent flow. The NICE CXone hits the proxy tunnel mAIstro agent using the mAIstro API, and this agent calls Seek with the required context, where it can be properly routed to the appropriate agent, such as Appointments, FAQ, etc.