Part 1: Installing PCCE 12 – The Core

Lately Cloverhound has been doing a lot of work on PCCE and with the introduction of version 12 things are quite different from UCCE. We figured it was time to write a blog as Cisco’s documentation on PCCE vs. UCCE for each of the versions is very tough to navigate. This will be one of our most in depth posts covering the entire install and initial configuration process step by step. We’ll assume you know some of the basic CCE terminology and concepts, read up on our CCE intro if you need a primer. Otherwise, let’s get started!

The Differences between PCCE and UCCE

PCCE (Packaged Contact Center Enterprise) is a variant of UCCE (Unified Contact Center Enterprise) that uses the same architecture in the backend. That means it has the same system components (Router, Logger, PG, CVP, etc..) and the same tools to use in troubleshooting the system. That being said, PCCE (especially v12) is quite different in the following ways:

  • PCCE is extremely strict in what architectures are allowed. It can only be deployed following Cisco’s documented “reference designs.”
  • Heavily automated installation process with strict requirement checks. This is drastically different from UCCE. If you’re coming in with experience installing UCCE, read the manual before you do anything!
  • Administration of the platform. For several versions now PCCE has featured a web based administrator not fully available in UCCE. In version 12, this has been significantly enhanced and to include full system administration and features formerly part of the CVP Operations Console. The new administration app is known as the “SPOG” aka Single Pane of Glass. For the most part nothing is configured under the old “Configuration Manager” utility.
  • Even components like ECE have a SPOG page add-on that allows central configuration. The SPOG page offers a ‘gadget’ like add-on and you too, can write third party administration tools and integrate them into the SPOG. I know your all dying to see it so it looks like this:

Screen Shot 2020-02-06 at 2.15.29 PM

  • Some optional components like Dialer still follow a somewhat hybrid process. You still need to manually deploy the PIM’s on the MRPG, however there is a MRPG pre-built that is auto deployed with PCCE now.

So as you can see above, there are a lot of differences and plenty that is familiar.


Important Requirements and Gotchas


DO NOT SKIP THIS SECTION! Especially if you have prior experience installing CCE, there are critical differences and gotchas in PCCE v12 that can cost you a lot of time if you ignore them.


  • PCCE requires and actively validates that your server layout exactly matches the reference design, including which VM is placed on which UCS chassis and the presence of unsupported VMs on same (lab builds are lenient on VM placement but not OVA template usage). This means Router, Logger, PG, AW/HDS, CVP Finesse and CUIC all have explicit requirements with how many of each of these servers you need and whether the environment is simplex or duplex. You must choose on the reference layouts documented in the CCE design guide, supporting either 2000, 4000 or 12000 agent counts. If your VM layout doesn’t exactly match one of these reference designs, YOUR INSTALL WILL FAIL, NO EXCEPTIONS.
  • The PCCE installer knows everything. It inspects the model of UCS chassis you are running, it knows every single VM on every chassis and what purpose it serves, and it knows exactly what OVAs are in use and whether they have been altered. Do not try and fool the installer or take shortcuts, it will punish you by failing to install.
  • No CVP Operations Console as of PCCE v12. Don’t install it, all Operations Console functions have moved to the all-powerful SPOG.
  • Once the core is deployed you can do things like deploy extra CVPs and VVBs at remote locations in order to keep call treatment local. PCCE refers to these locations as ‘sites’.
  • Some components like Dialer and ECE are optional, however, Cisco has streamlined the process for adding them on. We will cover these in future posts as the core PCCE installation process does not include them.
  • Don’t do ANYTHING manually that you would do in UCCE to install, unless explicitly outlined in the PCCE installation guide. Don’t even run ICMDBA on the logger. Literally do absolutely nothing after you install ICM and all the components. (You will run Domain Manager still but we cover that shortly). There is a special SQL Server database automatically created when you launch the installer called pcce_inventory tracks your inventory and installation progress. Manual changes will tend to freeze this database mid-progress and block you from proceeding. You’ll then get into an infinite loop of deleting all configuration on machines and deleting the ‘pcce_inventory’ DB until you hit that magic amount of reboots to get the PCCE installer running again. It’s like a trap specially designed to capture people who know a lot of UCCE already. Trust us on this: play dumb, read the install guide line by line, and touch NOTHING after running the PCCE installer that isn’t explicitly in the install guide or mentioned here.
  • One more time: FOLLOW THE INSTALLATION GUIDE (and this post) to a T. We’ll include links to Cisco docs where appropriate.

Server Layouts

In this post we will be deploying the Lab Only Duplex-mode model. Here is the link to Cisco that describes this layout:

The layout for our servers is as follows according to this doc.

Screen Shot 2019-12-24 at 12.45.24 PM

  • You are probably wondering what other layouts we can deploy and how they map to UCCE. Here is a table from Cisco’s design guide:

Screen Shot 2019-12-24 at 12.40.20 PM

Here is a screenshot of all the server deployment options straight from the installer.

Screen Shot 2019-12-24 at 11.19.11 PM

Remember, the Lab Only option does not enforce server model and VM placement requirements. If you’re installing one of the production reference designs, things will be even stricter than what you see in this post. Follow the reference guide exactly.

The Server and App installs

Let’s take a quick look at the Installation Guide for the 2,000 agent reference design just to hammer home that we only run the installer and do NO configuration. The link is here:

As you can see from the outline the steps they give are very high level:

Screen Shot 2019-12-24 at 12.36.40 PM

If we dig down into say the Rogger here is what we get for the steps for installing the Rogger:

Screen Shot 2019-12-24 at 12.32.23 PM

Effectively the steps are setup VM, install Windows and SQL Server, and run CCE installer. This is literally all we do to get it to the point the PCCE installer will run and do all of it’s magic. Install each server on this page to the exact place it says and STOP.

The exception is any component running on Cisco’s Linux platform – UCOS, such as UCM, CUIC, VVB, and Finesse. These are setup as before by running through the UCOS setup wizard. The exception is you do not configure the applications via their web UI unless stated otherwise.

Note: PCCE and UCCE v12 support changed from Windows 2012 to Windows 2016 in after initial release. New install ISOs were issued for the 2016 compatible version. PCCE 12 is ONLY supported on Windows 2016 now. Make sure you install Windows 2016. If the installer complains about not support it, you need to get the updated installer image. Here is the official communication from Cisco:

Below is an outline of the steps we will follow in this post. You can find the CCE OVA templates here (needs a Cisco account with download access):

