CXone Studio SNIPPET Action: Making REST API Calls and Parsing JSON Responses

CXone Studio SNIPPET Action: Making REST API Calls and Parsing JSON Responses

What You Will Build

  • A NICE CXone Studio Snippet that executes an outbound HTTPS GET request to a third-party service, parses the JSON response body, and extracts a specific field into a session variable.
  • This tutorial uses the native JavaScript execution environment provided within the NICE CXone Studio “Snippet” action node.
  • The code examples are written in strict JavaScript (ES6+), which is the runtime engine for CXone Studio Snippets.

Prerequisites

  • NICE CXone Studio Access: You must have a CXone account with permissions to edit Studio Flows.
  • Target API Endpoint: A publicly accessible REST API endpoint that returns JSON. For this tutorial, we will use the public jsonplaceholder.typicode.com service.
  • Studio Flow: An existing or new Studio Flow where you can insert a Snippet action.
  • Knowledge of Studio Variables: Understanding how to create and reference session variables in CXone Studio.

Authentication Setup

CXone Studio Snippets run in a sandboxed Node.js-like environment. Unlike server-side integrations, you do not configure OAuth tokens in the Snippet code itself unless you are generating them programmatically.

For outbound calls to third-party APIs from a Snippet, you must handle authentication headers manually within the JavaScript code. If the target API requires an API Key or Bearer token, you must store these securely in CXone Studio Secure Variables or Global Variables and reference them in your Snippet.

Security Warning: Never hardcode secrets directly in the Snippet source code. Use Studio’s variable injection mechanism.

In this tutorial, we assume the target API (jsonplaceholder) is public and requires no authentication. If your API requires an Authorization header, you would construct it like this:

const token = context.variables.global.apiToken; // Retrieve from Secure Global Variable
const headers = {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
};

Implementation

Step 1: Initialize the HTTP Client and Context

In CXone Studio, the context object is the bridge between the flow state and your code. The context.http object provides methods for making network requests.

The first step is to define the target URL and prepare the request configuration. We will use the context.http.get() method for this tutorial, as it is the most common pattern for retrieving data.

// Define the target API endpoint
const targetUrl = "https://jsonplaceholder.typicode.com/users/1";

// Define headers if necessary (empty object for public APIs)
const headers = {
    'Accept': 'application/json'
};

// Initialize response container
let responseData = null;
let statusCode = null;

Important Note: The context.http methods in CXone Studio are synchronous in execution relative to the flow engine, but they rely on the underlying Node.js https module. You must handle the response object correctly.

Step 2: Execute the GET Request and Handle Errors

We will now perform the actual HTTP request. We must wrap this in a try-catch block to handle network failures, timeouts, or unexpected server errors.

CXone Studio Snippets have a maximum execution time (typically 10-30 seconds depending on your license and configuration). Long-running requests will cause the snippet to fail. Always set a reasonable timeout if the API supports it, or ensure your endpoint is fast.

try {
    // Execute the GET request
    // The context.http.get method returns a response object
    const response = context.http.get(targetUrl, headers);

    // Capture the status code for debugging or branching
    statusCode = response.statusCode;

    // The body is returned as a string in many Studio versions,
    // so we must parse it if it is JSON.
    if (response.body) {
        try {
            responseData = JSON.parse(response.body);
        } catch (parseError) {
            // Log parsing error to the flow logs
            context.log("Error parsing JSON response: " + parseError.message);
            responseData = null;
        }
    } else {
        context.log("Response body was empty");
    }

} catch (httpError) {
    // Handle HTTP-level errors (e.g., connection refused, timeout)
    context.log("HTTP Request Failed: " + httpError.message);
    // Set a flag or variable to indicate failure
    context.variables.session.apiCallSuccessful = false;
}

Why we parse manually: While some newer Studio environments attempt automatic JSON parsing, relying on JSON.parse() ensures compatibility across all CXone versions and gives you explicit control over error handling when the response is malformed.

Step 3: Extract Data and Update Session Variables

Once the JSON is parsed into a JavaScript object, we can extract specific fields. In this example, we are fetching a user object from jsonplaceholder. The response structure looks like this:

{
  "id": 1,
  "name": "Leanne Graham",
  "username": "Bret",
  "email": "Sincere@april.biz",
  "address": { ... },
  "phone": "1-770-736-8031 x56442",
  "website": "hildegard.org",
  "company": { ... }
}

We will extract the name and email fields and store them in CXone Studio Session Variables. This allows subsequent nodes in your flow (like a “Speak” or “Text” node) to use this data.

if (responseData && statusCode === 200) {
    // Extract specific fields
    const userName = responseData.name;
    const userEmail = responseData.email;
    const userId = responseData.id;

    // Assign to Session Variables
    // These variables must exist in your Studio Flow context
    // or be created dynamically if your Studio version supports it.
    // Best practice: Pre-create them in the Flow Variables panel.
    context.variables.session.userName = userName;
    context.variables.session.userEmail = userEmail;
    context.variables.session.userId = userId;

    // Set success flag
    context.variables.session.apiCallSuccessful = true;

    context.log("Successfully extracted user data for ID: " + userId);
} else {
    // Handle non-200 status codes (e.g., 404 Not Found)
    context.log("API returned status code: " + statusCode);
    context.variables.session.apiCallSuccessful = false;
    context.variables.session.errorReason = "HTTP Status: " + statusCode;
}

