NAV Navbar
shell

Introduction

Use the IBM Planning Analytics Workspace UI API to return generated Planning Analytics Workspace assets. You can return assets such as cube views, the dimension editor, the set editor, and TM1 views.

The Planning Analytics Workspace UI API is developed and built using the Nest framework.

Some code examples contain http(s)://<Planning Analytics Workspace URL>. If you are using these code examples, be sure to replace <Planning Analytics Workspace URL> with your own Planning Analytics Workspace URL.

Logging in

You can access the Planning Analytics Workspace UI API in several different ways. If you are accessing the API from the /ui path, you will be prompted to log in using a pop up dialog box. However, there may be other scenarios where you will need to log in using the POST method. For these methods, use /login in the POST header.

Negotiate authentication

To use the Negotiate authentication method, Planning Analytics Workspace must be configured to use a TM1 authentication server that supports Negotiate authentication (mode 2 and 3).

Body

Include the following in the body of your login POST request:

JSON: { “mode”: “negotiate” }

FORM: mode=negotiate

Cognos CAM passport

To use the Cognos CAM passport for login, Planning Analytics Workspace must be configured to use CAM authentication or use a TM1 authentication server that is configured with CAM (mode 5).

Body

Include the following in the body of your login POST request:

JSON: { “camid”: “CAM-PASSPORT-COOKIE-VALUE” }

FORM: camid=CAM-PASSPORT-COOKIE-VALUE

Cognos CAM namespace

To use the Cognos CAM namespace for login, Planning Analytics Workspace must be configured to use CAM authentication or use a TM1 authentication server that is configured with CAM (mode 5).

Body

Include the following in the body of your login POST request:

JSON: { “username”: “TM1-OR-COGNOS-USER”, “password”: “PASSWORD” }

FORM: username=URLENC-TM1-OR-COGNOS-USER&password=URLENC-PASSWORD

Cognos CAM or TM1 native authentication

To use Cognos CAM or TM1 native authentication for login, Planning Analytics Workspace must be configured to use CAM with a preset namespace or configured to use a TM1 authentication server that uses native authentication (mode 1 or 2).

Body

Include the following in the body of your login POST request:

JSON: { “namespace”: “CAM-NAMESPACE-ID”, “username”: “COGNOS-USER”, “password”: “PASSWORD” }

FORM: namespace=URLENC-CAM-NAMESPACE-ID&username=URLENC-COGNOS-USER&password=URLENC-PASSWORD

Login tokens

The Planning Analytics Workspace API accepts the x-csrf-tokenfield in the request header. After you send the login POST request, you will receive a response that contains an x-csrf-token. You can use the x-csrf-token in the header of future non-GET type requests that are sent via AJAX.  

Showing a widget

You can use an endpoint to return an HTML page that renders a Planning Analytics Workspace book, a Planning Analytics Workspace view, a TM1 legacy view, a drill through view, a dimension editor, a set editor, or websheet.

Syntax

Example for Classic experience:

http(s)://<Planning Analytics Workspace URL>/ui?type=cube-viewer&server=Planning%20Sample&cube=plan_BudgetPlan&view=Budget%20Input%20Detailed

Example for New experience:

http(s)://<Planning Analytics Workspace host>[<Planning Analytics Workspace port>/?type=cube-viewer&server=Planning%20Sample&cube=plan_BudgetPlan&view=Budget%20Input%20Detailed

Method: GET

URL Format: /ui?p1=a1&p2=a2&...#f1=a3&f2=a4&...

Query parameters: ?p1=a1&p2=a2&...

Fragment parameters: #f1=a3&f2=a4&...

You have flexibility when it comes to how you want to structure your requests. All parameters can be passed as either a query or a fragment parameter. Queries and fragment parameters are processed in the same way.

The following requests are all equivalent:

All of the above requests will return the following:

Parameters

The type parameter (alias Type) determines which type of widget or asset to render. Each widget/asset type requires a different set of parameters. Below are the widgets/assets that you can return and the parameters associated with each.

Planning Analytics Workspace books

Examples for opening a book in Classic experience:

http(s)://<Planning Analytics Workspace URL>/ui?type=book&path=/shared/myBook1
http(s)://<Planning Analytics Workspace URL>/?perspective=book&path=/shared/book1&embed=true

