Introducing the Address API – International calling for your applications at your fingertips.

December 03, 2014
Written by

international-signpost

Your business is growing by leaps and bounds. As you’ve expanded your service internationally you’ve been careful to think about the experience that you provide customers in different parts of the world. Providing a top tier experience means localising your website into different languages, accepting local currencies as payment and offering local support phone numbers to customers.  Now you’re getting ready to expand again, this time to Mexico.

Running down your expansion checklist you’ve got your website localised in Spanish and you’re ready to accept Pesos. All you need now is a local phone number to let your Mexican customers contact your support team.

Since your call center is built on Twilio, expanding to other countries like the UK was a breeze, but Mexico is a bit different. Like a number of countries around the world, Mexican regulations require you to provide a foreign (outside of Mexico) address to Twilio in order to purchase a local Mexican phone number.

(Learn more about Address Requirements here)

Thankfully Twilio now makes this simple via our Addresses API. This new API allows customers like yourself to quickly satisfy the address requirements required by numerous countries.

In this post we’ll see how to build a simple address and phone number management portal using ASP.NET MVC.  Along the way we’ll learn how to use the Addresses and Incoming Phone Numbers API’s to purchase Twilio phone numbers, including from countries with Address restrictions.

Of course if you just want to download and deploy the entire application without having to type all the code, feel free to head to the GitHub Repo where the entire application shown below is available.

Building a full address and phone number management system directly into your own application has a lot of advantages but does take some time.  If you want to get started fast you can head over to your Twilio dashboard and use it to manage addresses and buy phone numbers.

Screen Shot 2014-11-26 at 2.17.02 PM.png

What you will need

Before we get started, lets make sure you’ve got all of the tools you’ll need to use the Addresses API:

  • A Twilio account – you can sign up for free!
  • A physical address – everybody has an address right?
  • Your choice of programming language and framework – I will be using C# with ASP.NET MVC but you can use whichever language you like.

Managing Addresses

Each address you provide to Twilio can be used to satisfy a specific country’s address requirements.  Depending on the country, a phone number might have one of three address requirements:

  • Any: Your account must have an address, but it can be anywhere in the world.
  • Foreign: Your account must have an address outside the phone number’s country.
  • Local: Your account must have an address within the phone number’s country.

As long as you’ve provided Twilio with at least one address which satisfies a country’s address requirements you will be able to purchase local numbers for that country.

We’ll start our address management app by creating an empty ASP.NET MVC 5 app. Once the project is created we’ll install the Twilio .NET Helper Library via Nuget.

We can then add our Twilio credentials to the Web.config file so we don’t need to copy and paste them every time. These can be found on Twilio’s dashboard and will be entered under as follows:

<add key="TwilioAccountSid" value="[YOUR_TWILIO_ACCOUNT_SID]"/>
<add key="TwilioAuthToken" value="[YOUR_TWILIO_AUTH_TOKEN]"/>

Next, create a new controller called HomeController under the Controllers folder and add the code that will give us access to Twilio’s API and then get a list of Addresses from Twilio and pass that list to the view for it to render. This list will start off empty if you still haven’t got any addresses. We will soon be creating functionality that enables us to add new addresses to an account.

using System.Configuration;
using Twilio;

Our action will then be as follows:

public ActionResult Index()
{
    var accountSid = ConfigurationManager.AppSettings["TwilioAccountSid"];
    var authToken = ConfigurationManager.AppSettings["TwilioAuthToken"];
    var twilio = new TwilioRestClient(accountSid, authToken);

    var addresses = twilio.ListAddresses();

    if (addresses.RestException != null)
    {
        return new HttpStatusCodeResult(500, addresses.RestException.Message);
    }

    ViewBag.Addresses = addresses.Addresses;

    return View();
}

In the controller we’ve used the helper libraries ListAddresses method to get a list of our addresses which is then passed to the view using the ViewBag.

Having the controller created we now add a View under the Views/Home folder called index.cshtml.  We’ll use this view to list any addresses we’ve registered with  Twilio. The application uses ASP.NET’s Razor syntax to loop over a list of addresses and add each to an HTML table:

<a class="btn pull-right" href="/Home/AddAddress">Add new address</a>
<table class="table table-striped">
    <thead>
        <tr>
            <th>Customer Name</th>
            <th>Country ISO</th>
            <th>Address</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in ViewBag.Addresses)
        {
            <tr>
                <td>
                    @Html.ActionLink((String)@item.CustomerName, "Details", "Home", new { Sid = item.Sid }, null)
                </td>
                <td>@item.IsoCountry</td>
                <td>
                    @item.FriendlyName <br />
                    @item.Street<br />
                    @item.City, @item.Region @item.PostalCode
                </td>
            </tr>
        }
    </tbody>
