Cisco AXL API with Ruby

In this post I’m going to talk about Cisco’s AXL API and how to do basic CUCM administration tasks using Ruby as a scripting language. I’ll be using the example of bulk adding route patterns with a CSV file, but you can take the provided example code and customize it for your own needs. I can hear you already…

“But I can do all of this with BAT Import/Export. Why would I want to write a script?”

First of all, because it’s kind of cool. But seriously – it is more flexible and allows for interactivity and integration with other systems. After you’ve wrap your head around it you’ll have a better understanding of SOAP and REST APIs, allowing you to interact with other web services that use these standards.

I will be using Ruby since it provides good libraries for SOAP interactions and CSV importing, but mostly because I think it can be a bit easier to understand as compared to other scripting languages out there.

Ruby Installation

There are a number of ways to install Ruby depending on your operating system, so I won’t go over each of them in this post. Go here for specific instructions on your platform. I run OS X and used Homebrew to install and update Ruby. To install Homebrew, type the following into Terminal:

ruby -e "$(curl -fsSL"

With Homebrew installing Ruby is as simple as typing this:

brew install ruby

Savon and CSV Libraries

After Ruby you will need to install the Savon and CSV gems. Gem is Ruby’s package manager and allows for easy distribution and installation of Ruby programs and libraries. From a terminal window or command prompt install these by typing the following:

sudo gem install savon
sudo gem install csv

Example Code

All of the example code mentioned in this post (including an example CSV file) is available on our Github site. Either download from the site directly or clone the repository from a command line:

git clone

Running Example Code

To run the code, simply open the addroutepattern.rb script and edit the settings at the top of the file with your own CUCM version, credentials, IP address, and CSV file path/name:

version = "10.5"
username = "admin"
password = "password"
ip = ""
path = 'test.csv'

Next edit the example CSV file with the route patterns that you want to add to your CUCM. Save both files and run the following from the command line in the example code folder:

ruby addroutepattern.rb

That’s it! You may get errors if the route patterns already exist or if the partitions or route lists in the CSV don’t exist. Otherwise check CUCM to ensure that route patterns were added correctly.

How It Works

First is the the setup portion of the script that includes Savon and CSV libraries and provides settings for CUCM:

require 'savon'
require 'csv'

version = "10.5"
username = "admin"
password = "password"
ip = ""
path = 'test.csv'

The first actual code section is a new Savon client being initialized:

client = Savon.client(
wsdl: "lib/axl/#{version}/AXLAPI.wsdl",
namespace: "{version}",
endpoint: "https://#{ip}:8443/axl/",
basic_auth: [username, password],
headers: {'Content-Type' => 'text/xml; charset=utf-8'},
ssl_verify_mode: :none)

This creates the framework and SOAP namespace for the script to use to format the XML request and response that will be made to CUCM. Each version of CUCM has a different WSDL file (contained in the lib folder in the example code). This file lists the different messages and parameters that are allowed for that version of CUCM for Savon to use. The client variable will be referenced later with the call function in order to make the SOAP request.

Next we load the CSV file and for each row we take each value and assign it to a variable to use in our request parameters:

CSV.foreach(path, headers:true) do |row|

 params = { routePattern: { 
 pattern: row['pattern'],
 usage: 'Translation',
 description: row['description'],
 routePartitionName: row['partition'],
 patternUrgency: row['urgent'],
 blockEnable: row['block_enable'],
 useCallingPartyPhoneMask: row['external_mask'],
 calledPartyTransformationMask: row['called_transform_mask'],
 callingPartyTransformationMask: row['calling_transform_mask'],
 digitDiscardInstructionName: row['discard'],
 prefixDigitsOut: row['called_prefix_digits'],
 destination: { routeListName: row['routelist'] }}}

This (and the next section of code) run in a loop for as many rows are in the CSV file. Ensure that the CSV file keeps the first line as the headers for the file, otherwise it won’t load correctly (since headers:true is set in the script).

Finally we send the SOAP request to CUCM using the function and the parameters we set above:

response = do
message params

For this example we use the add_route_pattern message, which is one of the defined messages available from the AXL WDSL schema. If you wanted to perform another action you would replace this with one of the other available messages in the WDSL (such as get_phone) and replace the parameter variables and CSV headers with those required for the message you are using.

Other Available Actions and Parameters

To take this example code and modify for your own purposes you’ll probably want to have a list of available actions and parameters for your specific version of CUCM. This link provides a list of available APIs and operations for each CUCM version. The data dictionaries provided by Cisco here contain the available fields and data types for each API. Simply replace add_route_pattern with the operation you want to use and modify the CSV headers and param code to match the fields/parameters for that operation.

Troubleshooting AXL Connectivity

The AXL web service is enabled by default on Cisco CallManager servers and does not have to be installed or configured. If you are having trouble connecting to the AXL service on CUCM see the steps provided in Cisco’s AXL Troubleshooting Guide.