Screen Shot 2019-12-24 at 2.22.18 PM

  1. Install 2 Roggers and 2 AW/HDSs (Side A and B)
    1. Create VM from OVA Templates.
    2. Install Windows 2016. (Make sure to license it as either Standard or Enterprise, the installer will not allow Windows 2016 Evaluation or Developer editions).
    3. Install SQL Server 2017. Make sure to follow the Cisco installation guide step by step:
    4. Run PCCE 12.0(1) installer from the 2016 compatible ISO. (See Appendix A for screenshots and process to this installer).
    5. Install PCCE Mandatory update found on CCO here: Shot 2019-12-24 at 2.28.22 PM
  1. Install 2 PGs (Side A and B)
    1. Create VM from OVA Templates.
    2. Install Windows 2016.
    3. Run PCCE 12.0(1) installer from the 2016 compatible ISO. (See Appendix A for screenshots and process to this installer).
    4. Install PCCE Mandatory update found on CCO here:
  2. Install 2 CVP Call/VXML servers.
    1. Create VM from OVA Templates.
    2. Install Windows 2016.
    3. Download CVP Software from
    4. Install CVP 12.0(1) ISO for Windows 2016. (See Appendix B for screenshots and process to this installer)
  3. Install 3 CUCM Servers (1 Publisher, 2 Subscribers). For the purposes of this lab we’ll install 12.5(1), which is supported with PCCE 12.0.
    1. Create VM from OVA Template.
    2. Install CUCM Pub
    3. Install CUCM Sub 1
    4. Install CUCM Sub 2
    5. Patch CUCM Primary to ES1 (Software here:
    6. Patch CUCM Subscribers to ES1
  4. Install 2 Finesse servers (Primary and Secondary). The process is similar to installing a CUCM Cluster.
    1. Create VM from OVA Template.
    2. Download Software off
    3. Install Finesse Primary
    4. Install Finesse Secondary
    5. Patch Finesse Primary to ES2 (Software here:
    6. Patch Finesse Secondary to ES2
  5. Install 2 CUIC (Publisher and Subscriber). The process is similar to installing a CUCM Cluster.
    1. Create VM from OVA Template:
    2. Download Software off

   Screen Shot 2019-12-24 at 2.38.45 PM

    1. Install CUIC Publisher
    2. Install CUIC Subscriber


You can find the detailed processes for installing each in the appendix.

Running Domain Manager

The steps as documented by Cisco are a little confusing, but once all the servers are built and installed exactly as Cisco lays out for your reference design we are going to follow the Post-Installation section of the following guide:

This will show us how to get PCCE installed and configured. The first thing we need to do is log into our AW and run Domain Manager to create the appropriate OU within Active Directory to support CCE. This step is exactly the same as in UCCE. Nothing has changed here. To run the tool, you will need a domain account that has admin permissions on the parent OU that will house the OU generated by CCE. The Domain Manager tool will create this OU based on an instance name you select, as well as a couple child OUs and several security groups – all contained within the generated OU. CCE will not make any schema changes or any changes at all outside of this OU.

To run the tool: Open up the ‘Unified CCE Tools’ on the AW desktop and look for Domain Manager. Alternatively, open up the search toolbar in Windows and start typing “Domain Manager”.

Screen Shot 2019-12-24 at 5.02.22 PM

When you run the tool, it will automatically load your domain information. If you’re not seeing this, you probably haven’t added the machines to a domain. Make sure to join every PCCE or CVP Windows server to your domain.

Screen Shot 2019-12-24 at 5.02.43 PM

Once open, select the domain, then click Add under Cisco Root in the toolbar on the right. This will add the magic OU named “Cisco_ICM” to the domain where PCCE will house its domain accounts and security groups. The user using Domain Manager does necessarily need to be a Domain Admin, but does need admin rights to the parent OU in which you are creating the ‘Cisco_ICM’ OU. For lab purposes, its easiest to just use a Domain Admin.
After clicking ‘Add’ you’ll have to confirm where the in domain you want the ‘Cisco_ICM’ OU to live. For our lab, we’ll just have it live under the root of In production, you may want to place this within a separate OU (this is the OU to which you need admin rights).

Screen Shot 2019-12-24 at 5.02.55 PM

Press ‘OK’ and we’ll see this next screen where we can add a ‘Facility’, which is used to group permissions for multiple PCCE instances (for example: prod, lab and test).

Screen Shot 2019-12-24 at 5.03.09 PM

Click add. We’ll just create a Facility named ‘lab’ for our lab:

Screen Shot 2019-12-24 at 5.11.01 PM

Click OK and we’ll see this … almost there.

Screen Shot 2019-12-24 at 5.09.04 PM

Finally click ‘Add’ under ‘Instance’. This will add an instance which corresponds to a single installation of PCCE. Whatever we enter here will also be the naming convention for our databases, as well as various command line tools. Typically this is a short 3-5 character abbreviation for your company name. For our lab we are going to abbreviate “Cloverhound” and name our instance: ‘clv’.

Screen Shot 2019-12-24 at 5.11.11 PM

Click ‘OK’ and we are done! Here is the finished product.

Screen Shot 2019-12-24 at 5.09.13 PM

Note on Facility and Instance naming: You can only backup and restore PCCE databases if they have the exact same instance name. If you plan on restoring data from prod to lab or vice versa, then you should name all your instances the same and separate by Facility name (i.e. Facilities named “lab”, “test”, “prod”). This way you can transfer data seamlessly between environments. If however you won’t be transferring databases directly between environments (you can still transfer scripts and import/export configuration via bulk admin tools), then it may be better to name your instances differently (i.e. Instances named “clv”, “clvdev”, “clvtest”) to avoid accidentally applying changes to the wrong environment.

Running the PCCE Installer

After finishing with Domain Manager, the next step is to browse to https://<AW Side A IP>/cceadmin to launch the installer. Note that you do not run the Web Setup tool and add the instance as you do in UCCE.

This brings up a login screen that looks like this:

Screen Shot 2019-12-24 at 11.21.24 PM

For setup, you’ll need to use a domain account belonging to the ‘Setup’ security group within the PCCE OU, and with admin privileges on the Windows servers. The username format needs to be entered as:

In our example, we created an account named ‘ucceadmin’ in the ‘’ domain so our username is entered as ‘’. No other format will work. A local Windows account will not work.

Screen Shot 2019-12-24 at 5.17.13 PM

Once logged in for the first time you should see a blank ‘Overview’ screen:

Screen Shot 2019-12-24 at 5.18.25 PM

Next click the Infrastructure tab and you’ll hopefully see the ‘Deployment Type’ screen. Notice that the Deployment Type dropdown is white and can be selected. This is good!

Screen Shot 2019-12-24 at 11.20.44 PM

Every once in awhile you’ll get the exact same screen but the ‘Deployment Type’ is greyed out. This is not so good. It means the installer thinks an install has already been initiated.  It looks like this:

Screen Shot 2019-12-24 at 5.18.42 PM

If this happens you’ll need to log into SQL Manager on the AW and find the ‘pcceInventory’ database, delete it entirely, and restart the server. Likely this happens due to accidentally running some install steps manually (see our earlier warnings about not doing this) but in our experience it wasn’t always clear why and we tend to run into this at least once every time. Maybe you will have better luck. If you have run install steps manually make sure to undo them, delete anything you’ve configured that you shouldn’t have, then delete the ‘pcceInventory’ database and restart.

The ‘pcceInventory’ database visible in SQL Studio:

Screen Shot 2019-12-24 at 11.04.18 PM

Once working, click the ‘Deployment Type’ dropdown and select your deployment type, then select the instance you setup in Domain Manager:

Screen Shot 2019-12-24 at 11.19.06 PM

For this post we’ll be installing the ‘Packaged CCE: Lab Mode’ deployment type.

Building the System Inventory

This step varies significantly between production deployments (2000, 4000, or 12000) agents and lab. At present we only have screenshots here for Lab Mode, but fortunately inventory setup is simpler in production than in Lab Mode.

A production deploy pretty much configures itself. After selecting your Deployment Type, you’ll be asked for your ESXi addresses and root logins. Once provided, the installer will auto-magically discover and configure your entire core inventory (optional components are still added later). From here, it will ask you to enter credentials for the various components.

This is mostly straightforward, except note that when it asks for “Service Account”. If you don’t auto create, you can provide an existing domain account that will be used to run the Logger and Distributor (part of the AW/HDS) Windows services. This account should be created before entering here, and made part of the ‘Service’ security group in the PCCE OU.

Details can be found in the PCCE Administration guide, here:

Since a lab build does not require strict VM placement, it cannot auto-discover all your components via ESXi. Instead, it will ask you to upload an inventory spreadsheet, as seen in the screen below. You can configure this by providing an csv file – a template for which can be downloaded from the Inventory page. Note there is a bug (CSCv040197) with the example being wrong for CVP credentials.

Screen Shot 2019-12-24 at 11.20.12 PM

Notice that the Download box is greyed out. This is a lie, ignore it and click anyways to download the template file.

Here’s a screenshot of the template example file to give an idea what it’s looking for:

Screen Shot 2019-12-30 at 4.03.39 PM

You will need to include one line for each mandatory machine in your environment. Optional components can be added later via the UI.

Most of the fields are self explanatory other than the ‘publicAddressServices’ field. You can find a detailed description of the inventory template format in the PCCE admin guide here:

This is the contents of the final file we used in our lab with all the correct formats ( passwords are not real). We saved this as a file named ‘inventory.csv’.









CREATE,CUICPUB,CUIC_PUBLISHER,,type=DIAGNOSTIC_PORTAL&userName=admin&password=cisco; type=IDS&userName=admin&password=cisco,,sideA









After you upload your file the installer will validate line by line to make sure everything is in the correct format. Fix any errors that appear. Here is what it looks like with errors:

Screen Shot 2019-12-30 at 3.59.54 PM

Finishing the PCCE Install

Once the file is validated, the installer will ask you for a domain service account. This is the same as the one described earlier in this section for production builds. For a lab, you can just use your administrator domain account.

Screen Shot 2020-01-06 at 10.32.09 AM

Finally from here it’s time to initialize the install. For the duplex install it will run through 33 steps to be completed. If any step fails it will make you revert the changes (it automates this), fix the error and try it again. You can run into a lot of different issues if you don’t follow the steps exactly, or have the right passwords or have enough storage, or breath on it too hard. Also be sure you don’t make any sudden movements or look it directly in the eyes, as it is easily spooked.

It will look like this as it runs through its steps:

Screen Shot 2020-01-06 at 10.58.49 AM

If you have any issues the screen will look like this below. In this case, one of the AWs was still turned off.

Screen Shot 2020-01-06 at 10.59.25 AM

Once all 33 steps complete successfully you will see this:

Screen Shot 2020-01-20 at 7.30.31 PM

Congratulations! The installer has accepted you and allowed the installation to complete. Next you can click ‘Done’ and if you click ‘Overview’, you will see a completely different menu system!

Screen Shot 2020-01-20 at 7.32.45 PM

The core PCCE install is complete, but we still have some work to do to get call routing functioning completely. The next step is to add a VVB to so it can process IVR instructions from CVP.

Initializing the VVB

The first thing you’re going to want to do is go to your VVB administrator web page and initialize it. This will happen automatically the first time you log into it. 

DO NOT try to add VVB to the PCCE inventory before doing this, or else it will never initialize properly and you’ll need to reinstall VVB from scratch. You were warned. (Also, keep in mind that VVB does not allow admin usernames to start with “vvb”, you’ll run into problems if you do)

To initialize the VVB, browse to the VVB address in your browser and login, after which you will see this screen:

Screen Shot 2020-01-20 at 10.53.52 PMWait for all the services to activate and then click ‘Next’. You will see the following screen:

Screen Shot 2020-01-20 at 10.54.32 PM

The default settings are typically what you want here. Click ‘Next’ again. From here it will tell you configuration is complete and the VVB Service is restarting. Give it about 10 minutes then continue on with the next step.

Adding the VVB to the PCCE Inventory

One of the nice things about the PCCE SPOG is it has a basic monitoring view, although we’ve found that it isn’t always accurate. To reach the inventory status page, from the SPOG navigate to Infrastructure -> Inventory:

Screen Shot 2020-01-20 at 10.56.00 PM

From here you can view your inventory and its status, as well as add optional external components like VVB, CVP Reporting Server, and ECE. Our lab inventory looks like this:

Screen Shot 2020-01-20 at 10.56.17 PM

Most of the alerts in our setup are related to the ICM Diagnostic Framework and aren’t particularly important for our lab. However, if I click on Unified CM Publisher the alerts are very useful. We’ll see they are warning us we have no trunks built to CVP, which is needed to deliver calls to agents:

Screen Shot 2020-01-20 at 11.59.54 PM

This is because the auto-configuration only adds the “pguser” jtapi user for UCM and nothing else. Everything else in UCM needs to be configured by hand the traditional way. We’ll build these trunks in a later section, but wanted to show that many of these alerts are a useful indication of what’s broken and how it should be fixed. Cisco did a really good job here.

Getting back to the task at hand, back on the main inventory page, scroll down to the bottom where it says ‘External Machines’ with a small “plus” icon. Here you can add VVB servers and other external components.

Screen Shot 2020-01-20 at 10.56.36 PMClick on the “plus” icon to add an external component. This brings up a pop-up asking what type of machine to add. The following choices are available in our lab environment:

Screen Shot 2020-01-20 at 10.56.47 PM

To install a VVB (aka Virtualized Voice Browser) you select the ‘Virtualized Voice Browser’ option (surprise, surprise), then enter in the hostname or IP Address of the VVB, and the application username and password, then click save.

Screen Shot 2020-01-20 at 10.57.08 PM

After this the VVB is added to the inventory and hopefully everything shows ‘in sync’.

The settings for the VVB can be found in the CCE Admin page at ‘Overview’ -> ‘Infrastructure Settings’ -> ‘Device Configuration’, as shown below:

Screen Shot 2020-01-20 at 10.58.59 PM

After selecting Device Configuration you will see the VVB configuration. This is where you configure all your VVBs instead of going to the standard VVB admin page. This is also where you configure CVP as you would have previously done in the CVP Ops Console. We did mention there was no Ops Console in PCCE 12.0 right? Well we’re mentioning it again because its import: there is no Ops Console in PCCE 12.0, do not install one.

Screen Shot 2020-01-21 at 12.06.14 AM

In most cases, the default VVB settings are fine. For a simple lab build nothing needs to be changed here, but if you do need to make changes now you know where to go.

Configure SIP Trunks in CUCM

We need to configure SIP trunks in CUCM for the CVPs so that we can deliver calls to agents which are logged in to phones managed by CUCM.

First, from the CUCM admin web page, browse to ‘Device’ -> ‘Trunks’:

Screen Shot 2020-01-21 at 12.08.08 AM

Next add a new SIP Trunk:

Screen Shot 2020-01-21 at 12.08.49 AM

You need create a separate CUCM trunks for each CVP Server – do not make a single trunk with two destinations. In our case we’ll create two trunks for our two CVP servers. Make sure to set the inbound CSS on the trunks to a CSS that can see the agents’ Line partitions.

A few other tips:

  • You’ll also want to make sure you reset the trunks after adding them. If you don’t they won’t work. You have to reset them at least once to put them into service.
  • Always check ‘run on all nodes’. This is especially helpful if you have a 5 server or larger CUCM deployment.

Screen Shot 2020-01-21 at 12.10.06 AM

We can now see in the PCCE dashboard that we have resolved the missing trunk alert:

Screen Shot 2020-01-21 at 12.16.11 AM

Configure CUCM to support internal transfers back to PCCE

Almost every call center is going to want to be able to transfer to agent’s from CUCM back to a queue on PCCE. These are what are known as CUCM PG originated calls. Since they are not CVP originated calls from CUBE we need to program the Network VRU label on CUCM to point back to CVP so it can finish it’s route correlation.

The first thing we need to know is how to find what our Network VRU labels are. They are kind of hidden in PCCE. We are going to go to the SPOG homepage and browse to Overview->Call Settings->Miscellaneous->Main Site. This will show us our Network VRU Labels.

Screen Shot 2020-02-06 at 11.47.36 PM

For CUCM it is 8881111000. That means we need to make a corresponding Route Pattern in CUCM in the Agent Partition that points to CVP. This will allow us to get past the Send to VRU node in PCCE scripts and open an RTP channel with CVP.

First we are going to add our CVP SIP Trunks we just made to a Route Group and a Route List so we can reference them in a Route Pattern.

Screen Shot 2020-01-21 at 12.16.44 AM

Screen Shot 2020-01-21 at 12.17.33 AM

Make sure to reset the route list after creating it and we suggest checking ‘Run on all nodes’ for the Route List’s as well.

Lastly we need to create a route pattern that will allow us to do internal transfers. The 4 X’s represent the 4 digit correlation ID that PCCE prepends by default.

Screen Shot 2020-02-06 at 11.50.03 PM

Configure CUCM to actually work

When you go to route calls to agents it’s going to use a sip server group in PCCE which requires you to use the format of an FQDN. It’s a made up FQDN but none the less CUCM needs to be programmed to use it. If you don’t set what is basically a whitelist, CUCM will reject calls. Your going to want to go to CUCM and browse to System -> Enterprise Parameters -> Clusterwide Domain Configuration and set the following to your domain.

Screen Shot 2020-02-06 at 11.23.05 PM

Configuring CVP Route plan within PCCE

Since CVP is our call control we need to give it a dial-plan. This previously was done in the CVP Ops Console, but as I mentioned this is no more. We are going to create two routes in PCCE. One for our network VRU label and another for our Agent Extensions.

First we are going to browse our PCCE SPOG page to Route Settings -> SIP Server Groups and create Server Groups for our VVBs and for our CUCMs.

We need to use a FQDN so we will use Make sure to choose the type of ‘VRU’.

Screen Shot 2020-02-06 at 2.55.25 PM

Add your VVB members to the SIP Server Group.

Screen Shot 2020-02-06 at 2.57.16 PM

We need to do the exact the same thing for but this time we use a Type of ‘Agent’.

Screen Shot 2020-02-06 at 2.58.48 PM

And for simplicity we will add all our CUCMs to it.

Screen Shot 2020-02-06 at 2.59.04 PM

The next step is to create the correct routes for our PCCE/CVP install. Click on the ‘Routing Patterns’ menu option.  Click ‘New’.

First, we are going to create a 77777777> pattern which is the default Network VRU label shipping with PCCE 12. Make sure to choose Pattern Type ‘VRU’ as well. Our only choice will be the SIP Server group we just created.

Screen Shot 2020-02-06 at 2.57.46 PM

We’ll also want to add a route for 91919191 and 92929292. CVP dials these numbers to play the ringtone and standard error message. 

Repeat the process for our agent extensions. For our lab we will be using 70XX extensions.

Screen Shot 2020-02-06 at 10.41.48 PM

Ingress Gateway Configuration to bring in calls to CVP

The next step is to configure our ingress gateway to send calls to CVP. 

For this config we are using a standard CUBE w/ a SIP trunk from Twilio. Our number for this config is +19802017899. CVP Doesn’t like the + sign on the DNIS numbers so we are going to strip it down to 9802017899. We will make a dial-peer to each CVP server for redundancy.

Screen Shot 2020-02-06 at 12.03.58 PM

Screen Shot 2020-02-06 at 12.04.04 PM

Screen Shot 2020-02-06 at 12.04.22 PM

Screen Shot 2020-02-06 at 12.04.29 PM

Confirming the number is reaching PCCE

The best way to check at this point you’ve gotten the number into PCCE through CVP and everything is communicating as it should be is to check the ICM Router Log Viewer Tool.

You can find it in the path of the following screenshot.

Screen Shot 2020-02-06 at 12.09.26 PM

If you open the tool you should see your test calls hitting the error section of the tool as shown here.

Screen Shot 2020-02-06 at 2.05.11 PM

We are almost there! This means we are good to configure PCCE to treat a call.

Configuring PCCE

The first step is too configure a Call_Type to be the entry point of our script.

We’ll go to the PCCE Web Admin->Overview and choose ‘Route Settings’ in the following box (green):

Screen Shot 2020-02-06 at 12.14.51 PM

From here we’ll browse the top right menu to ‘Call Types’ and select ‘New’. We’ll make the following Call Type.

Screen Shot 2020-02-06 at 12.26.36 PM

Next we need to create a ‘Dialed Number’ which will match our DNIS of 9802017899 that we are sending too PCCE. Browse to ‘Dialed Number’ and click ‘New’.

Screen Shot 2020-02-06 at 12.28.21 PM

Important notes on Dialed Number creation:

  • External Voice is for CVP originated calls and Internal Voice is for CUCM originated Calls.
  • Make sure to select a call type.
  • The Dialed Number String should match the DNIS value you send from CUBE.

Creating a test Script

We are going to use Script Editor to create our first test script in PCCE. We’ll reference the Built In CVP Studio Script ‘HelloWorld’ that ships out of the box for testing your install. You can find the Script Editor utility in the same exact folder you found the Router Log Viewer tool we just used.

Once we get into the utility we are going to want to click the New Script icon. You can also go to File->New.

Screen Shot 2020-02-06 at 12.31.36 PM

From here it will ask us if we want to create a ‘Routing’ script or an ‘Administrative’ script. Choose Routing.

Screen Shot 2020-02-06 at 12.31.44 PM

The script we are going to create will look like this

Screen Shot 2020-02-06 at 3.00.38 PM

Here is a close up of the Set Variable node for our HelloWorld step.

Screen Shot 2020-02-06 at 12.38.57 PM

Scheduling our Script

The final step is using Script Editor to map our ‘CVP_Demo’ Call Type to a Script in PCCE. In Script Editor we are going to go to Script -> Call Type Manager.

Screen Shot 2020-02-06 at 12.39.39 PM

From here we’ll want to select our ‘CVP_Demo’ call type and map it to the script we just created by clicking the ‘Add’ button.

Screen Shot 2020-02-06 at 12.40.01 PM

Give it a test call, it should work!

Let’s configure a few more things to make the install more complete.

Testing calls to agents

In order to test agent functionality we’ll need to configure a few things. The first thing we need to do is create an agent. You can do this by going to Users->Agents and clicking ‘New’ in the SPOG page.

Screen Shot 2020-02-06 at 9.33.04 PM

Next, we need to create a Skill Group and assign our Agent. Browse to Organization->Skills and click on ‘New’. Add a skill and make sure to assign your agent as a member. We’ll name our skill ‘Demo_Skill’.

Screen Shot 2020-02-06 at 9.34.15 PM

Next, you’ll want to create an agent team. You can find this at Organization->Teams. We’ll name our team ‘Demo’. Make sure to assign your agent as a member.

Screen Shot 2020-02-06 at 9.35.14 PM

Finally we’ll want to go edit our script to look like this so we can deliver calls to our new skill and use our HelloWorld app like Music On Hold if an agent isn’t ready.

Screen Shot 2020-02-06 at 9.42.07 PM

That’s it. Login in to Finesse and give it a test call. You should recieve the call!

Testing Internal Transfers from CUCM to CVP

As a final bonus we will configure and test an internal transfer point from PCCE.

First we need to create a new Call Type for the transfer. We’ll make a Call Type named ‘Internal_Transfer’.

Screen Shot 2020-02-06 at 9.50.18 PM

Next, we need to create a new Dialed Number but this time the type should be ‘Internal Voice’. We’ll use the DNIS 8888 for this.

Screen Shot 2020-02-06 at 9.50.59 PM

Now we need to associate the ‘Internal_Transfer’ Call Type to the script we created before.

Screen Shot 2020-02-06 at 9.51.25 PM

The last step is to create a CTI Route point in CUCM with the extension 8888 and associate that CTI Route Point to our pguser.

Screen Shot 2020-02-06 at 9.59.29 PM

Screen Shot 2020-02-06 at 10.00.02 PM

If everything worked out well you should see your CTI Route Point registered to the IP Address of your PG. If it’s isn’t showing registered, it isn’t correct.

Screen Shot 2020-02-06 at 10.57.02 PM

That’s it! Call 8888 from your IP phone and you should reach your agent. 

Congrats you’ve installed PCCE v12!

Thanks to Ed Umansky and Clay Scott for helping to build the lab and review this document!


PSTNgine – An Open-Platform PSTN Alternative

screen shot 2019-01-19 at 2.22.36 pm


One of the items that has long perplexed me in our industry is the stranglehold the carriers have on the market. In many market’s there is only one reasonable option for service and they all work in what feels like an archaic fashion. For instance, I’ve always found the idea of porting numbers between carriers to be strange and that I should be able to own my number and do what I please with it.

I’ve always thought there was big innovation to be had in this space. With the telecommunications market consolidation the past 15 years, they can charge whatever they want for what is essentially internet traffic. We have seen cord-cutting of cable providers in mass, and the PSTN will be next.

Last year, I had some long sleepless nights and I started building a small prototype of something I have been calling PSTNgine. It is powered by SIP and it’s more of a self-registration and ownership platform that lives in the public cloud. It works off current E.164 numbers and provides an alternative path home for the same numbers. Think of it like DNS for public phone numbers.

The general concept is the more companies and individuals who join the network, the more power the carrier loses over the PSTN. The apps and integration points integrate with the traditional PSTN making it seamless for users to adopt with no downside.

screen shot 2019-01-19 at 1.21.32 pm

Solution Benefits

I’m sure the first question your asking is, “Why would I even want this?”.

Lucky for you. I’ve compiled a short list of reasons which by no means represents every use case of the platform.

  • Flexibility: You own your numbers and what happens to them, there is no more ‘porting’ you just point your numbers to the IP address or endpoint you want, when you want. Think of it like an Open-Source PSTN or a DNS system for PSTN numbers.
  • Ease of use: Our mobile apps will let you register any number you can prove you own, including land-lines or small business toll-free, right to your cell phone.
  • Cost Savings: Since all traffic is sent over the public internet you’re using the bandwidth you already own, whether that call is going to Asia or a cell phone. We will obviously be charging for this service, but overall, way cheaper than using traditional PSTN for many types of calls such as international or toll-free. As the network grows everyone on it will save more.
  • Developer Friendly: Our platform is a full SIP Stack in the cloud including support for registration and WebRTC. Not only will we be kicking the PSTNs but you can register some devices and get the full power of a SIP Cloud with the phones you own today!
  • Cloud Apps: Imagine being able to use the full suite of services that were developer for the business user, on your PSTN/Toll-Free number. You’ll be able to power a deep SIP experience with APIs.
  • Open Platform: We don’t want to become the next carrier either, we want to build a new type of network, so we’ll offer access to our E.164 registration data for qualified partners who want to integrate into our SIP network. Terms and conditions will apply to prevent maliciousness.

See it in action:

Solution Design

SIP Core – Proxy

At the heart of PSTNgine is farm of SIP proxies which obviously may need to grow or adapt over-time but for this first couple million users will do just fine. Enough to prove the concept works. The general idea is simple you can send any E164 number to us by shooting a call to (ie. and we will try and get it home for you. If we can’t, you will get a 404 like normal.


A requirement for the enterprise customers is that you must have a public termination point for SIP and RTP. This would be a Proxy or Gateway that has a public IP address or in Cisco, an expressway. Our service lives in the public internet and we expect your on-ramp to be public.

Our SIP registration platform does support NAT if your equipment is configured properly. We can help you determine this and easily give you free testing endpoints. 95% of NAT devices will work fine with no changes to routers.

Phone Number Registration

Anyone can stand up a SIP proxy but the trick here was making it scale and be manageable. At the core of this is a DNS like database that takes an E.164 number and figures out what IP to send the request to (and if any translations should be applied). For example when you call, it will eventually make its way home to The default without a translation would be +19802180991@. Your domain is defined at an organizational level in PSTNgine.

If you call my cell phone, you will eventually make it to my iPhone app running call kit. It’s a native IOS, nice experience. We will of course release a similar Android app.

Once you build an account on our site you can register numbers or ranges of numbers with some two-factor like auth. (We dial the numbers you put in and you enter in the code we tell you, to confirm you own it). For large enterprises, it will be easier to provide us with billing records from your carriers. We will configure it all per your requests and then give you access to your portal for management.

PBX Integrations

The unique opportunity here is for a Cisco PBX for example there is a single integration point to bring your entire network of phones and DID’s onto our network and enabling least-cost routing with out entire network of users. Let’s walk through it with Cisco.

Pre-Requisites with Cisco: 

  • Expressway
  • Communications Manager.
  • Register your egress/ingress point with PSTNgine.
  • DNS records for your endpoints (if using DNS).

Inbound: For any DID you own you will receive requests to your expressway in the format of @<yourdomain/ip>. It’s your job to get those URIs home to your phones just like normal PSTN calls.

Outbound: This is where we do a bit of magic. You’re going to route every single call that would normally go to the carrier to PSTNgine to see if it exists on the network. If we don’t have it we will respond with a 404 and you will go to your normal carrier, here is what that would look like.

  1. Create a Route Group with the trunk to Expressway.
  2. Create a Route Group with the trunk to your CUBE/Carrier.
  3. Create a trunk in your expressway with the creds we have given you.
  4. Create a translation in Expressway to append and fire off the calls to PSTNgine.
  5. Create a Route List with the Expressway Route Group first, and your normal carrier second.

You may want to lower your SIP Retry timers to 250ms just in case our service ever has an issue, that would make an outage seamless to your users.

Every-time a company joins or a person registers a number, every other user on the network gets seamless access to cheaply calling them. The network will grow exponentially every-time a new business joins.

Mobile / Land Line integrations

At launch, an iOS and Android app will be available that sets your mobile phone up on the network with just a couple clicks. This will allow businesses to easily access their employees on the network as well as allowing any individuals access to the network for least-cost calling.

Businesses adopting this for Toll-Free numbers may see greatly reduced costs as the network grows.

SIP Registration

The platform also includes a full SIP Registrar which can support everything from Cisco Phones to WebRTC clients (SIP-WS, such as sip.js library), to our mobile clients. This means if you don’t have your own PBX or are looking to move to IP Phones or to cloud registration, you can use us directly as you voice backend. (Voicemail, transfer, conferencing, IVR, contact center available).

Carrier Access

We have brought a few carriers into our network for use on our platform. As our design calls for, our PBX / direct registered users would want access to the traditional PSTN for calling outside of our network. These services will be available for consumptions by our SIP registered users and for businesses who request access because it may be cheaper than their current carriers for some countries.


Security on our platform will work very closely to how to how firewalls on AWS. You will be required to provide us with your public IP addresses and ports for receiving SIP and RTP. We also offer VPN services for customers trying to connect to our cloud more securely or with a private network

User Interface

Unlike every carrier, our system allows self-provisioning through an easy to use, web interface. This means you can build SIP Trunks or change your firewall settings without the help of us. You can register devices, build WebRTC clients and do mostly everything on the platform yourself.

The one thing that would be very time-consuming would be registering ranges of DID’s. You can register a few manually for testing and we recommend working with us over Email to get large blocks added.

Open Data and APIs

If we are going to change the PSTN game, we can’t set out to be the next carrier. We’ll provide access to the E.164 least-cost routing database through an open access API for other carriers or users who want to build services that are like-minded or work with our service.

API’s for call interactions will be capable on the platform. The including starting SIP sessions and controlling them from the cloud which should allow all types of neat integration. These will be powered by REST calls or Webhooks depending on activity required.


The future of the PSTN and of telecommunications is awesome and its pure cloud. There is just way more bandwidth out there then it takes to make a phone call nowadays. 15 years ago, having all this on your LAN mattered, but I argue it doesn’t anymore.

What this change is doing is breeding incredibly innovative solutions, because supporting the development of cloud solutions is just way more efficient. Support organizations get smaller and dev teams with innovation get bigger. What we’re doing is introducing this to the PSTN, an old archaic industry.

We are still building this out, but as we have, you get a feel that not only is the PSTN outdated, but SIP has much bigger dreams in the cloud, than behind your firewall.

I’d love to get your feedback and would be happy to let you use our cloud to do some least-cost routing or register some devices to do some test calling. We have a Cisco Phone builder for our cloud and Cloverhound has been using the platform for about a month for basic inbound and outbound. All of the above plans are not implemented yet so things are at best, an early alpha. Try at your own risk.

Twitter – @chadstachowicz
Email –
Phone – 980-333-8415


Cisco Spark Hybrid Services – Call Service Connect Deployment


Undoubtedly we’ve all heard about Cisco Spark over the past year. Lumped in between the cloud and the cloud’s cloud, there is a component referred to as Hybrid Services. Hybrid Service is summed up as multiple components designed to bridge the preverbal gap between the Cisco Collaboration Cloud and your On-Prem UC (Unified Communications) infrastructure. For some of us, migrating to the cloud may not be an option for quite some time, if ever. Designed to introduce the customer to Cisco’s Cloud offerings, Hybrid Services aims to highlight the benefit of having a unified experience for all collaboration applications. This article is aimed at the engineer looking to deploy the Call Service Connect feature into their companies infrastructure, all the while helping us see a world that is Jabber-free. For instance, If I receive an incoming call on my 10 digit DID (Office number), Call Service Connect will allow me to receive that same incoming call through Cisco Spark on any of my mobile devices. Pretty cool, right? Likewise, outgoing calls to the PSTN are also routed out of your company’s gateway via SIP Trunk or PRI.


Let’s make a few assumptions. The first being that you have a working CUCM (Cisco Unified Communications Manager) and the second being that you have read our deployment guide for Expressway located here and here, respectively. Strap yourselves in, it’s a two parter. Satisfying those requirements will help immensely with the configuration and troubleshooting in the next few sections.

The below diagram depicts what the Call Connector will look like in your environment.Screenshot 2016-08-15 12.56.21.png

Its important to note that you MUST and I mean MUST be running Expressway 8.7.1 or higher on your Expressway-C. The image below was taken directly from the deployment guide. Certain pieces will work on 8.7, but the guide specifically mentions that in order to take “full advantage” of the feature, you need 8.7.1. In addition, CUCM MUST be chugging along at 10.5(2)SU3. The guide(s) I used from Cisco are here and here.

Screenshot 2016-08-15 13.12.29.png


Let’s start by agreeing CUCM and Expressway meet the version requirements for this to work. k? cool. Next let’s make sure we have DNS working as it should. Below you’ll see our SRV record we use. The Spark application uses this to route calls destined for your CUCM infrastructure to the correct host. Spark does an SRV lookup for the protocol sips using tcp as the transport protocol and sipmtls as the subdomain for this domain. In our case, we weight this record at 1 (lower value is more preferred) and priority at 10 (only relevant if we have more than one SRV record). The port we tell it to use is 5062 (Mutual TLS) and the target is our Expressway-E ( Like B2B or MRA, this uses the same protocol with the exception of us having it use 5062 instead of 5061. If you are using 5061 for MRA today, changing the MTLS port will break connectivity.

➜ ~ nslookup
> set type=SRV

Non-authoritative answer: service = 1 10 5062

Since we just declared that Cisco Spark should use 5062 on all inbound connections to our Expressway-E, we need to tell Expressway-E that. Below are our SIP settings. Ensure you have Mutual TLS mode set to On and its using 5062 as its Mutual TLS port.

Screenshot 2016-08-15 13.52.24.png


Once DNS is verified and the Expressway-E knows that port to use for MTLS, let’s hop over to CCM (Cisco Cloud Collaboration Management). From there, navigate to Services, Hybrid Call; Settings. Scroll down to the bottom and enable Connect. Under SIP Destination, enter in yourdomain will be the external DNS zone you used for your SRV entry above. This step ensures calls destined for your org make it to your Expressway-E. It does this by doing an SRV lookup against the sipmtls service offered by Another item involving DNS you will want to take care of while you’re here is Aware. Most notably, Aware makes Spark “aware” of all calls across your UC system enabling Spark to view recent call history. To verify your domain as a valid domain for your org, click Add Domain.

Screenshot 2016-08-15 13.57.59.pngScreenshot 2016-08-15 14.00.13.png

Enter in the domain you wish to add. After submission, the domain will go into a Pending state. Select Verify. In order for Cisco to verify you own that domain, it forces you to manually add a TXT record to your domain’s external DNS zone file. Simply go to your external DNS manager and create a new TXT record with the string below. This string will be unique to each domain.

Screenshot 2016-08-15 14.10.02.png

To verify, let’s look at our external DNS zone to ensure it created the record. For obvious reasons, we can not verify since we don’t own it. Instead, we will use

➜ ~ nslookup
> set type=TXT

Non-authoritative answer: text = “7744b423ac3a7d45bb83103d9a645168f3e3db5d9e52880f197e6638c7eefa3c”


Once DNS is configured and we’ve verified that inbound Spark calls to our org will route to the correct place, we need to head over to our Expressway-C and configure the CUCM integration. From Application>Hybrid Services>Call Service select New and add the CUCM IP address. Select Verify CredentialsNOTE: This user must have AXL and CTI access permissions. 

Screenshot 2016-08-16 13.00.31.png

Once verified, the status on both CTI and AXL will change to up. If you run into issue with this part, verify application user permissions for the account you used, as well as the AXL Web Service. Ensure it is running.

Screenshot 2016-08-16 13.04.27.png

Once added, navigate to Application>Hybrid Services>Call Connector and toggle the Active radio button to Enabled. This will start the Call Connector.

Screenshot 2016-08-16 13.49.15.png

Now that we’ve enabled the Expressway-C, we need to start work on how we’re going to place and receive calls. As depicted by the diagram, the call originates from the endpoint signaling CUCM where the destination is. As we can see, both outbound and inbound calls traverse the Expressway-C and E through the Unified Communications traversal zone. Outbound calls from CUCM to URIs will look at the SIP Route Pattern. In our lab, we are using * to default route any domain not matching a specific one to the trunk towards the Expressway-C. As this is a lab, we ensure that all domains listed as a destination in a SIP header get routed. The official guide will have you use * as your SIP route pattern. Screenshot 2016-08-16 13.59.50.png

Once the destination is matched to a SIP route pattern, it routes to the Expressway-C.

Screenshot 2016-08-16 14.22.01.png

The Expressway-C then looks at its Search Rules and determines the best match for the destination to route the call. In our case, we again have a default rule to send anything not matching a specific domain towards the Expressway-E. We do this because during the selection process, it queries its local zone for the destination. As the destination * doesn’t match any of the URIs on CUCM, it knows to send it on. Below is our rule we use to match.

Screenshot 2016-08-16 14.07.21.png

In our case, the TraversalZone is the Neighbor Zone to the Expressway-E. As this call enters the Expressway-E, it looks at its search rule to find where to go next. As you see by our outbound search rule towards CCM, we see it is matching any pattern string that contains and routing it out the DNS Zone Cisco Spark Hybrid ServicesScreenshot 2016-08-16 14.34.39.png

The Cisco Spark Hybrid Services DNS zone then makes a determination on where to send the call based on the configuration we have listed below. This configuration is similar to default DNS zone you most likely have on your Expressway-E with the exception of isolating the destination to look for. As this is a MTLS connection, we want to ensure TLS Verify mode is set to On as well as including the TLS Subject Verify Name of This ensures that all routes routed to this domain are encrypted using TLS.


Thats outbound. Let’s work on getting inbound calls. Since we have already completed the requisite steps above when we first started, all we need to do is ensure users have a Spark Remote CTI device in CUCM. Under your Unified CM Server setting on your Expressway-C there is an option for your Call Service Connect Configuration. For our lab, we opted for automatic provisioning. If you have thousands of devices, manual import may be better. Once you’ve done that, you will need to go into CCM and enable Connect for the users you want Call Service Connect enabled for. Toggle the switch to On and restart the Call Connector on the Expressway-C.

Screenshot 2016-08-16 14.52.38.png

Almost there. After Call Connector restarts, you should now see the Onboarded Users change to reflect the number of users you enabled for Call Service Connect.


Screenshot 2016-08-16 14.54.37.png

To verify, check CUCM to see the automatically provisioned device.

Screenshot 2016-08-16 15.01.02.png

From the Spark cloud, we can now work through getting calls inbound to our remote CTI device (Cisco Spark application). Caller A initiates a call to Caller B via their PSTN number (7048675309). Caller B will receive an inbound call to that PSTN number through the Spark application. It does this by matching inbound URI destinations. For example, when the Expressway-E receives a call, its destination will look like this:;user=phone

Our Expressway-E has a Search Rule targeting the Traversal Zone. This is directing all incoming URI destinations towards the Expressway-C. Screenshot 2016-08-16 15.11.20.png

Once our Expressway-C receives the SIP packet from the Expressway-E, it then looks where to route calls with the destination;user=phone. As you can see by the below figure, its matching any destination with the;user=phone suffix. The target destination to route this call is CUCM Neighbor. In this case, that is our CUCM. Screenshot 2016-08-16 15.17.13.png

One of the most time time consuming parts in all of this was the last part. I was able to get calls outbound and inbound but CM traces showed me that once the Expressway-C sent the calls to CUCM, it was stripping everything but 4 digits. If you are a victim of this nonsense, make sure to check the incoming allowed digits on the SIP trunk connecting CUCM to Expressway-C.

Screenshot 2016-08-16 15.19.28.png

We hope this guide can provide benefit in configuring Cisco Spark Hybrid Services for your organization. For any revisions, questions, or comments, feel free to contact myself directly (through Spark obviously) or drop a comment below.

2016-08-16 15.30.05.png


Tropo Log Tailing

Working with Tropo’s scripting API is a quick and easy way to get great call and SMS functionality into your applications. But while building with the scripting API is great, debugging your code can be very frustrating.

Currently, to get a peek into what’s happening on Tropo’s end, you need to download your logs from their application manager on These log files can grow very large (over 100MB) and load very slowly in their in-app editor. It’s also highly difficult to parse through the logs to find information that is relavent to what you are doing at that moment.

Most apps today have great real-time logging, like Ruby on Rails which lets you dig into the details of your app and see it executed in real-time. To bring this kind of experience to Tropo development, I’ve created the tropo_tail gem.

Tropo Tail Gem

To install, from your terminal or command prompt, type:

gem install tropo_tail

Installing this gem will give you access to the


command. Upon running it will ask you for your Tropo username and password. This is to login to Tropo’s FTP server. The gem will then feed the log file as it is generated on Tropo’s servers to your terminal in realtime!

You’ll notice that Tropo’s logs come with a lot of information, sometimes too much. To help with this during development you can use a flag:

tropo_tail --truncate

This will cut off a large portion of Tropo information such as the application ID and session ID, and let you see Tropo’s output and a timestamp.

In addition to helping debug issues with the scripting API, this will work for any Tropo applications including those using the webAPI to help get an inside track into what’s going on behind the scenes and help you develop higher quality apps in no time at all!


How to Click To Call Back With Tropo and Ruby on Rails

In this post, we’re going to build on our previous work on number masking. Let’s say you’ve created a mask for your number and someone called that mask. Now you want to call that person back. How do you do so without revealing your actual number?

Here’s how. Once again, we’ll be focusing on the Tropo back-end side of things.



  1. Create a model for saving call history.
  2. Create a view that shows this history and allows you to click on a number, triggering call_back
  3. Have Tropo call you and add you to a unique conference
  4. Have Tropo call the other person and add them to the same conference


Reminder: number is your actual phone number, while a mask is the phone number that is made publicly available. Calls to the mask get transferred to your actual number, keeping it anonymous.


Create a model for saving call history and a view for triggering the call back

We want to keep track of all calls made to a mask. To achieve this, we create an inbound_calls model that stores the number of the person calling and the time that the person called. An inbound_call belongs to a mask, which allows us to also keep track of the mask that was called and the number associated with that mask. Remember from our previous blog that a mask belongs to a number. 

Here is example code that stores an inbound call before making the transfer.

def transfer

    from = params[:session][:from][:id]
    to = params[:session][:to][:id]
    timestamp = params[:session][:timestamp]

    mask = Mask.find_by mask: Phonelib.parse(to).e164
    number = mask.number.phone_number

    inbound_call = from, mask: mask, time: timestamp)
    if ! 
        puts "Creating inbound call failed: #{inbound_call.errors.to_json}"

    t =  
    t.transfer(:to => number, :from => from)

    render :json => (t.response)


Note that Tropo provides the timestamp of the call in the session timestamp parameter. Here is an example view for triggering the call backs.




Have Tropo call and add people to a conference

def call_back(from, mask, number)
    conference_id = from.to_s + mask.to_s + rand(1000).to_s
    tell_tropo_to_invite_to_conference(conference_id, from, mask)
    tell_tropo_to_invite_to_conference(conference_id, number, mask)
def tell_tropo_to_invite_to_conference(conference_id, to, from) 
    tropo_params = {action: "create", conference_id: conference_id, to: to, from: from, token: token} 
    response = tell_tropo(tropo_params) 
    if response.code === '200' 
        puts "successfully invited #{to}" 
        puts "error: #{response.body}" 

def invite_to_conference 
    from = params[:session][:parameters][:from] 
    to = params[:session][:parameters][:to] 
    conference_id = params[:session][:parameters][:conference_id] 
    puts "Inviting #{to} to conference #{conference_id} with callerid #{from}" 

    t = to, from: from) 
    t.conference({ name: conference_id, id: conference_id}) 

    render json: t.response 

def tell_tropo(tropo_params) 
    uri = URI.parse('')   
    uri.query = URI.encode_www_form( tropo_params ) 
    http =, uri.port) 
    http.use_ssl = (uri.scheme == "https") 
    request = 
    return http.request(request) 

These methods are in the controller. The call_back method starts the whole process. The from is the number of the person we’re calling back. The mask is the mask that the person called. And the number is the number associated with the mask, i.e., your number. We will use the conference_id to invite people to the conference. We create a unique conference_id each time the call_back method is ran, or else every one will be added to the same conference.

The tell_tropo_to_invite_to_conference method tells Tropo to start the Tropo application that we created for inviting people to conferences. The script link we provided in that app points to our invite_to_conference method. The invite_to_conference method calls in a person to the conference_id provided. We pass the conference_id and other parameters to the invite_to_conference method by including the parameters as part of the query. We then access these parameters in the invite_to_conference method via params[:session][:parameters]. Notice that when calling the other person, the callerId is set to the mask, keeping your number anonymous 🙂

The tell_tropo method simply makes a GET request to Tropo with the query parameters that are passed in.

Here are the Tropo docs for making a call, setting up a conference, and passing parameters:


And that’s it! You can now call back people without revealing your phone number.



I’ve put together a collection of Ruby scripts for preparing exported CSV files from CUCM 7.x to import into CUCM 10.x and above. Download them here.


When migrating configurations between CUCM 7.x and CUCM 10.x and above, a typical task involves using the Bulk Administration system to export phones and configurations as CSV files. One of the issues with importing these CSV files directly into CUCM 10.x is that there are many headers in the 7.x CSV file format that aren’t supported in CUCM 10.x and will cause a failed import. These files will help to clean up the exported CSV files as well as provide some basic filtering functionality to limit the import to certain users and phones (as the CSV files can be very large sometimes they can be difficult to work with in Excel). Before importing any files be sure that your new CUCM system has all referenced dependencies configured (device pools, partititions, etc) or the import will fail.


From your 7.x Cisco Unified CM Administration page, navigate to Bulk Administration > Phones > Export Phones > All Details. Select “All Phone Types”, add a name for your export, select “Run Immediately”, and then click “Submit”. Next go to Bulk Administration > Users > Export Users. Click “Find” to pull up all user accounts, and then click Next. Input a file name and select “All User Format” for the file format. Select “Run Immediately” and then click “Submit”. Both of these export jobs can be viewed in Bulk Administration > Job Scheduler and, once completed, can be downloaded from Bulk Administration > Upload/Download Files. After downloading rename the files from .txt to .csv and place them in the CiscoCSVToolkit folder.

Replace the importfile variable in the stripbadcolumns.rb script to match your exported phone CSV file. Next run the script from a command line (ruby stripbadcolumns.rb). It may take a little while to run. This will save a file called “forimport.csv” that you can upload to your 10.x system and run using Bulk Administration > Phones > Insert Phones.

If necessary you can use the filterbydevicepool.rb script on your forimport.csv file to limit which phones you want to import by device pool. You can also use the filteruserbypartition.rb script to filter your exported user CSV file by the primary extension’s partition.


Prime Collaboration 11.x Review – Part 1 – Deployment


The Prime Collaboration Suite from Cisco consists of three components – Deployment, Provisioning, and Assurance. When these products were first released I didn’t hear a lot of good things about them (sorry Cisco), so I avoided them with most of my deployments. That said, it looks like Cisco has made a lot of updates in the last release and I wanted to get an unbiased review of each of these three products and if they are worth using in my upcoming projects. Prime Collaboration Standard is included with CUWL licensing since version 10.x – so if you have CUCM 10.x and higher, you can use these products. You can’t beat free, right?

This will be the first of three blog posts, each one focusing on one of the Prime Collaboration products. I’ll cover some Frequently Asked Questions, an overview of the benefits and drawbacks of using each product, and my experiences using it in the lab and in customer environments.

What is Prime Collaboration Deployment?

Prime Collaboration Deployment (or PCD) is meant to help manage installations, upgrades and migrations on to VMWare ESXi platforms. Cisco’s intention with these products seems to be making it easier for customer IT departments to manage Collaboration implementations once they are up and running, but it also can make some tasks much easier for partner consultants to initially set things up. Some of these things it does really well and can save you a lot of time, and some of these things may only be beneficial in certain situations. I’ll give my overall review and feedback of each function below.

How Do I Install PCD?

All Prime Collaboration images come preinstalled with any BE6k or BE7k installation, which can save some time with initial installs. In fact, Cisco has a new Config To Order Portal (CTOP) that lets you preconfigure a BE6k during the ordering process with IP addresses so it comes ready to go! Check out for more information on this.

If you aren’t using a BE6k or need to install it from scratch the process is very similar to setting up a CUCM or other VM based UC server. Simply deploy the OVA and then mount the bootable ISO image and boot the VM. Sadly the bootable ISO image is not available from CCO, so contact your Cisco account rep if you need to get a copy of the bootable version. Non bootable upgrade images and OVA templates are available here.

One thing to note that I learned the hard way – do not change the IP address of the PCD server after installation. It will seem to work fine and load the admin page, but most tasks will fail without any helpful error messages. If you do have to change the IP, just reinstall the server. I would also recommend disabling LRO on any ESXi blade before running your VM install tasks to reduce failures due to time of installation.

What Licensing Is Required?

To me this is one of the really dumb things about PCD – the normal license that you would get from Cisco for ESXi does not actually support the VMWare features that you need to use PCD. During the initial 60 day evaluation period for ESXi all features are enabled, so you could use PCD during that time, but once you apply the license you would normally get with a BE6k or BE7k type server you can no longer mount the NFS stores from PCD. To me PCD should not only be for initial deployment of images but also for managing the system after that point for patches. If you want to do this be sure to purchase the higher license type. From the documentation:

The following are compatible with Cisco Prime Collaboration Deployment:

  • Cisco UC Virtualization Foundation (appears as “Foundation Edition” in vSphere Client)
  • VMware vSphere Standard Edition, Enterprise Edition, or Enterprise Plus Edition
  • Evaluation mode license

The following are not compatible with Cisco Prime Collaboration Deployment:

  • Cisco UC Virtualization Hypervisor (appears as “Hypervisor Edition” in vSphere Client)
  • VMware vSphere Hypervisor Edition

New Installations – 6/10

PCD can potentially save you some time in the initial deployment of UCM, CUC, and IM&P servers onto ESXi blades. Especially if you have a lot of servers to deploy. That said, I had issues deploying IM&P and couldn’t get an installation to successfully complete (this may have been related to an issue with my ESXi server, but I couldn’t get it to work after multiple attempts). It seems to take a lot longer than doing the installations manually, and on failed attempts it takes a long time to know that things failed, and the information provided isn’t as useful as it could be. I would like to see Cisco add diagnostic dump file information to failed installs automatically to assist in troubleshooting when this happens. Also once an install task starts running it is impossible to cancel it.

The process is pretty straightforward to get new installations running:

  1. Log in to the web interface using “globaladmin” account.
  2. Upload all bootable ISO images to the built in SFTP server in PCD under the /fresh_install folder. Note that you have to use the adminsftp account to connect to SFTP, which uses the same password as the globaladmin account you used on setup. PCD lets you set up external SFTP servers, but it doesn’t seem like you can use these for much of anything, so stick to the built in server for images and other ISOs.
  3. From your vSphere client, deploy the OVA templates for servers you want to install on your ESXi server but don’t start them or mount any ISO images.
  4. Set up all UC server records in DNS ahead of time. This will save you time in failed installs.
  5. Add your ESXi blades in PCD under Inventory > ESXi Hosts. This lets PCD use NFS to mount ISOs and manage the VMs on the server.
  6. Add your UC servers that you want to install under Inventory > Clusters. You can’t group CUC together with UCM and IM&P, so set up one cluster for UCM/IM&P and one for CUC. Be sure to select the “Publisher” task under both your UCM Publisher and also your IM&P primary server (this was a bit unintuitive for me at least). I have no idea why “Primary Voicemail” is an option for the server role in CUCM, so I didn’t check that box.
  7. Set up your install tasks under Tasks > Install. PCD will search the local datastore for the ISO image appropriate to your deployed OVA template. PCD will complete UCM publisher install tasks before running subscriber installs or IM&P, and it seems to add your server references to UCM for you, so you don’t need to do any of that.
  8. Expect to wait a while (6-8 hours potentially) for your install tasks to come back and say they are complete. As I mentioned, this is a bit slower than doing things manually, but the installations are completely unattended so you don’t have to sit there and enter any information or watch reboots. Which is nice.

Upgrades – 7/10

Upgrade tasks are pretty easy, whether it’s installing a patch or adding a locale file. Simply add the files to the /upgrade folder using SFTP and add a new upgrade task under Task > Upgrade. I can’t speak for doing major version upgrades using this feature, but doing minor release patches was very easy. I also like the capability of scheduling upgrades for later (such as during your maintenance window), and the option to reboot back into the same version you were running before. This would allow you to complete your upgrade but wait until a later maintenance window to actually make the upgrade live.

Migrations – 8/10

This is really where PCD might let you do things that there is just no clean way to do otherwise. I have recently had a few projects where I had to move a customer from UCM 7.x to 10.5 and had to do a lot of painful editing of CSV files to export/import configurations – and still had to do a lot of manual configuration on top of that because Import/Export just wouldn’t work. I now wish I had used PCD migration for these. That said, this function is only available during a fresh install – you can’t migrate configurations onto an already installed cluster. Also note that you can only do migration tasks for the last 3 versions of UCM, so if you installed PCD 11 and wanted to migrate from UC 7 this would not be possible (but would be if you were using PCD 10).

You can also use this task to migrate UCM running on non VM servers onto ESXi for the same version, and then upgrade to new versions on the ESXi servers. Or you can readdress servers, which is a common step during these sorts of projects.

I haven’t used the migration tasks for production customers yet, so when I do I will come back and update my review, but based on what I’ve seen so far I would definitely recommend using PCD for these sorts of projects, and will be doing so myself in the future.



Connect to console using Terminal on OSX

For longer than I  can remember, I’ve used SecureCRT for all of my console needs. By far, the easiest and most intuitive application for ssh/telnet/console. With that said, we’ve all at one time or another been in a situation where we had to make due with what we had. Recently, I did an upgrade of OSX rendering my SecureCRT unable to open. After countless reboots, it came back to life. This got me thinking…..What would I do without SecureCRT? I’ll tell you. Use my Mac in all its glory to achieve the same goal. This is where I am today. Connecting to the console using terminal.

  • Open ‘’ on your Mac running OSX . Yours should look similar to this.

Screenshot 2016-01-20 14.00.57.png

  • Change your working directory to /dev by entering the command below. You should see your working directory change.

Screenshot 2016-01-20 14.03.04.png

  • Next, we’re going to make sure our USB to DB9 adapter is plugged in by issuing the command below. This command tells to return any lines that match usb. As you can see, I have two devices available. Most commonly, yours will be cu.usbserial.

Screenshot 2016-01-20 14.08.23.png

  • Now that we’ve verified we can see the adapter, time to connect. Issue the screen command followed by the full path of the device, plus the baud rate. In most cases, 9600 baud rate will work fine, especially if it is a newer Cisco device. This number is issued as a command line argument after specifying the full path of the device. See example below.

Screenshot 2016-01-20 14.13.17.png

  • Press Return/Enter to connect.
  • As you can see, the tab has now changed to screen. This is because we are now in the application window. NOTE: Control+C will not work here. To exit the screen application, issue CTRL+A then CTRL+\ You will be prompted “Are you sure?.” Of course you are. type and then enter. This will drop you back into working directory you were in before.

Screenshot 2016-01-20 14.15.34.png


We hope this helps a few of you out there who, like me, struggled with finding an alternative to ol’ trusty SecureCRT. Let us know if this has saved you once or twice…or if this is your daily routing by dropping a comment below!


What do we want? Video! When do we want it? NOW!

In this post, we will be covering the deployment and configuration of Cisco’s Telepresence video-conferencing solution. After reading this you’ll be able to deploy Cisco’s Telepresence solution.

Cisco has plenty of deployment guides (and assorted other documentation) for this product, but I haven’t found a concise and clear guide to just getting it working -so I figured I’d write one up.

For those of you unfamiliar, Cisco’s Telepresence solution is the de facto standard in most corporate offices worldwide. Telepresence isn’t so much one device as it is a suite of them. Wikipedia defines “Telepresence” as a range of products developed by Cisco Systems designed to link two physically separated rooms so they resemble a single conference room regardless of location. While most of that is true, it can do so much more. From integration into Jabber to multi-conference room meetings, it really is the king of enterprise video.

In the next section and throughout the article, we will be demonstrating the exact steps we took to get our current lab Telepresence up and running. While its assumed that your setup may differ slightly, the same principles are applied. As always if you run into issues or have questions, feel free to drop a comment below.

Lets dive in!

The Ingredients

Listed below is what we used to get things going. The versions don’t matter so much as long as they are all compatible with one another. Compatibility guide is available HERE.

  • VMWare ESXi 5.5
  • Telepresence Conductor
  • Telepresence Server (vTS)
  • CUCM 10.5
  • SX-20
  • Jabber Client for Mac
  • Jabber Client for Windows

Once you’ve successfully obtained all the OVFs, its time to deploy. The order in which they are deployed makes no difference. Note: You will need entitlement to download the OVFs.

Conductor- Download Link

vTS- Download Link

Jabber for Mac-Download Link

Jabber for Windows-Download Link


We’re ready to deploy VMs. Log into vCenter and select File>Deploy OVF Template. Select your OVA file that corresponds to the items above and do the obligatory next, next, finish. Ensure you select Thick Provisioned, as Thin is not supported.

Telepresence Conductor

  1. Upon first boot, you will be prompted for username/password. Username is admin, password is TANDBERG. Once in, you will roll through the initial setup. This part is fairly straight forward and will require you to assign it an IP. Note: before its all said and done, conductor will have 3 IPs all in the same subnet. For now, we will just need to assign one. If you are using a voice VLAN, you will want to assign Conductor an IP in that subnet.
  2. After an IP has been assigned, navigate to the GUI https://<IP&gt; and login using admin and the password you changed it to during setup. If you are deploying this to anything other than lab or POC testing, make sure to change the password.

Telepresence Server (vTS)

  1. Upon first boot, you are dropped into a generic shell that has TS:>. Without reading the config guide, it’s almost impossible to know what to do next. Once you are at this stage, we need to assign an IP. Below is the syntax you will use to do so. This line assigns the address to the TelePresence Server, with subnet mask and default gateway Obviously your environment may differ so change the IPs accordingly.


2. Reboot the vTS server for the changes to take effect. After the vTS                 server comes back up, navigate to the GUI https://<IP> and hang                     tight. We will come back to this soon.


At this point, you should have a vTS server and a Conductor online and accessible from the PC you are working from.  Below I will provide steps with descriptions on why we are doing them.

  • Navigate to the IP of your  vTS server. Go to Users>Add New UserScreenshot 2016-01-04 09.36.03.pngCreate a username, name, and assign a password. Make sure to give the user Administrator rights.

This user will be used to authenticate from the conductor to the vTS server and to select available resources.

  1. First order of business is to create a service template. For this demo, we have created one, but feel free to create as many as you want. These are simply used to allocate resources (Conference Bridge Pools).Screenshot 2016-01-04 13.50.19.png
  2. Once added, you should see the image below indicated communication between the conductor and vTS is successfulScreenshot 2016-01-04 10.11.29.png
  3. The IP or FQDN (if you prefer DNS) will be the IP of your vTS server. The username/password will be the one you just created with administrator right. For this, I’ve selected HTTPS as my protocol but you can use HTTP if you’re just wanting to test it out. Select SaveScreenshot 2016-01-04 10.08.56.png
  4. Give it a name and select Create Conference Bridge
  5. Navigate to the IP of your Conductor. Go to Conference Configuration>Conference Bridge Pools>New. Create new bridgeScreenshot 2016-01-04 09.43.21.png
  6. Let’s create some conference templates. These templates will be used in the Location setting to define the setting used when creating a conference either Ad-Hoc or Rendezvous. If you are doing both (which we are in this guide) we will need two separate templates. Select New. Below is our configuration.Screenshot 2016-01-04 13.52.17.pngScreenshot 2016-01-04 13.52.51.png
  7. Once the templates are created, we need to create some locations. On Conductor, go to Conference Configurations>Locations. Under Related Tasks add two additional IP address. One will be used for Rendezvous Conferencing, the other Ad-Hoc. These IPs should be in the same subnet as Conductor. Select New. The configuration below is essentially where we are creating a SIP trunk to CUCM. In the interest of simplicity, we are creating one trunk for both Ad-Hoc and Rendezvous. We will create the other end of the trunk later. As the name implies, select the Ad-Hoc template for Ad-Hoc conference. Select the IP addresses that you just created. One will be used for Ad-Hoc, the other for Rendezvous. Under Trunk 1, type the IP of the CUCM server. Since we are using TCP for the protocol, the port number does not matter. SaveScreenshot 2016-01-04 13.56.11.png
  8. One of the other items I missed when setting this up initially was Conference Aliases. These are used to setup Rendezvous Conferences by simply dialing a pattern and appending the conference number. Let’s say the incoming alias we create is (850….)@.* this would mean that anyone who dials 8501234 would create a conference at that number. It allows users who want to plan a meeting at a certain time to give that number out to the participants and have them dial in. Hence, Rendezvous. Screenshot 2016-01-04 14.08.59.png
  9. That just about does it for Conductor. Next item up to bat is the CUCM configuration. Since this post assumes you have a working CUCM, we will start by configuring two additional SIP trunks. The first will be our Ad-Hoc. Next will be the Rendezvous. Overall, setup of these trunks is fairly straight forward with the exception of the screenshot below. For additional help configuration trunks, check out this guide.Screenshot 2016-01-04 14.28.20.png
  10. After the SIP trunks have been created, we need to create a Route Pattern to route calls destined for 850XXXX out the proper trunk, i.e. the Rendezvous SIP trunk. In CUCM, select Call Routing>Route/Hunt>Route Pattern. The screenshot below tells us that any devices in PT-CH-Internal that dial 850XXXX will get routed out the Rendezvous_Meeting SIP trunk, which of course, is one of the IPs on Conductor. From there, Conductor will take that as “Oh hey, this device wants me to create a conference!”. Remember our Conference Alias we created? This is where it gets used. Screenshot 2016-01-04 14.35.18.png
  11. Last but not least, we need to create a Conference Bridge and add the bridge to an MRG that the endpoints are using. Under Media Resources>Conference Bridges select Add New. The SIP trunk will be the Ad-Hoc trunk you created in the step above. The username will be an administrator user. For our setup I created a user on Conductor called “conductor” and assigned it admin privileges. Screenshot 2016-01-04 14.43.59.pngScreenshot 2016-01-04 14.41.04.png
  12. Under Media Resources>Media Resource Groups, select either a new or existing MRG. Typically, creating a new MRG, adding the MRG to an MRGL and then assigning the MRG to the device is the way to go. Under Available Media Resources, select the new created Conference Bridge and click the ^ arrow to push it to Selected Media Resources. We called ours Conductor_AdHoc but obviously yours will differ.


  • As I mentioned above, we will be using an SX-20, Jabber for Mac, and Jabber for Windows applications to test conferencing both Ad-Hoc and Rendezvous. Since writing about a verifying video is boring, we would rather just show you! In our test, the SX-20 being used in the Conference room has already dialed into the 8501234 Conference. We are simply just joining in.


Special Thanks

  • Jason Murray- CCIE Collaboration at Cisco

Deploying Conductor and Telepresence




How to Mask Your Phone Number With Tropo and Ruby On Rails

In this post, we’ll show you how to create a Ruby On Rails web application that dynamically generates masks for phone numbers. The source code for this project can be found here. When some one calls the mask, the call will get transferred to the actual number. This way, users can keep their actual phone numbers anonymous, for example, when conducting business online.

We will focus on the Tropo back-end side of things.


  1. Create a Ruby on Rails App and expose it to the internet via ngrok for local testing
  2. Create a Tropo Account if you have not already done so
  3. Create a Tropo Application specifically for this feature, and provide your ngrok url
  4. Provision a Tropo mask (phone number) with the same area code as the number you are masking
  5. Use the Tropo Ruby Web API to transfer calls made to the mask to the actual number


Create a Rails App and expose it via ngrok:

Ngrok is an application that allows you to expose a local server behind a NAT or firewall to the internet. Using ngrok, you can run your Rails app on your local machine (via the command “rails server”) and have the application be exposed to the internet.
One you have ngrok running, your local server will be exposed on a public URL such as:
This is the url we will provide to Tropo when creating a new Tropo app.

Here is the ngrok website:

Every time some one masks a number through our app, we generate and store the mask (and number, if it’s not already stored) in the database. We’ll model this with two tables, a ‘mask’ table storing the generated masks and a ‘number’ table storing the number to which our masks will redirect. Here are the rails commands we used to create our models:

rails g model number number:string
rails g model mask mask:string number:references

Basically, each number and mask is a phone number, and each mask is associated to a number.

Create a Tropo Account and Application:

If you haven’t done so already, sign up for a new Tropo account and create a new application.

Here are the Tropo Docs that explain this process in detail:

When asked to provide a script URL, select the Web API option. Feel free to provide a fake URL if your application is not yet set up. You can always change this later. Once you have it set up, make sure to provide the publicly accessible URL to your app (more on this in the Ruby Web API section). There’s no need to add a number at this stage but feel free to do so.


Provision a mask

Below is an example of  how to dynamically provision masks from your Rails application.
Here are the docs:

# assumes number is prefixed with "+1"
def self.generate_mask_for_number(number)

    uri = URI.parse("{@@mask_app_id}/addresses")
    http =, uri.port)
    http.use_ssl = (uri.scheme == "https")

    request =
    request.basic_auth(@@user, @@pass)
    request.set_form_data({'type' => 'number', 'prefix' => number[1...5]})

    response = http.request(request)
    if response.code === '200'
        response_uri = JSON.parse(response.body)['href'];
        return extract_number_from_uri(response_uri)
        puts 'generating mask with prefix ' + number[1...5] + ' failed with http ' + response.code + ' and message: ' + response.body
        return generate_random_mask_for_number(number)


