Integrating FDC3-compliant apps into a workflow using the FDC3 workbench

If you’re developing an app that you want to integrate into a smart desktop, this topic is for you. You will learn:

  • About the FDC3 standard
  • How Finsemble implements this standard
  • Three ways you can integrate your app into a smart desktop of your client
  • How to develop and test your app using the FDC3 workbench

The FDC3 standard

The Financial Desktop Connectivity and Collaboration Consortium (FDC3) created and maintains an open standard for desktop communication between financial apps. Think of this standard as a language that apps can use to understand each other.

Any communication consists of passing information in two directions. Desktop connectivity is no different. An app needs to be able to send information to another app, and to receive information from others.

It is helpful to think about the FDC3 standard as a language that consists of nouns and verbs. The nouns describe objects on which actions are taken. In FDC3, we call them contexts. The verbs specify actions to take on these objects. We call these verbs intents. To make a mutually understandable sentence, both the sender and the recipient must agree on what the nouns and verbs mean and how to specify them.

In addition to the nouns (contexts) and the verbs (intents), we need a communication medium. In the case of the FDC3 protocol the medium is called a channel. Finally, we need to know who can participate in the information exchange. For that, we have the list called the App Directory.


We just learned that a context is a noun of the FDC3 protocol. It consists of identifiers and data that are passed from one app to another. This flow of information creates a Finsemble workflow.

A context consists of:

  1. A type identifier. This identifier must be unique, and is the only mandatory part of a context. It is used for routing.
  2. A name parameter that gives the context a human-readable title. Optional.
  3. An id object that provides a map of equivalent identifiers. Optional.
  4. Other metadata and properties. Optional.

Here is the formal specification:

