Amazon Web Services

Intro to Amazon Connect Streams API – Part 1

Amazon Connect Streams (Streams) is a JavaScript API that enables browser-based integrations with the Amazon Connect contact center. This series of blog posts covers three basic scenarios using Streams:

  1. Embedding the Contact Control Panel (Part 1)
  2. Subscribing to Streams Events (Part 2)
  3. Creating a Custom User Experience (Part 2)

Source code from this post is on GitHub at:

Source code and documentation for Streams is on GitHub:

As I was working through these samples, I was impressed by how smooth it went and how reliably Streams worked. Kudos to the Amazon Connect team for making it easy to get from nothing to something in a short time.

With that said, let’s get into it!


Developer Setup

Amazon does not distribute a pre-built version of Streams, so before we get started with our application we need to get the source from GitHub and build the Streams JavaScript file with make. This approach should work out of the box for developers on a Linux and Mac, but for my fellow Windows developers we have a few extra steps to take.

Buffing Up the Windows Command Line

The best way to get going on Windows is to first install the console emulator cmder from . Select the “full” version and you now have a Windows command line on steroids, with all the standard Unix commands, git command line, and lots of neat graphical options to tweak.

After cmder, we also need the make build tool for Windows. Download and install this from .

At this point, you should be able to open cmder, key in “make” and see an error message similar to “no targets specified and no makefile found”. If the command line cannot find make, you may have to update your PATH variable to include the path to make. Great, now we’re all set to join our Linux and Mac friends!

Cloning and building from GitHub

Follow the instructions at: to clone Streams from GitHub and then invoke make to generate the connect-streams JavaScript file. In short:

  1. Open your terminal of choice and change directories to wherever you want to put the Streams code for now
  2. Get the Streams code by keying in “git clone
  3. Build the “connect-streams-version.js” file by keying in “make” in the newly created amazon-connect-streams directory

As of this writing, the latest version is 1.2.0, so the output file should be connect-streams-v1.2.0.js. This is the file we will include in our application use Streams.

Sidebar: What is the makefile doing?

I was surprised to see a makefile being used for a JavaScript project, so I took a look. I’ve reproduced it below with inline comments about what’s going on:

 # Minimal Makefile for amazon-connect JS.
 # Concatenates JS assets in the correct order.

 # Invokes git to grab the version number of the library (i.e. v1.2.0)
 VERSION = $(shell git describe --tags)
 # Sets the output file name using this version number
 OUTPUT_JS = 'amazon-connect-$(VERSION).js'

 # A list of the all the individual JavaScript source files that make up Streams
 SOURCE_FILES = src/aws-client.js \
 src/sprintf.js \
 src/log.js \
 src/util.js \
 src/event.js \
 src/streams.js \
 src/client.js \
 src/transitions.js \
 src/api.js \
 src/core.js \
 src/ringtone.js \
 src/softphone.js \

 # Sets a rule (build task) of "all" that invokes $(OUTPUT_JS)
 all: $(OUTPUT_JS)

 # Defines what $(OUTPUT_JS) is
 # $^ is a special macro which represents what's to the right of the ":"
 # $@ is a special macro which represents what's to the left of the ":"
 # So the below command is really "cat $(SOURCE_FILES) > $(OUTPUT_JS)"
 # ...which means to concatenate all the source files into the output file
 cat $^ >$@

 rm -f $(OUTPUT_JS)

 # What rule to run when you invoke the makefile with no parameters

.PHONY: clean css

Application Whitelist

All of the sample applications we will build must be on the Amazon Connect Application Integration whitelist for Streams to work correctly. More specifically the domain of the application (please use HTTPS), must be on the whitelist. The purpose of the whitelist is to protect the CCP from being loaded in the iframe of malicious webpages. Check out the instructions on the Streams GitHub page: .