</table>

We’ll  run the project now.  If you’ve already told Twilio about an address, you’ll see it displayed on the web page.

What we need now is a way to add addresses to the list from our website.  Let’s build a form that lets a user enter an address and tell Twilio about it.

To start, back in HomeController let’s add another action method named AddAddress.

public ActionResult AddAddress()
{
    return View();
}

We’ll use that to display a new view called AddAddress.cshtml that contains a form which lets users enter an address. Let’s create that view.

<form action="/Home/Create" class="form-horizontal" method="post">
    <div class="control-group">
        <label class="control-label" for="friendlyName">
            Friendly Name
        </label>
        <div class="controls">
            <input type="text" id="friendlyName" name="FriendlyName" placeholder="name for the address" />
        </div>
    </div>
    <div class="control-group">
        <label class="control-label" for="customerName">
            Customer Name
        </label><div class="controls"><input type="text" id="CustomerName" name="customerName" placeholder="name for business or customer" /></div>
    </div>
    <div class="control-group">
        <label class="control-label" for="street">
            Address
        </label><div class="controls"><input type="text" id="Street" name="street" placeholder="street address, PO box, suite, unit, etc..." /></div>
    </div><div class="control-group">
        <label class="control-label" for="city">
            City
        </label><div class="controls"><input type="text" id="City" name="City" /></div>
    </div><div class="control-group">
        <label class="control-label" for="region">
            State/Province/Region
        </label><div class="controls"><input type="text" id="Region" name="Region" /></div>
    </div><div class="control-group">
        <label class="control-label" for="postalCode">
            Postal Code
        </label><div class="controls"><input type="text" id="PostalCode" name="PostalCode" /></div>
    </div><div class="control-group">
        <label class="control-label" for="country">
            Country
        </label><div class="controls">
            <select name="IsoCountry">
                <option value="MX">Mexico</option>
                <option value="GB">United Kingdom</option>
            </select>
        </div>
    </div>
    <div class="controls"><button class="btn btn-primary" type="submit">Save</button> <a class="btn" href="/">Cancel</a></div>
</form>

Not much happening here in this HTML form.  We’ve set it to POST the form data to a new action method named Create. Let’s add that method back in the HomeController.

public ActionResult Create(string FriendlyName, string CustomerName, string Street, string City, string Region, string PostalCode, string IsoCountry)
{
	var accountSid = ConfigurationManager.AppSettings["TwilioAccountSid"];
	var authToken = ConfigurationManager.AppSettings["TwilioAuthToken"];
	var twilio = new TwilioRestClient(accountSid, authToken);
	var address = twilio.AddAddress(FriendlyName, CustomerName, Street, City, Region, PostalCode, IsoCountry);
	if (address.RestException != null)
	{
    	return new HttpStatusCodeResult(500, address.RestException.Message);
	}

	ViewBag.address = address;
	return RedirectToAction("Index", "Home");
}

The Create method includes a bunch of method parameters.  When the user submits the form from the AddAddress view, we’ll use ASP.NET MVC’s model binding capability to take those form values and populate the method parameters with them.

Within the method we are doing two things.  First we use the Twilio’s helper library method AddAddress to tell Twilio about the new address.  Then we’re sending our user back to the list of addresses.

Let’s create our details page now that way our website users can also view and edit a new address in case they want to update anything.

We need a new method in our HomeController that will handle this request. This will bring back all the information about a single address based on its unique identifier.

public ActionResult Details(string Sid)
{
    var accountSid = ConfigurationManager.AppSettings["TwilioAccountSid"];
    var authToken = ConfigurationManager.AppSettings["TwilioAuthToken"];
    var twilio = new TwilioRestClient(accountSid, authToken);

    var address = twilio.GetAddress(Sid);

    if (address.RestException != null)
    {
        return new HttpStatusCodeResult(500, address.RestException.Message);
    }       
    ViewBag.address = address;

    return View();
}

Now all we need to do is create a view called Details.cshtml which will show information about each of the addresses.

