This example shows how to implement assisted transfer using the csharp SDK
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

Business Grade Assisted Transfer App

This application is outdated, but will be updated soon!

This example app shows how you can use the Conference feature on the App Platform for an assisted transfer use-case. In this flow, there are 2 Agents and 1 contact. The system calls out to a contact and adds them into a conference. Then 'Agent 1' is added in, this is one of your call center agents, maybe a real-estate agent or a help desk. Once Agent 1 and the contact are connected, Agent 1 selects the number for another agent, 'Agent 2', and they are added into the conference. Agent 1 can now drop while Agent 2 and the contact continue the discussion.

Uses the:


Build and Deploy

Azure One Click

Settings Required To Run

  • Catapult User Id
  • Catapult Api Token
  • Catapult Api Secret
  • Phone Number (any real phone number which can receive incoming call)

Deploy to Azure


Screen Shot Open the app in web browser. You will see phone numbers list (you should fill it first) to make call and recorded calls (if they exist).

How it works

Basic Flow Chart

Create Call to Owner and set callback URL for events

await Call.Create(new Dictionary<string, object>
    {"from", Context.Items["servicePhoneNumber"]},
    {"to", container.Resolve<string>("phoneNumber")},
    {"callbackUrl", $"{Context.Items["baseUrl"]}/called-to-owner"}

Speak Sentence then Create Bridge and set callbackURL for conference related events

var call = new Call {Id = ev.CallId};
await call.SpeakSentence("Welcome to the conference");
CurrentCall = call;
await Conference.Create(new Dictionary<string, object>
    {"from", Context.Items["servicePhoneNumber"]},
    {"callbackUrl", $"{Context.Items["baseUrl"]}/conference-callback"}

Add Member to conference then create new call to agent with recordingEnabled

CurrentConferenceMember = await
  conference.CreateMember(new Dictionary<string, object> {
      "callId", CurrentCall.Id
await Call.Create(new Dictionary<string, object> {
  {"from", Context.Items["servicePhoneNumber"]},
  {"to", ContactPhoneNumber},
  {"recordingEnabled", true},
  {"callbackUrl", $"{Context.Items["baseUrl"]}/called-to-contact"}

Add first agent to the conference

await conference.CreateMember(new Dictionary<string, object> {{"callId", ev.CallId}});

2nd Agent is requested to join call and callbackURL is set for events

await Call.Create(new Dictionary<string, object>
    {"from", Context.Items["servicePhoneNumber"]},
    {"to", AgentPhoneNumber},
    {"callbackUrl", $"{Context.Items["baseUrl"]}/called-to-agent"}

After 2nd Agent Answers, create gather

await call.CreateGather(
  "Agent from " + phoneNumber +
  " would like to join you to the conference. Press 1 to accept, Press 2 to decline."

Run some logic on the gathered digits, hangup if press 2.

if (ev.Digits == "1") {
  var conference = CurrentConference;
  if (conference != null)
      await conference.CreateMember(new Dictionary<string, object> {{"callId", ev.CallId}});
if (ev.Digits == "2") {
  await call.HangUp();

At hangup, create gather to either speak Sentence or play message

if (digits[0] == '1')
    await call.SpeakSentence(
      "Leave your message after signal. Press # to complete recording.",
if (digits[0] == '2')
    Trace.WriteLine("Play voice messages");
    await PlayVoiceMessage(container, call);


Clone the web application.

git clone

Before run them fill config files (Web.config) with right values:

phoneNumber - your phone number (the app will call to it),

catapultUserId, catapultApiToken, catapultApiSecret - auth data for Catapult API,

Open solution file in Visual Studio and build it.

You can run compiled C# code with IIS Express on local machine if you have ability to handle external requests or use any external hosting (like Azure).