Be careful to log into the AWS Console and go the “Amazon Connect virtual contact instances” page ( to find your Amazon Connect instance and the Application Integration whitelist. Don’t be like me and look fruitlessly in your Amazon Connect instance Dashboard.

When running your own Streams API application locally, make sure you add localhost, plus the appropriate port number to the whitelist.

Sidebar: What if I don’t?

If you don’t like following directions or are just curious and try to initialize Streams and the CPP without adding your application to the whitelist, the CCP will not load and you will get some distinctive errors in the JavaScript console. Namely:

 Refused to display '{your_ccp_url}' in a frame because it set 'X-Frame-Options' to 'sameorigin'

For more details on X-Frame-Options and origins see:



1. Embedding the Contact Control Panel

Amazon Web Services - Avoid Contact Center Outages: Plan Your Upgrade to Amazon Connect
Avoid Contact Center Outages: Plan Your Upgrade to Amazon Connect

Learn the six most common pitfalls when upgrading your contact center, and how Amazon Connect can help you avoid them.

Get the Guide

You can see the full code for this sample by cloning my GitHub repository and checking out the “sample-1-embedding-ccp” tag. Keep in mind that Streams applications, like Amazon Connect, only work in Chrome and Firefox

Thanks for sticking around through all the setup! Time to get cracking and see what Streams can do.

Our first sample application uses Streams to embed the Amazon Connect Contact Control Panel (CCP) in a host HTML and JavaScript web application. This sample application lets you change your status and handle contacts through the default CCP user experience. To keep it simple, I’ll use inline JavaScript and avoid any client side JavaScript frameworks. We end up with just a few lines of JavaScript code and minimal HTML in our index.html:

 <!DOCTYPE html>
 <div id="myApp">
 <h1>Amazon Connect Streams API Samples<h1>
 <h2>Embedding CCP</h2>
 <div id="containerDiv" style="width: 320px; min-width: 200px; height: 465px; min-height: 400px; ">
 <!--Amazon CCP will go here-->
 <script src="amazon-connect-v1.2.0.js"></script>
 <script type="text/javascript">
 //replace with the CCP URL for your Amazon Connect instance
 var ccpUrl = "your_CCP_Url";

 connect.core.initCCP(containerDiv, {
    ccpUrl: ccpUrl,
    loginPopup: true,
    softphone: {
    allowFramedSoftphone: true


Below is a screenshot of the application in action with an active contact:

Let’s dig into how this works by examining the HTML and JavaScript more closely.


Getting Your CCP URL

Depending on how fast you scanned the index.html code above, you may have noticed that a comment in the JavaScript telling us to replace the ccpUrl variable assigment with the CCP URL of our instance.

The CCP URL is the direct URL to your Amazon Connect instance’s CCP. To find this URL, just open the CCP from your Amazon Connect instance and grab the URL from the address bar. It should be something like: “” Copy that URL into the JavaScript and we now have a good ccpUrl variable.


Positioning the CCP on Screen

Streams needs a DOM element to put the CCP in. More precisely it will insert an iframe within this DOM element to host the CCP. The GitHub documentation suggests providing a div element with an id of “containerDiv”, as we do in the above HTML. We provide this element to the Streams initCCP method.

Sidebar: Tricky browsers

If you take a closer look at the JavaScript, you can see we pass a containerDiv variable to the initCCP method without explicitly declaring it:

    //containerDiv was never defined
    connect.core.initCCP(containerDiv, {

You might expect to have to use document.getElementbyId or jQuery to grab the DOM element and assign it to this variable. Instead it just works.

This may be old hat if you’ve done a lot of web development, but what’s going on here is that the browser is automatically creating global variables for elements with id’s. So the containerDiv variable is already the DOM element for div with id “containerDiv”.

To see this further, you can open the JavaScript console and key in “myApp” to see that a myApp variable exists and is assigned to the proper DOM element. This is pretty convenient and broadly supported across browsers, but you may want to explicitly grab the element into a variable anyway in production code. Being web development, of course opinions vary (


Initializing the CCP

When you load the Streams JavaScript file, the Streams library loads itself into the “connect” global object. To initialize Streams and load the CCP, you have to use the connect.core.initCCP method, passing in the container div and the CCP URL. You also have to set some flags to configure the CCP:

connect.core.initCCP(containerDiv, {    
    ccpUrl: ccpUrl,        
    loginPopup: true,         
    softphone: {
        allowFramedSoftphone: true

Flags, flags

The full list of flags and what they do is in the documentation on GitHub at:

Two flags of interest for this example are loginPopup and softphone.allowFramedSoftphone.

loginPopup should be set to true. This means that if/when your login to Amazon Connect expires and you need to login, the Streams API will open a pop-up window to the Amazon Connect login page.

softphone.allowFramedSoftphone should also be set to true. This allows audio to flow through from Amazon Connect to the CCP in the iframe. If this is set to false, incoming calls will ring in your application and you will be able to try and accept them through the CCP, but the calls will never be connected.

If set to true, when the CCP is loaded the first time, you will see some log messages in the JavaScript console indicating that the voice engine has been initialized:

[INFO]: VoiceRingtoneEngine initialized.
[INFO]: QueueCallbackRingtoneEngine initialized.

Set softphone.allowFramedSoftphone to false if you plan on having your agents use the default CCP and just want to get event notifications (covered in part 2) to your application.


Taking a Call

Go ahead and place a call to the sample application. You should be able to accept the incoming call in the CCP and take any call control actions you need. It is impressive how little code we need to do this, but at this point our application is not all that interesting versus the default CCP. In the next sample we will enrich our application by subscribing to events from Streams and reacting to incoming contacts and agent status changes.

Sidebar: Pop-ups and Login

You may notice that the first time you visit the sample application, a new tab or window will open to Amazon Connect’s login page. After entering your credentials, that window becomes the CCP. For our examples, you should close that CCP window once you log in and navigate back to the sample application window. I will come back and update this post if I can find a way to get around this behavior.


Stay tuned for the second part of this post, covering Streams events and custom experiences!

To learn more about what we can do with Amazon Connect, check out Helping You Get the Most Out of Amazon Connect

About the Author

Peter Miller is a Solutions Architect at Perficient focused on call center solutions including Amazon Connect

More from this Author

Thoughts on “Intro to Amazon Connect Streams API – Part 1”

  1. Hi, I tried aboeve step, but after i launch it on browser, the CCP login keeps on reloading/refreshing so I’m not able to login.

  2. Peter Miller Post author

    The CCP login popup window keeps reloading? Or the CCP itself? Do you see any messages in the browser’s JavaScript console?

  3. Hi, great posts. Re your comment on ‘Pop-ups and Login’ – did you find any other way to close down that CCP pop up? I did find a reference on an AWS forum which mostly works..

    then in function subscribeToAgentEvents:
    const w =”, connect.MasterTopics.LOGIN_POPUP);
    if (w) {

    I am unsure if there are circumstances were this wouldn’t work though.. but when the agent state changes (logs in), it closes down that window nicely.

  4. Peter Miller Post author

    I’ve also seen a number of forum posts on the topic. Something like that gets you close. If it is vital to close the CCP window after you login, you can disable the auto-login from your Streams app, pop the CCP manually in your application code, hold onto a reference to that window and close it when you get a login event for the Agent

  5. Great instructions! – I’m hitting a problem with what seems to be the whitelisting as I’m receiving ‘Refused to display ” in a frame because it set ‘X-Frame-Options’ to ‘sameorigin’.’ errors in the browser console. I’ve included the origins in the application integration section of Connect using the format ‘ but still with no luck. Can anybody provide any advice?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe to the Weekly Blog Digest:

Sign Up