interface Context {
    type: string;  
    name?: string;  
    id?: {
       [x:string]: string;  
    [x: string]: any;

For example, you could define an instrument context like this:

interface Instrument extends Context { 
    type: 'fdc3.instrument',
    name: string;  
    id: {
       ticker?: string;
       ISIN?: string;   
       CUSIP?: string;  

If you want to use this in a JSON, it could look like this:

    "type" : "fdc3.instrument", 
    "name" : "Tesla",  
    "id" :
           "ticker" : "tsla",
    "country": "US"

Currently FDC3 recognizes 4 contexts.

Context channels

A context channel is a mechanism of grouping together apps that can share information. Before an app can receive any information at all, you must first assign it to a channel. If you’re familiar with color-coded channels in the previous releases of Finsemble, you already know how context channels work. If context channels are new to you, the idea is that for each piece of information traveling on a channel, only apps assigned to that channel can access that information. To all other apps this information is not only inaccessible, they don’t even know it’s there.

Although strictly speaking not mandatory, it is a good idea to assign each app to at least one channel. After all, if you have no need for that app to share information, why have it in the first place? For this reason, you must explicitly join it to a channel as needed.

(There is an exception to this rule. If an app isn’t participating in any workflow, you don’t need to add it to any channel. It will be on the desktop still, but separate from the interop. One example of such an app is PowerPoint. It’s on many desktops, but doesn’t exchange information with any other app.)

There is one more type of channel, App Channel. Channels of this type are created programmatically.


So far, we have seen contexts, or the nouns of our FDC3 language. Now, let’s look at intents, which are the verbs. A verb specifies an action to be performed on an object. An action can be a request to display a chart, or a search for an app that can start a chat, or some such.

Here is how to find an app to start a chat:

const intentApps = await fdc3.findIntent("StartChat");

The big 4

FDC3 defines many APIs, but for desktop interop we really need only 4 APIs, which at Finsemble we call the big 4:

  • addContextListener(contextType, handler)
  • addIntentListener(intent, handler)
  • raiseIntent(intent, context)
  • broadcast(context)

Using these big 4 standard APIs is enough for achieving desktop interop. Without a standard, desktop interop would be extremely difficult and prohibitively expensive. It would require a unique API implementation for each smart desktop provider your app needs to support. It’s much easier to establish a standard protocol that defines how each app must communicate with others. As long as all the apps follow this standard, every app understands every other app.

FDC3 has more APIs than the big 4. Learn more about FDC3.

Learn more about Interop.

Implementing the standard: Finsemble

Although FDC3 defines the standard, it doesn’t implement it. Instead, it leaves the implementation to desktop agents. Finsemble is one such desktop agent. With the release of 6.0, Finsemble fully supports the FDC3 1.2 standard. There are other desktop agents with varying degrees of adherence to the standard.

As a desktop agent, Finsemble implements an fdc3 API that apps can use to communicate with each other. We call this implementation interop. For HTML apps, the API is available as a global object within Finsemble or as an imported dependency for Java and .NET applications. Following the FDC3 standard, after an app connects to a single channel and subscribes to a given context type, it can send or receive data from other apps. What are channels? Channels are means of moving information from one app to another.

When an app raises an intent to communicate with another app, Finsemble picks the correct app to send the intent to, if possible. But sometimes there is more than one app that can receive the intent. In this case. Finsemble presents the user with a resolver, which is a UX component that lists all available apps that could receive the intent. A user then picks the right app from the list.This way, your intent or data always finds the right destination.

Three ways to integrate your app

There are 3 ways you can integrate your app into a smart desktop by using the FDC3 standard. The simplest way is for you to provide FDC3-compatible APIs that other apps can use to communicate with your app. You can then integrate your app within a compliant desktop agent, such as Finsemble, that someone else implemented. This approach requires the least amount of work.

At the other end of the spectrum there is the most amount of work for you: write your own desktop agent. We strongly recommend that you don’t choose this approach. Creating your own interop service is a lot more complex than it seems.

Instead of building your own agent, we recommend the third way: plug your app into Finsemble. Finsemble is a desktop integration and workflow management platform that you can use to quickly integrate your app with the smart desktops of your customers. We can whitelabel Finsemble so that you can brand it the way you want. This way, all the infrastructure work is already done. You don’t need to reinvent the wheel. All you need to do is use it.

If your customer already uses Finsemble, you might want to integrate your app into their smart desktop. If they don’t, they are probably considering buying some kind of desktop management. You can demo your app inside the Finsemble smart desktop.

You don’t need to know everything there is to know about Finsemble to integrate your app. Your customer will worry about the design and deployment. You only need to show them how your app fits into their workflow, which is one of possibly many workflows they have. We will guide you through the skills you need to perform the integration.

How your app fits the Finsemble smart desktop

Now that you've decided to integrate your app into a Finsemble smart desktop, you need to figure out how it will fit. It’s best to make this decision before you start writing the first line of code. Your choice is between hosting a smart desktop yourself or placing your app within a smart desktop that someone else hosts.

Your app is a part of a workflow

Your app will be a part of a workflow that a customer uses, or it might implement and automate an entire workflow. This workflow could be sales, trading, client support, back office, contact center, treasury, customer relations, and so on. You probably already know which workflow your app will participate in or implement. For the demo, you can create a workflow that reasonably approximates one your customer or prospect has. When you deploy the app for a specific customer, you need to know all the details.

Each company is different, and so you need to examine each customer’s workflow individually to determine how your specific app fits in. For example, an order can come in as a pull, or a customer might push information onto clients who then click and trade. Your app will react differently in these two situations.

It might be tempting to only look at the part of the workflow where you intend to place your app. In some cases this might be sufficient. But if you analyze the entire workflow, you might discover additional interactions that your app needs to implement.

To analyze a workflow, begin by listing all the apps your prospect has on their desktop, and determine whether these apps are a part of the workflow you want to join. For example, a customer might have Outlook, Tableau, a news app, OMS in-house, Bloomberg, Symphony, Excel, and so on. Not all the apps participate in workflows. Some apps, such as PowerPoint, are on the desktop but aren't a part of any workflow. Others might be a part of another workflow, one that you aren’t implementing. Those apps are irrelevant for you, so you can remove them from your list.

If your client already has Finsemble, take full advantage of it. Write your app as it will exist in their own Finsemble.

Simple example: a chat app

In this example, we will design a simple app that provides chat functionality. The actual communication could be email or a phone call, but here we will focus on email only.

We already know we need to use intents (verbs) and contexts (nouns).

The first thing your app needs is to connect to a channel. Initially, all apps are placed in the default channel, but that’s rarely the channel where your app needs to communicate. You need your app to join a specific channel where other apps expect to communicate.

When the app launches, it will listen for a start chat intent. Any app that wants to communicate via chat can use your app. So we need to add an intent listener. In FDC3, this is what the context listener looks like:

addIntentListener(intent: string, handler: ContextHandler): Listener;

const listener = fdc3.addIntentListener('StartChat', context => {
    // start chat has been requested by another application

Here is an example workflow:

  1. A user reads an email about a stock and wants to buy it. In our example, we use Home Depot with the ticker symbol HD. The email contains a link with this ticker symbol. So far, the information is flowing between the user and the screen. There’s nothing for us to do yet.

  2. The user clicks the link, indicating interest in the stock.

    This action from the user causes the mail app to raise an intent “I have a symbol, I want to look it up.”

    fdc3.raiseIntent("ViewChart", contextobject={ type: 'fdc3.instrument', id: {symbol: 'HD'})
  3. Finsemble picks up the intent, finds all the apps that can handle it, and launches a resolver, which displays all these apps.

  4. The user picks a chart app from the list.

  5. Finsemble sends the intent to the chart app

  6. The chart app listens for the instrument context in the intent and finds the stock ticker. It then updates its own state with the ticker.

  7. The app displays the chart for HD

Even in this simple workflow, a lot of information is exchanged. We have 3 participants: the mail app, the chart app, and Finsemble itself. (Actually, we have one more participant, the human user, but we’ll ignore them for our purposes.) All of these participants must communicate effectively for this flow to work.

Now that you have all the relevant apps, you need to define the flow of information and decide how to process the information at each step. Here are the questions you need to answer:

  • What tasks does your app need to accomplish in this workflow?
  • What apps will your app need to communicate with to achieve these tasks?
  • Are these apps already present on the smart desktop or do you need to acquire and install them?
  • What kind of data or intents does your app need to listen to or send, and to whom?
  • What data or intents do the other apps need from your app before they can send you the info you need?

If the workflow is complex, you might find it helpful to create a workflow diagram. Teaching you how to create one is out of scope for this topic. There are many online tools to help you.

For all but the simplest workflows, it’s a good idea to test your app against the workflow you just diagramed. You might want to use our test app for this. More about this app in a moment.

Developing and testing your apps with the FDC3 workbench

When you are developing an FDC3-compliant app or even a desktop agent, you need to test it. Because FDC3 is about communicating, your app needs at a minimum one other app to communicate with. You could grab an existing app and test against that, but often that’s not enough because you want to test many different types of communication repeatedly.

Many developers end up writing their own little helper tool that they discard when their app is done. So many devs have created these throwaway apps that we decided to provide a workbench that can help you develop and test your app without writing this throwaway code. Our FDC3 Workbench works for any FDC3-compliant platform, not just for Finsemble.

Note: The FDC3 workbench works with Finsemble 6.0 or later. That’s because the earlier versions of Finsemble don’t fully support FDC3.

Why use the workbench?

Developing and debugging your FDC3 app is much easier if you have a good way of testing your integration code. Our FDC3 Workbench provides you with just that. This app works for any provider. In this tutorial we show you how to use it with Finsemble.

When most people start developing for FDC3, they often create a throw-away tool that helps them test their app. This happens so often that we decided to help. No more throw-away work. You can reuse the workbench whenever you need it.

You can use the workbench in several ways. First, you can experiment with various contexts and intents to learn how the FDC3 standard works. To get going fast, open two instances of the workbench and send messages back and forth between them. That’s one way to quickly get comfortable with FDC3-compliant code.

Second, you can use the workbench as a stand-in for the environment in which your own app will operate. You can test various communications back and forth that you expect your app to receive, and test how your app behaves when it receives different contexts or intents. Finally, you can work on modifying the code in the workbench until it does exactly what you want, and then move this thoroughly tested code into your own app.

Opening the workbench

If you haven’t installed Finsemble yet, check out Installing Finsemble. You don’t have to install the workbench separately. It will be installed for you as a sample app.

If you’re already running Finsemble 6.2 and didn’t add the workbench, or if you are upgrading from an earlier version of Finsemble, you will need to install the workbench app yourself. Specifically, you need to add this entry to your own project's public/configs/application/appd.json :

"FDC3 workbench": {
    "appId": "FDC3 workbench",
    "name": "FDC3 workbench",
    "description": "Development and test tool for FDC3 desktop agents and apps",
    "manifest": {
        "window": {
            "url": "",
            "width": 800,
            "height": 750,
            "options": {
                "minWidth": 75
        "foreign": {
            "components": {	
                "App Launcher": { "launchableByUser": true },
                "Toolbar": { 
                    "iconURL": "" },
                "Window Manager": {
                    "FSBLHeader": true,
                    "persistWindowState": true 
        "interop": {}
    "version": "1.0.0",	
    "tooltip": "FDC3 Workbench",	
    "images": [	
            "url": "",
            "tooltip": "FDC3 logo"	
    "tags": ["fdc3", "interop", "interoperabilty", "developer tool"],	
    "contactEmail": "",	
    "supportEmail": "",	
    "publisher": "Cosaic",		
    "icons": [	
            "url": ""		

If you’re using anything else other than Finsemble, you need to install the app on your provider platform. You can download the workbench from the FDC3 website.

Now that you have the workbench ready, let's open it. In the Finsemble toolbar click the “Apps” menu and pick FDC3 workbench from the dropdown.

Launch the workbench

Your workbench window should look like this:

Start screen

The interface is pretty intuitive. In a moment we'll join a channel and use it to communicate with an app by using contexts and intents, but first let’s take a look at what else is here.

The window consists of multiple panels. The panels on the left represent all the actions you can take in the workbench. And so, you can make the workbench join or leave channels, you can create contexts and intents, and you can also manage the context linking. On the right, we have a panel with 2 tabs. The Current stat tab shows you the current state of the workbench. You can see the channel that the workbench joined, the current context, and the context and intent listeners. The System log tab shows all the actions that the workbench participated in.

In the upper right corner you can see the FDC3 version, the provider it runs on, and the provider version. In our case, it's FDC3 version 1.2 running on Finsemble 6.0. If you choose a different provider, your screen will show that provider instead.

If at any point you are uncertain about FDC3 standards and APIs, follow the Learn more link in the footer. The help opens in a new window.

Joining a channel

Currently Finsemble supports 6 channels and you can have your workbench join any one of them. You can join a channel in one of two ways. The first way is to pick the channel from a dropdown menu of the Channel tab and then click Join:

Join a channel

The other way is specific to Finsemble. You can click the Join icon in the upper left corner of the screen and pick a channel:

Join a channel

Either way, the result is the same: you can see the channel you picked under Current Channel in the “Current state” tab on the right.

Now that your workbench has joined a channel, you can start communicating with other apps. If at any point you want to leave the channel, all you need to do is pick it from the dropdown and click “Leave”. Alternatively, if you pick another channel to join, the workbench will leave the current channel and switch to the new one.

Sharing contexts

A context is the first thing you need to create. In Finsemble a context is a data type in the JSON format. Often you will need the same contexts, so the workbench has multiple templates for you to choose from. You can also write your own code. Here are the available context templates:

  • contact
  • contactList
  • instrument
  • instrumentList
  • organization
  • country
  • position
  • portfolio

Most likely you will pick a template from this list and then modify it as needed. Let’s do this now.

Click the “Context” tab, and click the down arrow in the Template field to display the list of available templates. Let’s pick fdc3.instrument. Here is how this context template looks like:

    "type": "fdc3.instrument", 
    "name": "Microsoft", 
    "id": {  
        "ticker": "MSFT",  
        "RIC": "MSFT.OQ",  
        "ISIN": "US5949181045" 

You can change the name and you can add or remove fields and do any other modifications. As you try out different modifications, the workbench performs code validation for you. The lines where it found problems are marked with the red x so you can easily find and fix any issue.

Caution Caution: It’s best to fix any validation issues before you can use the context.

Let’s switch the company to Home Depot and simplify our context:

    "type": "fdc3.instrument",  
    "name": "Home Depot",  
    "id": { 
        "ticker": "HD"  

When you are done, click "Create context". This context now appears under Context in the right panel, and it is available for your use.

If you modified the template and you want to reuse it later, click "Save template".

Caution: Caution: When you save the template, you are overwriting the existing template. So don’t save it unless you are sure of your changes. If you did overwrite it, all is not lost, but in the extreme cases you will need to reinstall the workbench. For this reason, if you plan to make extensive modifications to a template, it’s best to rename it.

Now that we have our context, we can share it with another app to see how well it works. You would normally use the app you are developing, but for our purposes let’s open the AG-Grid example blotter. You can find it in the Apps dropdown on the Finsemble taskbar. When the blotter appears, you need to join it to the same channel as our workbench. Click the Link icon in the upper left corner and pick the appropriate channel.

Our blotter app is now ready to receive a context from the workbench. Let’s broadcast the contest by clicking the "Broadcast" button. When the blotter app receives this context, it displays the information associated with it. All the other information in the blotter disappeared. That’s because the context we broadcast specified only this one entity.

Broadcasting to all the apps on the channel

According to the FDC3 standard, all apps on a channel see all the messages that appear on that channel. You can use the workbench to see it in action. Let’s add another app. From the Apps dropdown, pick the ChartIQ example app. Open it and then join it to the same channel that your workbench and your blotter already joined.

Let’s modify the context as here:

    "type": "fdc3.instrument", 
    "name": "3M", 
    "id": {  
        "ticker": "MMM" 

Click "Create context". You will see this context in the Context textbox on the right. Now click the "Broadcast" button. Notice that both apps, the chart and the blotter, received this context and reacted to it:

Incidentally, it is possible to prevent the apps on the same channel from receiving communication from some app. To do so, you need to use selectConnect.

You can keep modifying and rebroadcasting your code until you're happy with it. When you get your code working the way you want it to, copy it by clicking the "Copy code" button. You can then paste the code into your own app, confident that it works correctly.

Broadcasting works both ways, so the workbench can also receive broadcasts. Before we try this, we must add a context listener to the workbench. It is not enough that both the blotter and the workbench are on the same channel. You must add a listener of the appropriate type. Without the listener, there is no way for the workbench to receive the broadcast. Usually, you specify the type of the context listener so that the listener ignores all the other types. However, it is possible to have a listener without a specific type. Such a listener receives all contexts.

To add a listener, under “Add context listener” in the left panel pick a context listener from the dropdown and click "Add listener". The context listener will appear under Context Listeners in the right panel. You can delete the listener later by clicking the "Delete" icon.

In a real app, you would add code to process the data your app received, but here we are only going to show that the data arrived.

Our workbench is now ready to receive contexts of this specific type. Let’s try it. In the AG grid, clear the Symbol search field to show all the available ticker symbols. Pick one, such as BA, and double-click it. The fdc3.instrument listener now shows the content for British Airways, ticker symbol BA, which looks similar to this:


So now we have 2 components that can talk to each other, broadcasting intents back and forth. Feel free to try it. Experiment with the workbench and an app of your choice to see this in action.


Now that we have contexts working, let's add intents. The simplest thing we can do is raise an intent for context. We have a context ready in our workbench, so let’s use it. Under Intents in the left panel, click Raise context.

Next, we will raise an intent. From the Content type list, pick View chart, and then click "Raise intent". Finsemble now finds the app that can handle this intent, in our case ChartIQ example app. The chart app opens and displays the chart for the context we set earlier.

The workbench contains these intents:

  • startCall
  • startChart
  • viewChart
  • viewContact
  • viewQuote
  • viewNews
  • viewAnalysis
  • viewInstrument

For the communication to flow in the other direction, that is, for the workbench to receive intents from other apps, we need to add an intent listener. Let’s add one now. Under Add intent listener, pick ViewChart from the dropdown menu, and then click "Add".

There is a listener for every intent, and so the list of available intent listeners is the same as the list of available intents.

Our Workbench doesn’t support adding intent listeners yet. Expect it to come in the near future.

Using the workbench to learn more about FDC3

If you want some practice with FDC3, here is one thing to try:

  1. Open 2 instances of the workbench and place them on your screen side by side. On the left, we have workbench A, on the right we have workbench B.

  2. Join both workbenches to the same channel. Here we join channel 1.

  3. In workbench A, create a context. Here, we created an context.

  4. In workbench B, create a context listener for that context. We have created an context listener.

  5. In workbench A, in the Context tab, click Broadcast context. You will now see workbench B receive the broadcast context from workbench A. Your screen should look similar to this:

Now it's your turn. Go ahead and experiment with sending the information back and forth to see how it works in practice.

Viewing the system log

Now that we have performed several actions, let's view the system log. In the right panel, click the System log tab. You can now see all the steps we took in this tutorial. You can see all the channels we joined and left, all the contexts we broadcast and all the contexts we received, and so on. Scroll down to the bottom of the panel to review all our actions:

Go ahead and play with the workbench and other apps, sending and receiving information using the FDC3 protocol. Feel free to experiment with modifying our templates. You can always restore them to the original if you need to.

Testing and debugging

You can test and debug the FDC3-related issues with the workbench, but there might be other problems in your app that you might want to diagnose. To help you with this task, check out the Troubleshooting topic. You might also want to use the Central logger.

How to add FDC3 capabilities to an app

You can test any FDC3-compliant app by using the workbench. Until now, we assumed the apps we work with already have FDC3 capabilities. But many apps don’t. There are 3 ways to make an app use FDC3 to communicate:

  1. Design the app as FDC3-compliant from the beginning. If you’re developing your app from scratch, this is the best way to do it.
  2. Add a preload to a non-FDC3 app. Preloads work for web apps only. For more info about preloads, see Preloads.
  3. Add code that supports FDC3 capabilities to the existing non-compliant app. This could be faster than developing your app from scratch.