Skip to contentSkip to navigationSkip to topbar
Page toolsOn this page
Looking for more inspiration?Visit the

Make outbound phone calls


In this tutorial, you'll learn how to make and manage outbound phone calls with Twilio Programmable Voice(link takes you to an external page) and your preferred programming language. You'll use the Calls resource in the Twilio Voice API.


Complete the prerequisites

complete-the-prerequisites page anchor
PythonNode.jsPHPC# (.NET Core)JavaGoRuby
  1. Install Python(link takes you to an external page).
  2. Install the Twilio Python SDK(link takes you to an external page). To install using pip, run:
pip install twilio
  • Sign up for Twilio and get a phone number:
    1. Sign up for Twilio(link takes you to an external page).
    2. To get a phone that has voice capabilities, do either of the following in the Twilio Console(link takes you to an external page):
      • In the Account Dashboard, click Get a phone number.
      • In the navigation menu, go to Phone Numbers > Manage > Buy a number.
    3. In the Account Dashboard, copy your Account SID and Auth Token and paste them in a temporary local file for use later in this quickstart.

PythonNode.jsPHPC# (.NET Core)JavaGoRuby
  1. Create and open a new file called make_call.py anywhere on your machine and paste in the following code:

    Make an outbound call with TwiMLLink to code sample: Make an outbound call with TwiML
    1
    # Download the helper library from https://www.twilio.com/docs/python/install
    2
    import os
    3
    from twilio.rest import Client
    4
    5
    # Find your Account SID and Auth Token at twilio.com/console
    6
    # and set the environment variables. See http://twil.io/secure
    7
    account_sid = os.environ["TWILIO_ACCOUNT_SID"]
    8
    auth_token = os.environ["TWILIO_AUTH_TOKEN"]
    9
    client = Client(account_sid, auth_token)
    10
    11
    call = client.calls.create(
    12
    twiml="<Response><Say>Ahoy, World</Say></Response>",
    13
    to="+14155551212",
    14
    from_="+15017122661",
    15
    )
    16
    17
    print(call.sid)

    To learn all of the API response values that you can return with print(), see the response for Create a call in the API documentation. Precede the response value with call. (for example: print(call.sid) returns the sid value).

  2. Set the environment variables for your Account SID and Auth Token.

    (warning)

    Improve security with API keys

    To better control access, use API keys instead of the Account SID and Auth Token when you deploy to production. To learn more, see Why you should use API keys.

    • On Mac or Linux:

      1. Run the following commands to add your credentials as environment variables in a twilio.env file and source them. Replace ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX with your Account SID and replace your_auth_token with your Auth Token.
      1
      echo "export TWILIO_ACCOUNT_SID='ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'" > twilio.env
      2
      echo "export TWILIO_AUTH_TOKEN='your_auth_token'" >> twilio.env
      3
      source ./twilio.env
      1. If you're committing code with git, run the following command to add the twilio.env file to .gitignore to avoid uploading your credentials in plain text:

        echo "twilio.env" >> .gitignore
    • On Windows command line (cmd.exe):

      Run the following commands. Replace ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX with your Account SID and replace your_auth_token with your Auth Token.

      1
      set TWILIO_ACCOUNT_SID=ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      2
      set TWILIO_AUTH_TOKEN=your_auth_token

    Learn more about storing your Twilio credentials safely.

  3. In the make_call.py file, do the following:

    • Replace the value for to with the recipient phone number in E.164 format.

    • Replace the value for from with your Twilio phone number in E.164 format.

    • Replace the value for twiml with your desired TwiML instructions.

      • To use a hosted TwiML URL, replace twiml with url and set the value to the URL that hosts your TwiML instructions. For example:

        url="http://demo.twilio.com/docs/voice.xml"

        The following voice.xml file is hosted at http://demo.twilio.com/docs/voice.xml uses the <Say> and the <Play> TwiML tags to read a message and play an MP3 file for the user.

        voice.xml

        voicexml page anchor
        1
        <?xml version="1.0" encoding="UTF-8"?>
        2
        <Response>
        3
        <Say voice="woman">Thanks for trying our documentation. Enjoy!</Say>
        4
        <Play>http://demo.twilio.com/docs/classic.mp3</Play>
        5
        </Response>
        6
        </xml>
      • To use a TwiML application to handle calls, replace twiml with application_sid and set the value to your TwiML application's SID. You can create and configure applications on the TwiML Apps(link takes you to an external page) page in the Twilio Console.

        application_sid="<YOUR_TWIML_APP_SID>"

        When your outbound call is connected, Twilio will make a request to the Voice URL set on your application.

        (warning)

        Warning

        The application_sid take precedence over the twiml and url parameters and ignores the following parameters: method, fallback_url, fallback_method, status_callback, status_callback_method. Twilio expects that your application handles all of this information. Learn more about the Calls resource.

  4. Save your changes and run this command from your terminal in the directory that contains make_call.py:

    python make_call.py

After a few moments, you receive a call from your Twilio number.


Manage your outbound call

