This repo is an example of generating dynamic BXML for a voicemail app
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

CSharp BXML Voicemail

This application is outdated, but will be updated soon!

This repo is an example of generating dynamic BXML for a voicemail app.



Build and Deploy

Azure One Click

Settings Required To Run

  • Catapult User Id
  • Catapult Api Token
  • Catapult Api Secret

Deploy to Azure


Open app's url in another browser or refresh page in opened one. Call to phone number on the page and follow to voice instructions.

How it works

Basic Flow

Create bandwidth application (if needed)

var appId =
(client.Application.List(new ApplicationQuery {Size = 1000}).FirstOrDefault(
  a => a.Name == appName) ?? new Application()).Id ?? await
  client.Application.CreateAsync(new CreateApplicationData
    Name = appName,
    IncomingCallUrl = $"{baseUrl}/callback",
    CallbackHttpMethod = CallbackHttpMethod.Get

Order Phone numbers with application id

var numbers =
  await client.AvailableNumber.SearchLocalAsync(
    new LocalNumberQuery {State = "NC", City = "Cary", Quantity = 1});
phoneNumber = numbers.First().Number;
await client.PhoneNumber.CreateAsync(new CreatePhoneNumberData
  Number = phoneNumber,
  ApplicationId = applicationId

On incoming call, respond with bxml

var response = new Response(
  new SpeakSentence
    Sentence = "Press 1 to record a message. Press 2 to listen to your messages.",
    Gender = "female",
    Voice = "kate",
    Locale = "en_US"
  }, new Gather {RequestUrl = "/menu-event", MaxDigits = 1, InterDigitTimeout = 30});
return Response.AsText(response.ToXml(), "text/xml"); //return BML

If user presses 1, then prompt for recording to be ended by

//record a message
var response = new Response();
response.Add(new SpeakSentence
  Sentence = "Please record your message at the beep. When you are finished, please press pound",
  Gender = "female",
  Voice = "kate",
  Locale = "en_US"
response.Add(new PlayAudio {Url = ""});
response.Add(new Record {RequestUrl = "/record-event", TerminatingDigits = "#"});

If user presses 2, then playback last voicemail

var response = new Response();
foreach (var verb in RecordingStorage.Select(r => new PlayAudio {Url = r.Media}))

Once done recording, grab media

using (var catapultApiClient = new HttpClient())
    catapultApiClient.DefaultRequestHeaders.Authorization =
        new AuthenticationHeaderValue("Basic",
    var json = await catapultApiClient.GetStringAsync((string)Request.Query.RecordingUri);
    var serializer = new JavaScriptSerializer();
    var recording = serializer.Deserialize<Recording>(json);

    RecordingStorage.Add(recording); //save recording in storage


Clone the web application.

$ git clone

Go to project directory and open VoiceMailDemo.sln in Visual Studio, switch configuration to "Release" and make "Build Solution".

Open Web.config and fill section appSettings (see comments for details).

Click right button of mouse on project in Solution Explorer and select "Publish". Select in opened window "Microsoft Azure Web Apps". In new window log in on Azure and create new app (without database) by clicking on button "New". After that select created app in lis "Existing web apps" and press "OK". Press "Publish" to upload the app on Azure.