Example for opening a book in the New experience:

http(s)://<Planning Analytics Workspace URL>/ui?type=book&path=/shared/myBook1

Example for opening a book in the New experience using the embed parameter:

http(s)://<Planning Analytics Workspace URL>/?perspective=dashboard&path=/shared/book1&embed=true

The following parameters apply to type=book.

Parameter name Required Description Examples
type Yes The type of widget to render (alias Type). - type=book
path Yes The absolute location of the asset. -path=/shared/myBook
-path=/shared/path/to/my/book/myBook
-path=/personal/path/to/my/book/myBook

You can open a New experience book by using the Planning Analytics Workspace URL. If you want to control synchronization settings with the URL or JavaScript APIs, use the /ui parameter.

You can also open a book by using the embed parameter which shows or hides the top navigation bar.

Planning Analytics Workspace views

Example for Classic experience:

http(s)://<Planning Analytics Workspace URL>/ui?type=cube-viewer&server=Planning%20Sample&cube=plan_BudgetPlan&view=Budget%20Input%20Detailed

Example for New experience:

http(s)://<Planning Analytics Workspace host>[<Planning Analytics Workspace port>/?type=cube-viewer&server=Planning%20Sample&cube=plan_BudgetPlan&view=Budget%20Input%20Detailed

Example for New experience using properties parameter:

http(s)://<Planning Analytics Workspace host>[<Planning Analytics Workspace port>/?type=cube-viewer&server=Planning%20Sample&cube=plan_BudgetPlan&view=Budget%20Input%20Detailed&properties={"dimensionOverview_name":false, "dimensionOverview_sectionheaders": false} 

The following parameters apply to type=cube-viewer when path is defined.

Parameter name Required Description Examples
type Yes The type of widget to render (alias Type). - type=cube-viewer
path Yes The absolute location of the asset. -path=/shared/myView
-path=/shared/path/to/my/view/myView
server No Overrides which TM1 server the view is located in. You can use this parameter if you have multiple TM1 servers with the same cube view.
If you have a Planning Analytics Workspace view for one TM1 server, but want to use another TM1 server, use the server parameter to define which server to use.
-server=Planning_Sample2
toolbar No See the TM1 Legacy views section below for more detail. - toolbar=all
properties No JSON object where key is the property name and value is a boolean denoting the property is on or off. Supported properties are:
-dimensionOverview_name (default is true)
-dimensionOverview_iconography(default is true)
-dimensionOverview_contextinformation(default is true)
-dimensionOverview_sectionheaders
-dimensionOverview_sectionicons

TM1 Legacy views

Example for Classic experience:

http(s)://<Planning Analytics Workspace URL>/ui?type=cube-viewer&path=/shared/ABC/KamView

Example for New experience:

http(s)://<Planning Analytics Workspace host>[<Planning Analytics Workspace port>/?type=cube-viewer&path=/shared/ABC/KamView

The following parameters apply to type=cube-viewer when path is defined.

Parameter name Required Description Examples
type Yes The type of widget to render (alias Type). - type=cube-viewer
server Yes Name of TM1 server where the view is located. - server=SData
- server=Planning%20Sample
cube Yes Name of cube where view is located. This cube must exist inside the specified server. - cube=Input%20Cube
- cube=plan_BudgetPlan
view No Name of the view. This view must exist inside the specified cube. The default view is used if view is not defined. - view=CPView
- view=Budget%20Input%20Detailed
private No Defines whether or not the view is private. Can be either true or false. The default is false. - private=true
- private=false
toolbar No A comma delimited string of action names to display in the toolbar. The all preset denotes all actions. The default is all if this parameter is not defined. Supported actions are as follows:
- export
- save
- swapAxes
- suppressZero
- refresh
- sandbox
- toggleOverview
The order that the actions are shown in the toolbar is the same order defined in this parameter.
- toolbar=all
- toolbar=suppressZero,sandbox,refresh,save

Dimension editor

Example for Classic experience:

http(s)://<Planning Analytics Workspace URL>/ui?type=dimension-editor&server=Planning%20Sample&dimension=plan_business_unit&hierarchy=plan_business_unit