manage-your-outbound-call page anchor

Optionally, you can configure additional parameters when making outbound calls to customize call behavior. Below are some common use cases.

Send digits

send-digits page anchor

To dial an extension, set the SendDigits parameter to the sequence of digits to send after the call connects.

  • You can include any digit (0-9), A, B, C, D, #, or *.
  • To add pauses, use w for a half-second pause or W for a one-second pause between digits.

Learn more about the request body parameters.

1
// Download the helper library from https://www.twilio.com/docs/node/install
2
const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";
3
4
// Find your Account SID and Auth Token at twilio.com/console
5
// and set the environment variables. See http://twil.io/secure
6
const accountSid = process.env.TWILIO_ACCOUNT_SID;
7
const authToken = process.env.TWILIO_AUTH_TOKEN;
8
const client = twilio(accountSid, authToken);
9
10
async function createCall() {
11
const call = await client.calls.create({
12
from: "+18668675310",
13
method: "GET",
14
sendDigits: "1234#",
15
to: "+14155551212",
16
url: "http://demo.twilio.com/docs/voice.xml",
17
});
18
19
console.log(call.sid);
20
}
21
22
createCall();

Response

Note about this response
1
{
2
"account_sid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
3
"answered_by": null,
4
"api_version": "2010-04-01",
5
"caller_name": null,
6
"date_created": "Tue, 31 Aug 2010 20:36:28 +0000",
7
"date_updated": "Tue, 31 Aug 2010 20:36:44 +0000",
8
"direction": "inbound",
9
"duration": "15",
10
"end_time": "Tue, 31 Aug 2010 20:36:44 +0000",
11
"forwarded_from": "+141586753093",
12
"from": "+18668675310",
13
"from_formatted": "(415) 867-5308",
14
"group_sid": null,
15
"parent_call_sid": null,
16
"phone_number_sid": "PNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
17
"price": "-0.03000",
18
"price_unit": "USD",
19
"sid": "CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
20
"start_time": "Tue, 31 Aug 2010 20:36:29 +0000",
21
"status": "completed",
22
"subresource_uris": {
23
"notifications": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Notifications.json",
24
"recordings": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Recordings.json",
25
"payments": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Payments.json",
26
"events": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Events.json",
27
"siprec": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Siprec.json",
28
"streams": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Streams.json",
29
"transcriptions": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Transcriptions.json",
30
"user_defined_message_subscriptions": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/UserDefinedMessageSubscriptions.json",
31
"user_defined_messages": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/UserDefinedMessages.json"
32
},
33
"to": "+14155551212",
34
"to_formatted": "(415) 867-5309",
35
"trunk_sid": null,
36
"uri": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.json",
37
"queue_time": "1000"
38
}

Receive call status updates

receive-call-status-updates page anchor

To receive the outcome of calls, set the StatusCallback parameter to your status callback URL. After Twilio completes your call, it'll make an asynchronous request to the URL. If you don't provide a StatusCallback URL, Twilio will end the call without sending any status updates to your application.

  • To specify the HTTP request method Twilio should use when making requests to the StatusCallback URL, set the StatusCallbackMethod parameter to either GET or POST. The default is POST.
  • To specify which call progress events should trigger a request to your StatusCallback URL, set the StatusCallbackEvent parameter to either initiated, ringing, answered, or completed. To specify multiple values, separate them with a space. The default is completed.

Learn more about the StatusCallback and StatusCallbackEvent parameters.

(warning)

Warning

The StatusCallback URL must contain a valid hostname. You can't use underscores.

1
// Download the helper library from https://www.twilio.com/docs/node/install
2
const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";
3
4
// Find your Account SID and Auth Token at twilio.com/console
5
// and set the environment variables. See http://twil.io/secure
6
const accountSid = process.env.TWILIO_ACCOUNT_SID;
7
const authToken = process.env.TWILIO_AUTH_TOKEN;
8
const client = twilio(accountSid, authToken);
9
10
async function createCall() {
11
const call = await client.calls.create({
12
from: "+18668675310",
13
method: "GET",
14
statusCallback: "https://www.myapp.com/events",
15
statusCallbackEvent: ["completed"],
16
statusCallbackMethod: "POST",
17
to: "+14155551212",
18
url: "http://demo.twilio.com/docs/voice.xml",
19
});
20
21
console.log(call.sid);
22
}
23
24
createCall();

Response