# assumes number is prefixed with "+1"
def self.extract_number_from_uri(uri)
    index_of_plus = uri.index('+')
    return uri[index_of_plus..-1]


I’ve used the Net:HTTP library built into Ruby, but you’re welcome to use other libraries, such as HTTParty.

This method takes in a person’s phone number and makes a POST request to{@@mask_app_id}/addresses, where mask_app_id is the id of your Tropo application (not to be confused with app token). This id can be found in the url when visiting your Tropo application.



Your Tropo username and password are used for basic authentication. The form data specifies the type as ‘number’, which is required. The prefix is optional, and specifies the prefix of the provisioned number, with ‘+’ omitted. In the example, we are provisioning a mask with the same areacode as the number passed in to the method. The generate_random_mask_for_number method does the same thing, but sets the prefix to “1”, which causes Tropo to generate a random U.S. number.

Note that the number being passed in is assumed to be in international format. To help with phone number format issues, we recommend using a library such as Phonelib:

If you’re provisioning masks dynamically, it’s important to keep track of the numbers and their masks, so that you can properly transfer calls. One way to do this is to to maintain a table of masks, and a table of numbers, where each mask belongs to a number.

Once a number is provisioned, you will see it listed in your Tropo application webpage.


Tropo Ruby Web API

When some one calls the mask (i.e., the Tropo provisioned number), Tropo will make a POST request to the voice URL you provided, and it expects a JSON response. Below is an example of using the Ruby Web API library to return a JSON string. This string tells Tropo to forward the call to the number associated with the mask. Make sure the URL you provided in your Tropo App leads to this method (e.g., is the url you provided and that gets routed to the transfer method in your config/routes.rb like so:   post ‘/transfer’, to: ‘transfers#transfer’ ).

def transfer

    from = params[:session][:from][:id]
    to = params[:session][:to][:id]

    mask = Mask.find_by mask: Phonelib.parse(to).e164
    number = mask.number.number

    t =
    t.transfer(:to => number, :from => from)

    render :json => (t.response)

The from is the number of the person calling. The to is the mask. The number is the number associated with the mask, which we get from the database. Here are the Tropo docs for transferring a call:


And we’re done! From now on, any calls to the mask will be forwarded to the actual number.
Check out our next blog post on adding a callback feature, coming soon.