Designing Dynamic Screen Pops for CXone MAX using Custom Data Payloads
What This Guide Covers
You are configuring NICE CXone to surface a browser-based screen pop in the MAX agent desktop - one that renders customer context (account number, case history, sentiment score) sourced from a CRM or custom data store - triggered by the interaction’s custom data payload populated in Studio. When working, agents see a pre-populated customer record appear in a pinned browser tab within 2 seconds of accepting the interaction, with zero manual lookup required.
Prerequisites, Roles & Licensing
- Licensing: CXone ACD + MAX Desktop Agent (included in standard CXone entitlement); Screen Pop feature enabled at the tenant level (verify with your NICE CXone TAM)
- Permissions required (Admin):
ACD > Skills > EditStudio > Scripts > EditAdmin > Screen Pops > Manage
- CXone Studio: Version 34+ (for
CUSTOM_DATAaction availability) - External dependencies: A CRM or data system with a URL-based record retrieval interface (Salesforce, ServiceNow, Zendesk, or an internal portal); the CRM URL must be accessible from the agent’s browser without VPN interruption
- Browser requirement: Agents must use Chrome or Edge - Firefox and Safari have restrictions on cross-origin iframe navigation that break some screen pop URL patterns
The Implementation Deep-Dive
1. Understanding the CXone Screen Pop Architecture
CXone screen pops are not server-push events - they are URL-based redirections triggered by the MAX desktop in response to ACD events. The chain is:
[Inbound call arrives]
--> [Studio script executes and populates CUSTOM_DATA variables]
--> [ACD routes interaction to agent queue]
--> [MAX receives interaction offer event with CUSTOM_DATA payload]
--> [MAX fires configured Screen Pop URL with variables substituted]
--> [Browser tab/window opens or navigates to the CRM record]
The payload transportation mechanism is the CUSTOM_DATA variable block in Studio - a structured dictionary that travels with the interaction from IVR to agent handoff. The Screen Pop URL template uses token substitution to inject these variables into the URL at runtime.
Screen pops can target:
- A new tab (least disruptive; agents can ignore if busy)
- The agent’s current focused tab (most disruptive; use carefully)
- A pinned Secondary Browser Panel within MAX (recommended for contact centers - keeps the CRM in a consistent location without overwhelming the agent’s browser)
2. Populating CUSTOM_DATA in Studio
The Studio script is where customer identity and context are resolved before the interaction reaches an agent. All data you want available at screen pop must be written into CUSTOM_DATA (or equivalent custom variables) before the REQAGENT action.
Example Studio script segment (ANI-based customer lookup):
// Step 1: Capture the ANI
ASSIGN strANI = "{ANI}"
// Step 2: Call an external lookup to your CRM
// Using the SNIPPET action to call a REST API
SNIPPET
var serviceUrl = "https://api.your-crm.com/customers/lookup?phone=" + strANI;
var req = new CXone.HttpRequest();
req.method = "GET";
req.url = serviceUrl;
req.headers["Authorization"] = "Bearer {CRM_API_KEY}";
var response = req.send();
var customerData = JSON.parse(response.body);
SET customerId = customerData.id;
SET customerName = customerData.fullName;
SET accountTier = customerData.tier;
SET caseCount = customerData.openCaseCount;
SET crmRecordUrl = customerData.profileUrl;
END SNIPPET
// Step 3: Write to CUSTOM_DATA for MAX to consume
CUSTOM_DATA customerId "{customerId}"
CUSTOM_DATA customerName "{customerName}"
CUSTOM_DATA accountTier "{accountTier}"
CUSTOM_DATA caseCount "{caseCount}"
CUSTOM_DATA crmRecordUrl "{crmRecordUrl}"
// Step 4: Route to agent
REQAGENT
Key constraint: CUSTOM_DATA values are string-typed. Serialize complex objects to JSON strings and deserialize in your screen pop page if needed. Maximum payload size per variable is 1,024 characters; total CUSTOM_DATA payload per interaction is limited to approximately 8KB.
The Trap - calling external APIs synchronously in Studio without timeout handling: The CXone.HttpRequest call in Studio is blocking. If your CRM API takes >3 seconds to respond (or times out entirely), the Studio script stalls at that action, increasing IVR wait time before REQAGENT fires. Always set a timeout:
SNIPPET
req.timeout = 2000; // 2 seconds max
var response;
try {
response = req.send();
} catch(e) {
// Fallback: proceed without CRM data
SET customerId = "UNKNOWN";
SET customerName = "Lookup Failed";
SET crmRecordUrl = "https://your-crm.com/search";
}
END SNIPPET
For high-traffic environments (>500 concurrent calls), stress-test your CRM API before enabling this pattern - the CXone Studio engine will make one request per inbound interaction.
3. Configuring the Screen Pop in CXone Admin
Navigate to Admin > ACD > Screen Pops and create a new Screen Pop definition.
Screen Pop URL template:
The URL template uses {variable_name} tokens that MAX substitutes with the CUSTOM_DATA values at pop-time:
https://your-crm.com/customers/{customerId}?source=cxone&agent={AgentId}&interactionId={ContactId}
Built-in system tokens available for substitution (no CUSTOM_DATA required):
| Token | Value |
|---|---|
{ContactId} |
Unique CXone interaction ID |
{AgentId} |
CXone agent user ID |
{SkillName} |
ACD skill that routed the call |
{ANI} |
Calling number |
{DNIS} |
Dialed number |
{MediaType} |
INBOUND_VOICE, CHAT, EMAIL, etc. |
Combined with CUSTOM_DATA variables:
https://your-crm.com/customers/{customerId}?tier={accountTier}&ref={ContactId}&agent={AgentId}
Pop trigger event: Set to Accepted (fires when the agent clicks Accept on the interaction) rather than Offered (fires when the call rings to the agent). Offered creates premature pops on rejected/transferred interactions.
Pop target: Select Secondary Browser Panel to open the URL in the built-in MAX panel rather than a new browser window. This keeps all agent tooling within the MAX frame.
The Trap - using the external browser window pop on Citrix/VDI environments: If agents run MAX inside a Citrix or VMware Horizon VDI session, “open in external browser” pops open a browser inside the VDI session (not the agent’s local machine). CRM applications may block access from VDI egress IPs. Test the screen pop URL from a VDI session before rollout. The Secondary Browser Panel inside MAX avoids this issue entirely since it uses MAX’s embedded Chromium renderer.
4. Differentiating Screen Pop Behavior by Channel
A single Screen Pop definition fires the same URL for all interaction types. If voice, chat, and email should pop different CRM views (call summary vs. ticket vs. email thread), configure separate Screen Pop definitions and bind them to specific ACD skills.
Approach: skill-based pop assignment
In Admin > ACD > Skills, each skill has a Screen Pop dropdown. Bind different pops:
| ACD Skill | Screen Pop | URL Pattern |
|---|---|---|
Voice_Tier1_Support |
Pop_Voice_CRM |
crm.com/calls/{ContactId} |
Chat_Sales |
Pop_Chat_CRM |
crm.com/chats/{ContactId}?source=chat |
Email_Billing |
Pop_Email_Tickets |
ticketing.com/tickets?ref={ContactId} |
For interactions that transfer between skills (e.g., chat escalated to voice), the screen pop fires based on the current skill at time of agent acceptance, not the originating skill. If the cross-skill context must be preserved, pass the original skill name via CUSTOM_DATA:
CUSTOM_DATA originChannel "chat"
CUSTOM_DATA originSkill "Chat_Sales"
And include it in the URL: crm.com/unified?origin={originChannel}&skill={originSkill}&id={ContactId}
5. Screen Pop for Digital (Omnichannel) Interactions
For chat and email interactions, the screen pop fires on the same Accepted event but the CUSTOM_DATA payload must be populated in the Digital Experience (DX) routing script rather than a voice Studio script.
In CXone DX, custom data is passed through the Custom Variables section of the channel entry point configuration, and supplemented via the Pre-Chat Survey data (for chat) or email subject/body parsing (for email).
Chat pre-chat survey → CUSTOM_DATA:
Pre-chat survey fields map to Studio variables automatically if they share names. If your pre-chat survey asks for Email and AccountNumber, they arrive in the Studio script as {PCEmail} and {PCAccountNumber}. Map them to CUSTOM_DATA:
CUSTOM_DATA customerEmail "{PCEmail}"
CUSTOM_DATA accountNumber "{PCAccountNumber}"
Then construct the CRM pop URL using these values:
https://your-crm.com/customers?email={customerEmail}&account={accountNumber}&interaction={ContactId}
The Trap - PII in URL query strings: Placing email addresses and account numbers in URL query parameters means they appear in browser history, proxy logs, server access logs, and Referer headers on the destination page. For PCI-DSS or HIPAA environments, route to a lookup page that accepts a non-PII interaction ID and fetches the record server-side:
https://your-internal-portal.com/screenpop?cxone_id={ContactId}
The portal fetches contactId → CXone Data API → retrieves CUSTOM_DATA on the server side → renders the CRM record. This keeps PII out of URLs.
Validation, Edge Cases & Troubleshooting
Edge Case 1: Screen Pop Fires but Shows Blank/Error Page
The most common cause is that the CRM URL is accessible from the agent’s laptop browser but not from within the MAX Secondary Browser Panel (which uses Chromium’s embedded rendering engine). Check:
- Content Security Policy (CSP): The CRM page’s CSP may block
frame-ancestors. CXone embeds the page in an iframe - CSPframe-ancestors: 'none'will block this. Work with the CRM team to add your CXone domain to the allowed frame ancestors, or use the external browser pop instead. - SameSite Cookie Policy: The CRM session cookie may require
SameSite=None; Secureto function in a cross-origin iframe context. Older CRM implementations (Salesforce Classic, JIRA Server) may not support this without configuration changes.
Edge Case 2: CUSTOM_DATA Variables Empty at Pop Time
If the screen pop URL contains {customerId} but the variable is blank, the substitution produces {customerId} literally in the URL (not empty string). This causes a 404 on the CRM. Diagnose by checking the Studio script execution in CXone Reporting > Studio Trace - verify the CUSTOM_DATA lines executed and the variables were non-empty. Common cause: the CRM API lookup returned an empty result (new customer not in CRM) without the script falling back to a default value.
Edge Case 3: Screen Pop Fires Twice on Transfer
If an agent transfers the interaction to another skill, the receiving agent gets a new Accepted event - triggering a fresh screen pop with the same CUSTOM_DATA. This is expected behavior. If the second pop is disruptive (e.g., it navigates the agent away from notes they’ve been taking), configure the transfer-destination skill’s screen pop to target a new tab rather than replacing the current tab.
Edge Case 4: Screen Pop Timing - Pop Arrives Before Agent Sees the Interaction
If the pop fires on Offered rather than Accepted, and the agent’s machine is slow, the browser tab may open before MAX has rendered the interaction card - confusing agents. Always use Accepted as the trigger event. If business requirements demand pop on offer (e.g., for preview outbound campaigns where agents need context before deciding to accept), add a 1-2 second artificial delay using Studio’s WAIT action before REQAGENT, giving MAX time to render the offer card before the pop fires.