Call a WebSocket

Using Nexmo’s Voice API, you can connect PSTN phone calls to WebSocket endpoints. This means that any app that hosts a WebSocket server can now be a participant in a Nexmo voice conversation. Voice API removes all the hard work, a WebSocket is just another endpoint that you can connect to using an NCCO or an API call.

WebSockets is a computer communications protocol that provides full-duplex communication channels over a single TCP connection. WebSocket is implemented in Web browsers and web servers. For example, the Firefox and Google Chrome browsers, and the Tornado Web server.

Easy WebSocket connections using Voice API enables some innovative use cases, including easily integrating:

  • Artificial intelligence engines and bots (like Amazon's Lex platform) that can be conferenced into a meeting to enable faster decision making.
  • Analysis engines into voice calls to determine sentiment.
  • Bots that:
    • Make outbound calls to do simple tasks such as making a restaurant reservation or more complex ones, such as requesting information from field experts.
    • Take inbound calls and make their expertise more readily available. For example, a doctor in a small village in Tanzania can call a medical expert bot and get access to the same medical advice available to specialists at the Mayo Clinic.
  • Third party voice recognition, recording, and transcription engines.

In this section you see how to easily test a Voice API connect to a WebSocket endpoint. You create a NCCO that connects an inbound PSTN call to the echo server using WebSocket and a dual function server that provisions NCCOs and echoes voice messages back to a Websocket:


To follow the steps in this section you need a:

Create an echo server

The echo server provides the NCCO used by Nexmo to connect to a WebSocket and the WebSocket Voice API connects to.

When Voice API connects to a WebSocket endpoint, Nexmo makes an initial HTTP GET request for a WebSocket. The server responds with an HTTP 101 to switch protocols, the connection is upgraded to WebSocket. At that point you have a persistent TCP connection between Nexmo and the echo server. The initial message sent by Nexmo is plain text with metadata. Other text messages are sent mid-stream. You should inspect each message to determine if it contains text or binary data and parse binary frames only as audio.

When a message is received, the echo server tests if it binary. If so, it is echoed to the originator. Once the connection is established, fully bidirectional messages can originate from either end and do not need a response. Text messages are printed to the console. When the client terminates the connection it is removed from the list.

In a real world implementation, you either record the binary message to a file or pass the data to some audio processing code. You can also send audio back to the call at any point. You do not have to respond to an incoming message.

To create and run your echo server:

  1. Depending on the language you use, copy the following code to a local file echo_server:

    var WebSocketServer = require('websocket').server;
    var http = require('http');
    var HttpDispatcher = require('httpdispatcher');
    var dispatcher     = new HttpDispatcher();
    const fs = require('fs');
    //Create a server
    var server = http.createServer(handleRequest);
    var wsServer = new WebSocketServer({
        httpServer: server,
        autoAcceptConnections: true,
    //Lets use our dispatcher
    function handleRequest(request, response){
        try {
            //log the request on console
            dispatcher.dispatch(request, response);
        } catch(err) {
    // Serve the ncco
    dispatcher.onGet("/ncco", function(req, res) {
        fs.readFile('./ncco.json', function(error, data) {
           res.writeHead(200, { 'Content-Type': 'application/json' });
           res.end(data, 'utf-8');
    wsServer.on('connect', function(connection) {
        console.log((new Date()) + ' Connection accepted' + ' - Protocol Version ' + connection.webSocketVersion);
        connection.on('message', function(message) {
            if (message.type === 'utf8') {
                // Reflect the message back
            else if (message.type === 'binary') {
                console.log("Binary Message Recieved");
                // Reflect the message back
        connection.on('close', function(reasonCode, description) {
            console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
    //Lets start our server
    server.listen(8000, function(){
        //Callback triggered when server is successfully listening. Hurray!
        console.log("Server listening on: http://localhost:%s", 8000);

    To run this code sample you need to install the following dependencies:

    npm install http websocket httpdispatcher

    Run your application:

    node echo_server.js
    #!/usr/bin/env python
    import tornado.httpserver
    import tornado.websocket
    import tornado.ioloop
    import tornado.web
    class WSHandler(tornado.websocket.WebSocketHandler):
        connections = []
        def open(self):
            print("client connected")
            # Add the connection to the list of connections
        def on_message(self, message):
            #Check if message is Binary or Text
            if type(message) == str:
                print("Binary Message recieved")
                # Echo the binary message back to where it came from
                self.write_message(message, binary=True)
                #Send back a simple "OK"
        def on_close(self):
            # Remove the connection from the list of connections
            print("client disconnected")
    class NCCOHandler(tornado.web.RequestHandler):
        def get(self):
            with open("ncco.json", 'r') as f:
                ncco =
            self.set_header("Content-Type", 'application/json')
    application = tornado.web.Application([(r'/socket', WSHandler),
                                            (r'/ncco', NCCOHandler)])
    if __name__ == "__main__":
        http_server = tornado.httpserver.HTTPServer(application)

    Tornado is a Python web framework and asynchronous networking library. It is ideal for long polling, WebSockets, and other applications that require a long-lived connection to each user. To install it, call: pip install tornado

    Run your application:

  2. If you are running the server locally, open an http tunnel to the echo server:

    ngrok http 8000
  3. Note the URL to your echo server.

Connect a PSTN voice call to a WebSocket

To the Voice API, a WebSocket is just another endpoint. When you call the virtual number associated with your application, the NCCO at answer_url tells Voice API to connect your inbound call to the echo server using a WebSocket. If you use the NCCO below, you'll hear a brief introductory message before being connected to the WebSocket.

Participant App answer_url Participant Nexmo Participant User Participant EchoServer User->Nexmo: Call virtual number Nexmo->App answer_url: Send Call info App answer_url->Nexmo: Return NCCO with\nWebSocket connect Nexmo->EchoServer: Initiate Call leg User->EchoServer: Hi. EchoServer->User: Hi.

To connect an inbound PSTN call to the echo server using a WebSocket:

  1. Use the following template to create ncco.json. This file contains the NCCO to connect an incoming PSTN call to a WebSocket:

        "text":"Please wait while we connect you"
  2. Place ncco.json in the same directory as

  3. Ensure that answer_url for your Application is pointing to the echo server. If not, use the Nexmo CLI or Application API to update answer_url.

  4. Call the virtual number associated with your Application and listen to your own words of wisdom.

And that is it. Using Voice API you have connected a PSTN call to a WebSocket.