@{
    var address = ViewBag.Address;
}
<form action="/Home/Update" class="form-horizontal" method="post">
    <input type="hidden" name="Sid" id="Sid" value="@address.Sid">
    <div class="control-group">
        <label class="control-label" for="friendlyName">
            Friendly Name
        </label>
        <div class="controls">
            <input type="text" id="friendlyName" name="FriendlyName" placeholder="name for the address" class="span4" value="@address.FriendlyName " />
        </div>
    </div>
    <div class="control-group">
        <label class="control-label" for="customerName">
            Customer Name
        </label><div class="controls"><input type="text" id="CustomerName" name="customerName" placeholder="name for business or customer" class="span4" value="@address.CustomerName" required="true" /></div>
    </div>
    <div class="control-group">
        <label class="control-label" for="street">
            Address
        </label><div class="controls"><input type="text" id="Street" name="street" placeholder="street address, PO box, suite, unit, etc..." class="span4" value="@address.Street" required="true" /></div>
    </div><div class="control-group">
        <label class="control-label" for="city">
            City
        </label><div class="controls"><input type="text" id="City" name="City" class="span4" value="@address.City" required="true" /></div>
    </div><div class="control-group">
        <label class="control-label" for="region">
            State/Province/Region
        </label><div class="controls"><input type="text" id="Region" name="Region" class="span3" value="@address.Region" required="true" /></div>
    </div><div class="control-group">
        <label class="control-label" for="postalCode">
            Postal Code
        </label><div class="controls"><input type="text" id="PostalCode" name="PostalCode" class="span2" value="@address.PostalCode" required="true" /></div>
    </div><div class="control-group" />
    <label class="control-label" for="country">Country</label>
    <div class="controls">
        <span name="country">@address.IsoCountry</span>
    </div>
    <div class="controls"><button class="btn btn-primary" type="submit">Save</button> <a class="btn" href="/">Cancel</a></div>
</form>

Familiar? That’s because this page extremely similar to our create page, except that it’s used to update an existing address and will be rendered with existing pre-filled data. The action for updating the address loaded will be as follows:

public ActionResult Update(string Sid, string FriendlyName, string CustomerName, string Street, string City, string Region, string PostalCode)
        {
            var accountSid = ConfigurationManager.AppSettings["TwilioAccountSid"];
            var authToken = ConfigurationManager.AppSettings["TwilioAuthToken"];
            var twilio = new TwilioRestClient(accountSid, authToken);

            var options = new AddressOptions { FriendlyName = FriendlyName, CustomerName = CustomerName,Street = Street, City = City, Region = Region, PostalCode = PostalCode};
            var address = twilio.UpdateAddress(Sid, options);

            if (address.RestException != null)
            {
                return new HttpStatusCodeResult(500, address.RestException.Message);
            }

            ViewBag.address = address;
            return View(viewName: "~/Views/Home/Details.cshtml");
        }

Notice you can update everything apart from the country using the above method, this can be very handy for when a company expands and moves to a bigger office within the same country.

Run the web application again. You should be able to add new addresses to your list.  Each time you add an address you are potentially satisfying a country’s address requirements, thus allowing you to buy local phone numbers for that country. For example, adding an address with the country code MX would satisfy the address requirements of Mexico.  Next we’ll look at changes in the Twilio API that allow you to buy numbers in address restricted countries.

Numbers and Addresses

We now have a system that lets us tell Twilio about addresses so we can start buying phone numbers in countries that require them

But how will we know if the country we are trying to buy a number in has an address requirement?  If it does what kind of requirement it is?  Easy! The Available Phone Numbers API returns a new parameter named AddressRequirements which tells us what, if any, address restrictions each available phone number has on it.

Let’s create a way for users of our website to search for available phone numbers in the countries that we have addresses for.

We will create a couple of tabs on our pages so our website users can navigate between numbers and addresses. We will do this by opening the file Shared/_Layout and adding the following code immediately under the opening body tag:

<ul class="nav nav-tabs">
        <li role="presentation" class="@(ViewContext.RouteData.Values["controller"] == "Home" ? "active" : "")">
            <a href="/">Addresses</a>
        </li>
        <li role="presentation" class="@(ViewContext.RouteData.Values["controller"] == "Numbers" ? "active" : "")">
            <a href="/Numbers">Numbers</a>
        </li>
</ul>

We can now create a new controller named NumbersController. Make sure we are importing Twilio’s helper library into it.

using System.Configuration;
using Twilio;

Create the index action for the controller with the following code:

