Transfer a call using API

    This API enables an in-progress or active call to a different URL and fetch and execute XML from a new URL. If the call (the A leg) is in a Dial, you can also transfer the other party (the B leg) at the same time or only transfer the B leg to an URL. This is useful for many applications where you want to asynchronously change the behavior of a live call. For example, you can play music while the call is on hold, queue calls, transfer calls etc. Check out more about Transfer API here

    POST https://api.plivo.com/v1/Account/{auth_id}/Call/{call_uuid}/

    Prerequisites

    1. Sign up for a free Plivo trial account.
    2. Check out our server-side SDKs page and install the right helper based on the programming language you want to use.
    3. Buy a Plivo phone number. A phone number is required to receive calls. You can buy a Plivo phone number in over 20+ countries through the Buy Numbers tab on your Plivo account UI. Check the Voice API coverage page for all the supported countries.
    4. Use a web hosting service to host your web application. There are many inexpensive cloud hosting providers that you can use for just a few dollars a month. Follow the instructions of your hosting provider to host your web application.

    Set up a Web Server

    Let’s assume your web server is located at example.com. Below is a snippet to set up a route on your webserver. Let’s call it, transfer_api. Now when we send an HTTP request to example.com/call_transfer this route will be invoked. This route will return an XML which will read out a message for the caller and when 1 is pressed, transfer_action route is invoked. This will initiate the Transfer API.

    Note:For PHP, the route will be example.com/transfer_api.php.
    1. Copy the relevant code below into a text file and save it. Let’s call it, transfer_api.
    2. Next, you will now have to configure this URL in your Plivo application.

    Code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    
    import plivo, plivoxml
    from flask import Flask, Response, request, url_for
    
    app = Flask(__name__)
    
    # When the call is answered, a message is played which prompts the user to press 1 to transfer the call.
    # Once the digit is pressed, the transfer API request is made and the call is transfered to another number.
    
    @app.route('/call_transfer/', methods=['POST', 'GET'])
    def call_transfer():
        response = plivoxml.Response()
        getdigits_action_url = url_for('transfer_action', _external=True)
        getDigits = plivoxml.GetDigits(action=getdigits_action_url,
                method='GET', timeout=7, numDigits=1,
                retries=1, redirect='false')
        getDigits.addSpeak("Press 1 to transfer this call")
        response.add(getDigits)
        params = {
            'length' : "10" # Time to wait in seconds
        }
        response.addWait(**params)
        print response.to_xml()
        return Response(str(response), mimetype='text/xml')
    
    # The Transfer API is invoked by the Get Digits action URL
    @app.route('/transfer_action/', methods=['POST', 'GET'])
    def transfer_action():
        auth_id = "Your_AUTH_ID"
        auth_token = "Your_AUTH_TOKEN"
        p = plivo.RestAPI(auth_id, auth_token)
    
        digit = request.args.get('Digits')
        call_uuid = request.args.get('CallUUID')
        print "Call UUID is : %s " % (call_uuid)
        print "Digit pressed is : %s " % (digit)
    
        if digit == "1":
            params = {
                'call_uuid' : call_uuid, # ID of the call
                'aleg_url' : "https://example.com/connect/", # URL to transfer for aleg
                'aleg_method' : "GET" # ethod to invoke the aleg_url
            }
            response = p.transfer_call(params)
        else :
            print "Wrong Input"
        print str(response)
        return Response(str(response), mimetype='text/plain')
    
    if __name__=='__main__':
        app.run(host='0.0.0.0',debug='True')
            
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    
    require 'rubygems'
    require 'rubygems'
    require 'sinatra'
    require 'plivo'
    include Plivo
    
    # When the call is answered, a message is played which prompts the user to press 1 to transfer the call.
    # Once the digit is pressed, the transfer API request is made and the call is transfered to another number.
    
    get '/call_transfer/' do
        r = Response.new()
        getdigits_action_url = "https://example.com/transfer_action/"
        params = {
            'action' => getdigits_action_url,
            'method' => 'GET',
            'timeout' => '7',
            'numDigits' => '1',
            'retries' => '1',
            'redirect' => 'false'
        }
        getDigits = r.GetDigits(params)
        getDigits.addSpeak("Press 1 to transfer this call")
    
        params = {
            'length' => "10" # Time to wait in seconds
        }
        r.addWait(params)
    
        puts r.to_xml()
        content_type 'text/xml'
        return r.to_s()
    end
    
    # The Transfer API is invoked by the Get Digits action URL
    get '/transfer_action/' do
        AUTH_ID = "Your_AUTH_ID"
        AUTH_TOKEN = "Your_AUTH_TOKEN"
        p = RestAPI.new(AUTH_ID, AUTH_TOKEN)
    
        digit = params[:Digits]
        call_uuid = params[:CallUUID]
        print "Digit pressed: #{digit}"
        print "Call UUID: #{call_uuid}"
    
        if (digit == "1")
            params = {
                'call_uuid' => call_uuid, # ID of the call
                'aleg_url' => "https://example.com/connect/", # URL to transfer for aleg
                'aleg_method' => "GET" # ethod to invoke the aleg_url
            }
            response = p.transfer_call(params)
            print response
        else
            print "Wrong Input"
        end
    end
            
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    
    var express = require('express');
    var app = express();
    var plivo = require('plivo');
    
    app.set('port', (process.env.PORT || 5000));
    
    // When the call is answered, a message is played which prompts the user to press 1 to transfer the call.
    // Once the digit is pressed, the transfer API request is made and the call is transfered to another number.
    
    app.get('/call_transfer/', function(request, response){
        var r = plivo.Response();
    
        var getdigits_action_url = "https://example.com/transfer_action/";
        var params = {
            'action': getdigits_action_url,
            'method': 'GET',
            'timeout': '7',
            'numDigits': '1',
            'retries': '1',
            'redirect': 'false'
        };
        var getDigits = r.GetDigits(params);
        getDigits.addSpeak("Press 1 to transfer this call");
    
        params = {
            'length': "10" // Time to wait in seconds
        };
        r.addWait(params);
    
        console.log(r.toXML());
        response.set({'Content-Type': 'text/xml'});
        response.send(r.toXML());
    });
    
    // The Transfer API is invoked by the Get Digits action URL
    app.get('/speak_action/', function(request, response){
        var AUTH_ID = "Your_AUTH_ID";
        var AUTH_TOKEN = "Your_AUTH_TOKEN";
        var p = plivo.RestAPI.new(AUTH_ID, AUTH_TOKEN);
    
        var digit = request.query.Digits || request.body.Digits;
        var call_uuid = request.query.CallUUID || request.body.CallUUID;
        console.log("Digit pressed: ", digit);
        console.log("Call UUID: ", call_uuid);
    
        if (digit === "1") {
            var params = {
                'call_uuid': call_uuid, // ID of the call
                'aleg_url': "https://example.com/connect/", // URL to transfer for aleg
                'aleg_method': "GET" // method to invoke the aleg_url
            };
            response = p.transfer_call(params);
        } else {
            console.log("Wrong Input");
            response = "Error";
        }
        return response;
    });
    
    app.listen(app.get('port'), function() {
        console.log('Node app is running on port', app.get('port'));
    });
            
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    
    <!-- speak_api.php -->
    <?php    
        require 'vendor/autoload.php';
        use Plivo\Response;
        # When the call is answered, a message is played which prompts the user to press 1 to transfer the call.
        # Once the digit is pressed, the transfer API request is made and the call is transfered to another number.
        $r = new Response();
    
        $getdigits_action_url = "https://example.com/transfer_action.php";
        $params = array(
            'action' => $getdigits_action_url, # The URL to which the digits are sent.
            'method' => 'GET', # Submit to action URL using GET or POST.
            'timeout' => '7', # Time in seconds to wait to receive the first digit.
            'numDigits' =>  '1', # Maximum number of digits to be processed in the current operation.
            'retries' => '1', # Indicates the number of retries the user is allowed to input the digits
            'redirect' => 'false' # Redirect to action URL if true. If false,only request the URL and continue to next element.
        );
        $getDigits = $r->addGetDigits($params);
        $getDigits->addSpeak("Press 1 to transfer your call");
        $waitparam = array(
            'length' => '10'
        );
        $r->addWait($waitparam);
    
        Header('Content-type: text/xml');
        echo($r->toXML());
    ?>
    
    <!-- transfer_action.php -->
    
    <?php
        require 'vendor/autoload.php';
        use Plivo\RestAPI;
    
        $auth_id = "Your_AUTH_ID";
        $auth_token = "Your_AUTH_TOKEN";
        $p = new RestAPI($auth_id, $auth_token);
    
        $digit = $_REQUEST['Digits'];
        $call_uuid = $_REQUEST['CallUUID'];
        error_log($digit);
        error_log($call_uuid);
    
        if ($digit == "1"){
            $params = array(
                'call_uuid' => $call_uuid, # ID of the call
                'aleg_url' => 'https://example.com/connect.php', # URL to transfer for aleg
                'aleg_method' => 'GET', # Method to invoke the aleg_url
            );
            $resp = $p->transfer_call($params);
            print_r ($resp);
        } else {
            print ("Wrong Input");
        }
    ?>
            
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    
    // transferApi.java
    package plivoexample;
    
    import java.io.IOException;
    import com.plivo.helper.exception.PlivoException;
    import com.plivo.helper.xml.elements.GetDigits;
    import com.plivo.helper.xml.elements.PlivoResponse;
    import com.plivo.helper.xml.elements.Speak;
    import com.plivo.helper.xml.elements.Wait;
    import org.eclipse.jetty.server.Server;
    import org.eclipse.jetty.servlet.ServletContextHandler;
    import org.eclipse.jetty.servlet.ServletHolder;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class transferApi extends HttpServlet {
        private static final long serialVersionUID = 1L;
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
    
            PlivoResponse response = new PlivoResponse();
            GetDigits gd = new GetDigits();
            gd.setAction("https://example.com/transfer_action");
            gd.setMethod("GET");
            gd.setTimeout(7);
            gd.setNumDigits(1);
            gd.setRetries(1);
            gd.setRedirect(false);
    
            Speak spk = new Speak("Press 1 to transfer your call");
            Wait wait = new Wait();
            wait.setLength(10);
    
            try {
                gd.append(spk);
                response.append(gd);
                response.append(wait);
                System.out.println(response.toXML());
                resp.addHeader("Content-Type", "text/xml");
                resp.getWriter().print(response.toXML());;
            } catch (PlivoException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) throws Exception {
            String port = System.getenv("PORT");
            if(port==null)
                port ="8000";
            Server server = new Server(Integer.valueOf(port));
            ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
            context.setContextPath("/");
            server.setHandler(context);
            context.addServlet(new ServletHolder(new transferApi()),"/call_transfer/");
            context.addServlet(new ServletHolder(new transferAction()),"/transfer_action");
            server.start();
            server.join();
        }
    }
    
    // transferAction.java
    package plivoexample;
    
    import java.io.IOException;
    import java.util.LinkedHashMap;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import com.plivo.helper.api.client.RestAPI;
    import com.plivo.helper.api.response.response.GenericResponse;
    import com.plivo.helper.exception.PlivoException;
    
    public class transferAction extends HttpServlet {
        private static final long serialVersionUID = 1L;
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            String auth_id = "Your_AUTH_ID";
            String auth_token = "Your_AUTH_TOKEN";
            RestAPI api = new RestAPI(auth_Id, auth_Token, "v1");
    
            String digit = req.getParameter("Digits");
            String call_uuid = req.getParameter("CallUUID");
            System.out.println("Digit: " + digit + " Call UUID: " + call_uuid);
    
            if(digit.equals("1")) {
                LinkedHashMap<String, String> parameters = new LinkedHashMap<String, String>();
                parameters.put("call_uuid",call_uuid);
                parameters.put("aleg_url","https://example.com/connect/");
                parameters.put("aleg_method","GET");
    
                try {
                    GenericResponse transfer = api.transferCall(parameters);
                    System.out.println(transfer);
                } catch (PlivoException e) {
                    System.out.println(e.getLocalizedMessage());
                }
            } else {
                System.out.println("Wrong Input");
            }
        }
    }
            
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using RestSharp;
    using Plivo.XML;
    using Plivo.API;
    using Nancy;
    
    namespace transfer_api
    {
        public class Program : NancyModule
        {
            public Program()
            {
                // When the call is answered, a text is played which prompts the user to press 1 to transfer the call.
                // Once the digit is pressed, the transfer API request is made and the call is transfered to another number.
    
                Get["/call_transfer/"] = x =>
                {
                    Plivo.XML.Response resp = new Plivo.XML.Response();
                    String getdigits_action_url = "http://example.com/transfer_action/";
    
                    // Add GetDigits XML Tag
                    GetDigits gd = new GetDigits("", new Dictionary&lt;string, string&gt;()
                    {
                        {"action",getdigits_action_url}, // The URL to which the digits are sent.
                        {"method","GET"}, // Submit to action URL using GET or POST.
                        {"timeout","7"}, // Time in seconds to wait to receive the first digit.
                        {"retries","1"}, // Indicates the number of retries the user is allowed to input the digits
                        {"redirect","false"}, // Redirect to action URL if true. If false,only request the URL and continue to next element.
                        {"numDigits","1"}
                    });
    
                    // Add Speak XML Tag
                    gd.AddSpeak("Press 1 to transfer this call", new Dictionary&lt;string, string&gt;());
                    resp.Add(gd);
    
                    // Add Wait XML Tag
                    resp.AddWait(new Dictionary&lt;string, string&gt;()
                    {
                        {"length","10"}
                    });
    
                    Debug.WriteLine(resp.ToString());
    
                    var output = resp.ToString();
                    var res = (Nancy.Response)output;
                    res.ContentType = "text/xml";
                    return res;
                };
    
                // The Transfer API is invoked by the Get Digits action URL
    
                Get["/transfer_action/"] = x =>
                {
                    String digits = Request.Query["Digits"];
                    String uuid = Request.Query["CallUUID"];
                    Debug.WriteLine("Digit pressed: {0}, Call UUID: {1}", digits, uuid);
    
                    if (digits == "1")
                    {
                        RestAPI plivo = new RestAPI("Your_AUTH_ID", "Your_AUTH_TOKEN");
    
                        // Transfer API
                        IRestResponse&lt;GenericResponse&gt; resp = plivo.transfer_call(new Dictionary&lt;string, string&gt;()
                        {
                            { "call_uuid", uuid }, // ID of the call
                            { "aleg_url", "http://example.com/connect/" }, // URL to transfer for aleg
                            { "aleg_method", "GET" } // Method to invoke the aleg_url
                        });
    
                        Debug.WriteLine(resp.Content);
                    }
                    else
                    {
                        Debug.WriteLine("Invalid");
                    }
                    return "Transfer API";
                };
            }
        }
    }
            
    

    Create an Application

    1. Create an Application by visiting the Application Page and click on New Application or by using Plivo’s Application API.
    2. Give your application a name. Let’s call it Transfer API. Enter your server URL (e.g., http://www.example.com/transfer_api) in the Answer URL field and set the method as POST. See our Application API docs to learn how to modify your application through our APIs.
    3. Click on Create to save your application.

    Plivo Create Application Transfer API

    Assign a Plivo number to your app

    1. Navigate to the Numbers page and select the phone number you want to use for this app.
    2. Select Transfer Api (name of the app) from the Plivo App dropdown list.
    3. Click on ‘Update’ to save.

    Create Transfer API Application

    If you don’t have a number, go to the Buy Number page to purchase a Plivo phone number.

    Phone Number Search

    Test it out

    When you make a call to your Plivo number, the call will be answered by Plivo and the message “Press 1 to transfer this call” will be played. If you press 1, the Transfer API is used to transfer the call to another number.

    Sample XML

    Here is the XML returned from /call_transfer/:

    1
    2
    3
    4
    5
    6
    
    <Response>
        <GetDigits redirect="false" retries="1" method="GET" numDigits="1" action="http://example.com/transfer_action/" timeout="7">
            <Speak>Press 1 to transfer your call</Speak>
        </GetDigits>
        <Wait length="10"/>
    </Response>
    

    Here is the response from /transfer_action/:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    Digit: 1
    Call UUID: 2d3ccd56-c954-11e4-aaa3-fb391e29dbd3
    
    
    (202, {
            u'call_uuids': [
                u'e66aa1a0-9587-11e4-9d37-c15e0b562efe'
            ],
            u'message': u'transfer executed',
            u'api_id': u'eb8c80ae-9587-11e4-b423-22000ac8a2f8'
        }
    )
    
    <Response>
        <Speak>Connecting your call</Speak>
        <Dial>
            <Number>1111111111</Number>
        </Dial>
    </Response>
    

    Next Step

    Learn how to Forward Calls to a SIP Endpoint.

    1. Make an Outbound Call
    2. Play a Text-to-speech Message
    3. Connect Call to a Second Person
    4. Greet Caller by Name
    5. Play MP3/WAV Audio to Caller
    6. Hangup Using API
    7. Receive Incoming Call
    8. Forward Incoming Call
    9. Record Using API
    10. Screen Incoming Call
    11. Reject incoming call
    12. Get Details of all Calls
    13. Get Details of a single Call
    14. Get Details of Live Calls
    15. Build an IVR Phone Menu
    16. Conference Call
    17. Call Forward
    18. SIP Endpoint (Direct-Dial)