Note about this response
1
{
2
"account_sid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
3
"answered_by": null,
4
"api_version": "2010-04-01",
5
"caller_name": null,
6
"date_created": "Tue, 31 Aug 2010 20:36:28 +0000",
7
"date_updated": "Tue, 31 Aug 2010 20:36:44 +0000",
8
"direction": "inbound",
9
"duration": "15",
10
"end_time": "Tue, 31 Aug 2010 20:36:44 +0000",
11
"forwarded_from": "+141586753093",
12
"from": "+18668675310",
13
"from_formatted": "(415) 867-5308",
14
"group_sid": null,
15
"parent_call_sid": null,
16
"phone_number_sid": "PNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
17
"price": "-0.03000",
18
"price_unit": "USD",
19
"sid": "CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
20
"start_time": "Tue, 31 Aug 2010 20:36:29 +0000",
21
"status": "completed",
22
"subresource_uris": {
23
"notifications": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Notifications.json",
24
"recordings": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Recordings.json",
25
"payments": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Payments.json",
26
"events": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Events.json",
27
"siprec": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Siprec.json",
28
"streams": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Streams.json",
29
"transcriptions": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Transcriptions.json",
30
"user_defined_message_subscriptions": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/UserDefinedMessageSubscriptions.json",
31
"user_defined_messages": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/UserDefinedMessages.json"
32
},
33
"to": "+14155551212",
34
"to_formatted": "(415) 867-5309",
35
"trunk_sid": null,
36
"uri": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.json",
37
"queue_time": "1000"
38
}
(warning)

Warning

Recording a call is subject to the same obligations and requirements as the Recordings resource and the <Record> TwiML verb. For workflows subject to PCI or the Health Insurance Portability and the Accountability Act (HIPAA), see the applicable documentation.

To record your outbound call, set the Record parameter and set its value to true. You can also configure the following optional parameters to manage your call recordings:

  • To receive the recording and other information about the call, set the RecordingStatusCallback parameter to a URL that Twilio will request when the recording is available.
  • To specify the HTTP request method Twilio should use when making requests to the RecordingStatusCallback URL, set the RecordingStatusCallbackMethod parameter to either GET or POST. The default is POST.
  • To specify which recording status changes should trigger a request to your RecordingStatusCallback URL, set the RecordingStatusCallbackEvent parameter to either completed, absent, or in-progress. To specify multiple values, separate them with a space.

Learn more about the RecordingStatusCallback and RecordingStatusCallbackEvent parameters.

To programmatically pause, resume, or stop recordings, see the Recordings resource and How to record phone calls.

1
// Download the helper library from https://www.twilio.com/docs/node/install
2
const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";
3
4
// Find your Account SID and Auth Token at twilio.com/console
5
// and set the environment variables. See http://twil.io/secure
6
const accountSid = process.env.TWILIO_ACCOUNT_SID;
7
const authToken = process.env.TWILIO_AUTH_TOKEN;
8
const client = twilio(accountSid, authToken);
9
10
async function createCall() {
11
const call = await client.calls.create({
12
from: "+15017122661",
13
record: true,
14
recordingStatusCallback:
15
"https://www.example.com/recording-status-callback",
16
recordingStatusCallbackEvent: ["completed", "in-progress"],
17
recordingStatusCallbackMethod: "POST",
18
to: "+14155551212",
19
url: "http://demo.twilio.com/docs/voice.xml",
20
});
21
22
console.log(call.sid);
23
}
24
25
createCall();

Response

Note about this response
1
{
2
"account_sid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
3
"answered_by": null,
4
"api_version": "2010-04-01",
5
"caller_name": null,
6
"date_created": "Tue, 31 Aug 2010 20:36:28 +0000",
7
"date_updated": "Tue, 31 Aug 2010 20:36:44 +0000",
8
"direction": "inbound",
9
"duration": "15",
10
"end_time": "Tue, 31 Aug 2010 20:36:44 +0000",
11
"forwarded_from": "+141586753093",
12
"from": "+15017122661",
13
"from_formatted": "(415) 867-5308",
14
"group_sid": null,
15
"parent_call_sid": null,
16
"phone_number_sid": "PNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
17
"price": "-0.03000",
18
"price_unit": "USD",
19
"sid": "CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
20
"start_time": "Tue, 31 Aug 2010 20:36:29 +0000",
21
"status": "completed",
22
"subresource_uris": {
23
"notifications": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Notifications.json",
24
"recordings": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Recordings.json",
25
"payments": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Payments.json",
26
"events": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Events.json",
27
"siprec": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Siprec.json",
28
"streams": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Streams.json",
29
"transcriptions": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Transcriptions.json",
30
"user_defined_message_subscriptions": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/UserDefinedMessageSubscriptions.json",
31
"user_defined_messages": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/UserDefinedMessages.json"
32
},
33
"to": "+14155551212",
34
"to_formatted": "(415) 867-5309",
35
"trunk_sid": null,
36
"uri": "/2010-04-01/Accounts/ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Calls/CAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.json",
37
"queue_time": "1000"
38
}

After Twilio completes your call, it'll make an asynchronous request to your status callback URL. From here, it's up to you to decide what to do next. For example, you can trigger another event like send an SMS to the phone number you just called with a follow-up message, or try to place the call again if the call status returns failed.

  • Learn more about the Calls resource and all of its parameters to customize your outbound calls.
  • Add voice capabilities to your web application with the Voice JavaScript SDK or Twilio's mobile client SDKs for your Android or iOS applications.
  • View more Voice tutorials to learn how to build interactive voice response (IVR) systems, call recording, and more.