Example for New experience:

http(s)://<Planning Analytics Workspace host>[<Planning Analytics Workspace port>/?type=dimension-editor&server=Planning%20Sample&dimension=plan_business_unit&hierarchy=plan_business_unit

The following parameters apply to type=dimension-editor.

Parameter name Required Description Examples
type Yes The type of widget to render (alias Type). - type=dimension-editor
server Yes Name of TM1 server where dimension is located. - server=SData
- server=Planning%20Sample
dimension Yes Name of the dimension. This dimension must exist inside the specified server. - dimension=region
- dimension=plan_version
hierarchy No Name of the hierarchy of the specified dimension. This hierarchy must exist inside the specified dimension. If not defined, it will default to the same value as dimension. - hierarchy=ManufacturingSource
- hierarchy=plan_version

Set editor

Example for Classic experience:

http(s)://<Planning Analytics Workspace URL>/ui?type=set-editor&server=Planning%20Sample&dimension=plan_business_unit&hierarchy=plan_business_unit&uniqueName=All%20Business%20Units

Example for New experience:

http(s)://<Planning Analytics Workspace host>[<Planning Analytics Workspace port>/?type=set-editor&server=Planning%20Sample&dimension=plan_business_unit&hierarchy=plan_business_unit&uniqueName=All%20Business%20Units

The following parameters apply to type=set-editor.

Parameter name Required Description Examples
type Yes The type of widget to render (alias Type). - type=set-editor
server Yes Name of the TM1 server where the set or subset is located. - server=SData
- server=Planning%20Sample
cube Yes Name of the cube where view is located. This cube must exist inside the specified server. - cube=Input%20Cube
- cube=plan_BudgetPlan
dimension Yes Name of the dimension. This dimension must exist inside the specified server. - dimension=region
- dimension=plan_version
uniqueName Yes Unique ID of the set or subset. - uniqueName=Europe_all
- uniqueName=FY%202004%20Budget
dimensionCaption No Caption name of the specified dimension (if applicable).
hierarchy No Name of the hierarchy of the specified dimension. This hierarchy must exist inside the specified dimension. If not defined, it will default to the same value as dimension. - hierarchy=ManufacturingSource
- hierarchy=plan_version
hierarchyCaption No Caption name for the specified dimension (if applicable).
alias No The alias name for the set or subset (if applicable).
private No Defines whether or not the set or subset is private. Can be either true or false. The default is false. - private=true
- private=false

Websheet

Example for Classic experience:

http(s)://<Planning Analytics Workspace URL>//ui?type=websheet&Action=Open&Workbook=Applications/Planning%20Sample/Management%20Reporting/Actual%20v%20Budget&AdminHost=localhost&TM1Server=Planning%20Sample

Example for New experience:

http(s)://<Planning Analytics Workspace host>[<Planning Analytics Workspace port>/?type=websheet&Action=Open&Workbook=Applications/Planning%20Sample/Management%20Reporting/Actual%20v%20Budget&AdminHost=localhost&TM1Server=Planning%20Sample

The TM1 Web URL API parameters apply to type=websheet. Currently, none of the parameters passed in are changed. The parameters are simply copied when it redirects to the TM1Web URL API to render a websheet.

For more information, see TM1 Web URL API

Client communication

You can safely enable cross-origin communication between the parent dom (the "client") and the child dom containing the IBM Planning Analytics Workspace UI widget. Communication between the client and the child dom is required in order for the client to be able to issue commands or respond to specific Planning Analytics Workspace UI widget events.

The Planning Analytics Workspace UI widgets are usually contained inside of an iframe. The approach documented in this section is safe for same-origin and cross-origin communication.

Sending and receiving messages from the client are accomplished using the Window.postMessage API. See this link for more information.

AJAX requests

Example of a TM1 API request using AJAX:

GET /api/v0/tm1/Planning Sample/api/v1/Cubes

If you are sending AJAX requests from an application to access any of the Planning Analytics Workspace APIs, you need to use /api/v0 as the root of your request. If you are sending AJAX requests without using /api/v0/ as your root, you may experience a browser CORS issue.