public ActionResult Index(String IsoCountry)
{
    var accountSid = ConfigurationManager.AppSettings["TwilioAccountSid"];
    var authToken = ConfigurationManager.AppSettings["TwilioAuthToken"];
    var twilio = new TwilioRestClient(accountSid, authToken);

    var addresses = twilio.ListAddresses();

    if (addresses.RestException != null)
    {
        return new HttpStatusCodeResult(500, addresses.RestException.Message);
    }

    // Return ISO codes only once
    var availableCountries = addresses.Addresses.Select(m => m.IsoCountry).Distinct();

    if (IsoCountry != null)
    {
        var options = new AvailablePhoneNumberListRequest { VoiceEnabled = true };
        var numbers = twilio.ListAvailableLocalPhoneNumbers(IsoCountry, options);

        if (numbers.RestException != null)
        {
            return new HttpStatusCodeResult(500, numbers.RestException.Message);
        }

        ViewBag.numbers = numbers.AvailablePhoneNumbers;
    }

    ViewBag.countries = availableCountries;

    return View();
}

In the Index method we use the ListAddresses method of the Twilio .NET helper library to get the list of addresses we’ve told Twilio about and then use a LINQ query to select the unique set of country codes from our list of addresses.

Next, using the ListAvailableLocalPhoneNumbers method search for a list of available voice-enabled phone numbers. We’re passing the country code selected by the website user.

Finally we place both the list of country codes and the list of available phone numbers into the ViewBag so we can use it in our search view.

With the controller created, let’s create the corresponding view that displays the list of available phone numbers and allows the user to change the country for which we want to find numbers.

@if (Request["number"] != null)
{
    <div class="alert alert-success" role="alert">Yey! The number @Request["number"] is yours now!</div>
}
<form action="/Numbers" class="form-horizontal" method="post">
    <div class="control-group">
        <label class="control-label" for="IsoCountry">
            Available Countries 
        </label>
        <select name="IsoCountry">
            @foreach (var country in ViewBag.countries)
            {
                <option value="@country">@country</option>
            }
        </select>
        <button class="btn btn-primary" type="submit">Search</button>
    </div>

</form>

<table class="table table-striped">
    <thead>
        <tr>
            <th>Number</th>
            <th>Location</th>
            <th>Type</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @if (ViewBag.numbers != null)
        {
            foreach (var number in ViewBag.numbers)
            {
                <tr>
                    <td>@number.PhoneNumber</td>
                    <td>@number.Region</td>
                    <td>@number.AddressRequirements</td>
                    <td>@Html.ActionLink("Buy", "Buy", "Numbers", new { PhoneNumber = @number.PhoneNumber }, null)</td>
                </tr>
            }
        }
    </tbody>
</table>

Run the app and navigate to the Numbers route. You should see a drop down which contains a list of all the countries where you have already created an address for. You can search for numbers in any of those countries.

Screen Shot 2014-11-30 at 7.38.20 PM.png

Now it’s time to buy a number. The number listing page already has a link to buy individual phone numbers, so all we need to do is implement the action method that responds the the URL in that link.

public ActionResult Buy(String PhoneNumber)
{
    var accountSid = ConfigurationManager.AppSettings["TwilioAccountSid"];
    var authToken = ConfigurationManager.AppSettings["TwilioAuthToken"];
    var twilio = new TwilioRestClient(accountSid, authToken);

    var purchaseOptions = new PhoneNumberOptions { PhoneNumber = PhoneNumber };

    var purchase = twilio.AddIncomingPhoneNumber(purchaseOptions);

    if (purchase.RestException != null)
    {
        return new HttpStatusCodeResult(500, purchase.RestException.Message);
    }

    return RedirectToAction("Index", "Numbers", new { number = PhoneNumber });
}

Here we are using the normal AddIncomingPhoneNumber method to ask Twilio to buy the selected phone number.

Go ahead and run the app one last time and now you should be able to buy new phone numbers.  If we attempt to buy an address-restricted phone number and have not yet given Twilio and address that satisfied the address requirement, Twilio will return an error letting you know the specific address requirement for that phone number.

Screen Shot 2014-11-30 at 7.53.11 PM.png

Wrapping it Up

So there you go, we have now a simple address and phone number management application that makes it easy for you to locate and buy phone numbers from countries that require addresses in order to own a phone number.

Having an address is not a requirement every country has for acquiring local phone numbers, but with the new capabilities shown in this blog post, when your business needs to provide a first-class and localised experience to customers around the world, even customers who live in countries with address restrictions, Twilio is there to support you.

I would love to hear what your business requirements are when it comes to having addresses for telephone numbers, and how you are using the new Twilio Addresses API. Reach me out on Twitter @marcos_placona, by email on marcos@twilio.com or MarcosPlacona on G+ to tell me more about it.