Variable Pre-creation: In CXone Studio, it is highly recommended to pre-define variables like userName, userEmail, and apiCallSuccessful in the Flow Variables panel before running the flow. While you can often assign to new keys dynamically, pre-defining them ensures type consistency and easier debugging in the Flow Debugger.

Complete Working Example

Below is the complete, copy-pasteable JavaScript code for the Snippet action.

Instructions:

  1. Open your CXone Studio Flow.
  2. Add a Snippet action node.
  3. Paste the code below into the Script editor.
  4. Ensure you have created the following Session Variables in your Flow:
    • userName (String)
    • userEmail (String)
    • userId (Number)
    • apiCallSuccessful (Boolean)
    • errorReason (String)
/**
 * CXone Studio Snippet: Fetch User Data from JSONPlaceholder
 * 
 * This snippet makes a GET request to a public API, parses the JSON response,
 * and populates session variables with the result.
 */

// 1. Configuration
const TARGET_URL = "https://jsonplaceholder.typicode.com/users/1";
const TIMEOUT_MS = 5000; // Optional: Check if your Studio version supports timeout config

// 2. Initialize State
let responseData = null;
let statusCode = null;
let isError = false;

try {
    context.log("Initiating HTTP GET request to: " + TARGET_URL);

    // 3. Execute HTTP Request
    // Note: context.http.get(url, headers)
    const response = context.http.get(TARGET_URL, {
        'Accept': 'application/json',
        'User-Agent': 'CXoneStudio-Snippet/1.0'
    });

    statusCode = response.statusCode;
    context.log("Received HTTP Status: " + statusCode);

    // 4. Parse Response Body
    if (response.body) {
        try {
            responseData = JSON.parse(response.body);
        } catch (e) {
            context.log("JSON Parse Error: " + e.message);
            isError = true;
        }
    } else {
        context.log("Empty response body received.");
        isError = true;
    }

    // 5. Process Data
    if (!isError && statusCode === 200 && responseData) {
        // Safely extract fields using optional chaining if supported, 
        // or standard checks for older environments.
        const name = responseData.name || "Unknown";
        const email = responseData.email || "No Email";
        const id = responseData.id || 0;

        // Assign to Session Variables
        context.variables.session.userName = name;
        context.variables.session.userEmail = email;
        context.variables.session.userId = id;
        
        context.variables.session.apiCallSuccessful = true;
        context.log("Success: User data stored in session variables.");
    } else {
        // Handle Non-200 or Parse Errors
        context.variables.session.apiCallSuccessful = false;
        context.variables.session.errorReason = "Status: " + statusCode + " | Data: " + (responseData ? JSON.stringify(responseData) : "None");
        context.log("Failed to retrieve valid user data.");
    }

} catch (networkError) {
    // 6. Handle Network/Execution Errors
    context.log("Network Error: " + networkError.message);
    context.variables.session.apiCallSuccessful = false;
    context.variables.session.errorReason = "Network Exception: " + networkError.message;
}

Common Errors & Debugging

Error: context.http is not defined or context is undefined

What causes it:
This usually occurs if you are testing the code in a standard Node.js environment or a browser console instead of the CXone Studio Snippet editor. The context object is injected solely by the CXone runtime.

How to fix it:
Ensure you are pasting the code directly into the Snippet action node within the CXone Studio interface. You cannot run this code locally without mocking the context object.

Mocking for Local Testing:
If you wish to test the logic locally, you can mock the context:

// Mock Context for Local Testing Only
const mockContext = {
    variables: {
        session: {},
        global: {}
    },
    log: (msg) => console.log(msg),
    http: {
        get: (url, headers) => {
            // Simulate a network call
            return {
                statusCode: 200,
                body: '{"id":1,"name":"Leanne Graham","email":"Sincere@april.biz"}'
            };
        }
    }
};

// Replace 'context' with 'mockContext' in your script for local runs

Error: SyntaxError: Unexpected token < in JSON at position 0

What causes it:
The API returned an HTML page (likely a 404 error page or a login redirect) instead of JSON. When JSON.parse() tries to read the HTML string, it fails at the first < character.

How to fix it:

  1. Check the response.statusCode. If it is 404, 500, or 302, the API did not return data.
  2. Inspect response.body before parsing. If it starts with <html or <!DOCTYPE, it is not JSON.
  3. Add a content-type check:
const contentType = response.headers['content-type'];
if (contentType && contentType.includes('application/json')) {
    responseData = JSON.parse(response.body);
} else {
    context.log("Unexpected Content-Type: " + contentType);
    isError = true;
}

Error: Timeout exceeded or Script execution timeout

What causes it:
The external API took longer than the CXone Studio Snippet timeout limit (default is often 10 seconds) to respond.

How to fix it:

  1. Optimize the API endpoint. Ensure it is not performing heavy server-side processing.
  2. If using a proxy, ensure the proxy is not adding latency.
  3. In some CXone versions, you can adjust the timeout in the Snippet node properties if available. If not, consider moving this logic to an external middleware (like Azure Function or AWS Lambda) and calling that simpler endpoint from the Snippet.

Error: context.variables.session is read-only or Variable Not Found

What causes it:
In strict CXone Studio configurations, you cannot assign to a session variable that has not been pre-declared in the Flow Variables panel.

How to fix it:
Go to the Flow Variables panel in Studio. Add the following variables:

  • userName (Type: String)
  • userEmail (Type: String)
  • userId (Type: Number)
  • apiCallSuccessful (Type: Boolean)
  • errorReason (Type: String)

Then, in the Snippet, assign to them as shown in the Complete Working Example.

Official References