You do not need to use /api/v0/ as your root if you are using the Planning Analytics Workspace UI API in the Classic experience.

Sending messages

Examples:

var iframe = document.getElementByd('iframe_id_here');
// check if widget is fully loaded before sending message
// isWidgetReady is set to true when client receives the "onWidgetLoaded" message
if(isWidgetReady && iframe.contentWindow) {
    iframe.contentWindow.postMessage({
        type: "execute",
        eventName: "Compute",
        eventPayload: {}
    }, "<production url>");
}

Subscribes to the tm1mdv:executeCommand event. Once subscribed, the client receives messages whenever that event occurs

iframe.contentWindow.postMessage({
    type: "subscribe",
    eventName: "tm1mdv:executeCommand",
    eventPayload: {
        name: "first subscription"
    }
}, "<production url>");

Unsubscribes to the event above.

iframe.contentWindow.postMessage({
    type: "unsubscribe",
    eventName: "tm1mdv:executeCommand",
    eventPayload: {
        name: "first subscription"
    }
}, "<production url>");

Subscribes to the tm1mdv:commandProgress event. Once subscribed, the client receives a message whenever a command is in progress and when it finishes.

iframe.contentWindow.postMessage({
    type: 'subscribe',
    eventName: 'tm1mdv:commandProgress',
    eventPayload: {
        name: "second subscription"
    }
}, "http://localhost:8080/ui");

Triggers an redraw event.

iframe.contentWindow.postMessage({
    type: 'trigger',
    eventName: 'tm1mdv:redraw'
}, apiOrigin);

The following is a list of parameters that can be passed in:

Parameter name Required Description Examples
type Yes The type of message to send. - trigger
- subscribe
- unsubscribe
- execute
eventName Yes The full name of the event. - tm1mdv:executeCommand
- tm1mdv:memberSelect
- Compute
eventPayload n/a The payload body accompanying the message. The content and whether or not this parameter is required depends on the type of message. This must be an object in the following format: { k1: v1, k2: v2, ..., kn: vn } - { name: 'myEventNickname' }
- { selectedSet: 'Default' }

The following is a list of all the supported messages that the client can send:

Message type Description eventPayload
trigger Attempts to raise a particular event. The widget may or may not respond, depending on whether or not it is listening for this event name. Depends on the event. This would contain information needed for the event execution.
execute Attempts to execute a command on the widget. This is an alias to the trigger message type and is provided as a convenience. This is equivalent to sending type=trigger and eventPayload={commandName: <command_name>, commandArgs: { ... }}. Depends on the command. This would contain information needed to successfully execute the command.
subscribe Subscribes to a particular event. Once subscribed, the widget will send an on message back to the client every time the eventName event occurs. name: String (Required). Used to identify subscriptions.
- If the given name has already been registered, nothing happens.
unsubscribe Unsubscribes to a particular event. Only subscriptions with a name can be unsubscribed. name: String (Required). Used to identify subscriptions.
- If no name is given or if there were no previous subscriptions under that name, nothing happens.

Receiving messages

Examples:

var widgetReady = false;
window.addEventListener("message", function(event) {
    // only accept messages sent from the UI widget
    if(event.origin == "<production url>") {
        switch(event.data.type) {
            case 'onWidgetLoaded':
                widgetReady = true;
                break;
            case 'on':
                handleEvent(event.data.eventName, event.data.eventPayload);
                break;
            default:
                break;
        }
    }
});

Receiving an on message that indicated that the tm1mdv:executeCommand event had occured

function handleEvent(eventName, eventPayload) {
    if(eventName == "tm1mdv:executeCommand") {
        // first subscription was just notified!
        alert(eventPayload.name + ' was just notified!');
    }
}

Receiving an on message to check the progress of a command.

function handleEvent(eventName, eventPayload) {
    if(eventName === 'tm1mdv:commandProgress') {
        handleCommandProgress(eventPayload);
    }
    ...
}
function handleCommandProgress(payload) {
    switch (payload.commandProgress) {
        case 0:
            // a value of 0 indicates the command had failed
            break;
        case 1:
            // a value of 1 indicates the command had finished successfully
            break;
        case 2:
            // a value of 2 indicates the command had been canceled by the user
            break;
        case 4:
            // a value of 4 indicates the command has started executing
            break;
    }
}

You can find the specifications for the event object in the Window.postMessage API.

The following is a list of parameters under the event.data object:

Parameter name Required Description Examples
type Yes The type of message recieved. - onWidgetLoaded
- on
eventName Yes The full name of the event. - tm1mdv:executeCommand
- tm1mdv:redraw
- tm1mdv:memberSelect
eventPayload n/a The payload body accompanying the message. The contents depends on the type of message. All payloads contain a name and parentStore properties. - { name: 'first subscription', parentStore: { ... }, ... }

The following is a list of all the supported messages that the client can send:

Message type Description eventPayload
onWidgetLoaded Used to notify to the client that the UI widget has been fully rendered and can safely be interacted with. None
on Used to notify to the client that one of their subscribed events has occurred. This will contain more information about the context of the event that occurred.

HTML sample

<html>
    <style>
        .vertical { display: flex; flex-direction: column; }
        .vertical-fill { flex-grow: 2; }
        div#headerContent { margin: 5px; }
        div#headerContent button { margin-left: 20px }
        div#widgetContent iframe#widget { width: 100%; height: 100%; }
    </style>
    <script>
        var API_URL = '<Planning Analytics Workspace URL>';
        var IS_WIDGET_READY = false;
        var iframe;

        window.onload = function() {
            iframe = document.getElementById('widget');
            window.addEventListener('message', function(evt) {
                // only accept messages sent from the API service
                if(evt.origin == API_URL) {
                    switch(evt.data.type) {
                        case 'onWidgetLoaded':
                            IS_WIDGET_READY = true;
                            break;
                        case 'on':
                            handleEvent(evt.data.eventName, evt.data.eventPayload);
                            break;
                        default:
                            break;
                    }
                }
            });
        }

        function handleEvent(name, payload) {
            alert('event "' + name + '" had occurred: ' + JSON.stringify(payload));
        }

        function loadIframe() {
            var url = API_URL + 
                        '/ui/' +
                        '?type=cube-viewer' +
                        '&server=Planning%20Sample' +
                        '&cube=plan_BudgetPlan' +
                        '&view=Budget%20Input%20Detailed';
            iframe.src = url;
        }

        function isWidgetReady() {
            return IS_WIDGET_READY && iframe.contentWindow;
        }

        function redraw() {
            if(isWidgetReady()) {
                iframe.contentWindow.postMessage({
                    type: 'trigger',
                    eventName: 'tm1mdv:redraw'
                }, API_URL);
            }
        }

        function swapAxes() {
            if(isWidgetReady()) {
                iframe.contentWindow.postMessage({
                    type: 'execute',
                    eventName: 'SwapAxes'
                }, API_URL);
            }
        }

        function subscribe() {
            if(isWidgetReady()) {
                iframe.contentWindow.postMessage({
                    type: 'subscribe',
                    eventName: 'tm1mdv:executeCommand',
                    eventPayload: {
                        name: 'commandsCompleted'
                    }
                }, API_URL);
            }
        }

        function unsubscribe() {
            if(isWidgetReady()) {
                iframe.contentWindow.postMessage({
                    type: 'unsubscribe',
                    eventName: 'tm1mdv:executeCommand',
                    eventPayload: {
                        name: 'commandsCompleted'
                    }
                }, API_URL);
            }
        }
    </script>
    <body class="vertical">
        <div id="headerContent">
            <button onclick="loadIframe()">Render iframe</button>
            <button onclick="redraw()">Trigger redraw event</button>
            <button onclick="swapAxes()">Execute swap axis</button>
            <button onclick="subscribe()">Subscribe to "tm1mdv:executeCommand"</button>
            <button onclick="unsubscribe()">Unsubscribe to "tm1mdv:executeCommand"</button>
        </div>
        <div id="widgetContent" class="vertical vertical-fill">
            <iframe id="widget" class="vertical-fill"></iframe>
        </div>
    </body>
</html>

This is a sample of an HTML file that uses the IBM Planning Analytics Workspace UI API to create a cube viewer widget in an iframe. In this sample are also full examples of the trigger, execute, subscribe, and unsubscribe events.