Twilio Migration Guide
Introduction
This guide will show you how easy it is to migrate your voice calling services to Bandwidth from Twilio. We're the only Twilio alternative with its own nationwide carrier network, giving you the quality, control, and cost-savings that other providers can't match.
Our Voice API and XML structures (TwiML v BXML) are similar, allowing you to seamlessly migrate with low effort. With our comprehensive APIs, you will have everything you need and more to grow your business.
The differences between Twilio and Bandwidth's voice offerings
Most of the features available on Twilio's Programmable Voice are also available on Bandwidth's Programmable Voice API. Therefore, your migration should be straightforward, as getting started is identical for both.
A side-by-side comparison of our Programmable Voice API capabilities.
Features | Twilio | Bandwidth |
---|---|---|
Receive Calls from PSTN | ✓ | ✓ |
Make Calls to PSTN | ✓ | ✓ |
Own Nationwide Carrier Network | X | ✓ |
Play Audio | ✓ | ✓ |
Text-to-Speech | ✓ | ✓ |
SSML Support | ✓ | ✓ |
Recording (single/dual channel) and storage | ✓ | ✓ |
Transcription | ✓ | ✓ |
Media Streaming | ✓ | ✓ (Available via audio) |
Real-time transcription | ✓ | ✓ |
Custom Caller ID | ✓ | ✓ |
Voicemail Detection | ✓ | ✓ |
Conferencing | ✓ | ✓ |
Call Forwarding | ✓ | ✓ |
DTMF-based IVR | ✓ | ✓ |
Voice Activated IVR | ✓ | X |
Migrating your existing voice application
Migrating from Twilio to Bandwidth will require you to refactor your existing code, but most API call logic will remain the same. For example, Bandwidth's BXML must be used directly, and there is no user interface for constructing call flows visually. We also offer SDKs in your preferred language (Node, Python, Ruby, Java, C#, and PHP) and have put together a few examples to demonstrate how easy it is to move to Bandwidth.
How to make an outbound call
In this example we will show you the process of refactoring your code to migrate your existing application from Twilio to Bandwidth by changing just a few lines of code for placing an outbound call.
Twilio:
- cURL
- Java
- C#
- Ruby
- NodeJS
- Python
- PHP
Note: Remember to add authentication for your application if needed!
curl -X POST https://api.twilio.com/2010-04-01/Accounts/$TWILIO_ACCOUNT_SID/Calls.json \
--data-urlencode "Url=http://demo.twilio.com/docs/voice.xml" \
--data-urlencode "To=+15017122661" \
--data-urlencode "From=+15558675310" \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
// Install the Java helper library from twilio.com/docs/java/install
import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Call;
import com.twilio.type.PhoneNumber;
import java.net.URI;
public class Example {
// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
public static final String ACCOUNT_SID = System.getenv("TWILIO_ACCOUNT_SID");
public static final String AUTH_TOKEN = System.getenv("TWILIO_AUTH_TOKEN");
public static void main(String[] args) {
Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
Call call = Call.creator(
new com.twilio.type.PhoneNumber("+15017122661"),
new com.twilio.type.PhoneNumber("+15558675310"),
URI.create("http://demo.twilio.com/docs/voice.xml"))
.create();
System.out.println(call.getSid());
}
}
// Install the C# / .NET helper library from twilio.com/docs/csharp/install
using System;
using Twilio;
using Twilio.Rest.Api.V2010.Account;
class Program
{
static void Main(string[] args)
{
// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
string accountSid = Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID");
string authToken = Environment.GetEnvironmentVariable("TWILIO_AUTH_TOKEN");
TwilioClient.Init(accountSid, authToken);
var call = CallResource.Create(
url: new Uri("http://demo.twilio.com/docs/voice.xml"),
to: new Twilio.Types.PhoneNumber("+15017122661"),
from: new Twilio.Types.PhoneNumber("+15558675310")
);
Console.WriteLine(call.Sid);
}
}
# Download the helper library from https://www.twilio.com/docs/ruby/install
require 'rubygems'
require 'twilio-ruby'
# Find your Account SID and Auth Token at twilio.com/console
# and set the environment variables. See http://twil.io/secure
account_sid = ENV['TWILIO_ACCOUNT_SID']
auth_token = ENV['TWILIO_AUTH_TOKEN']
@client = Twilio::REST::Client.new(account_sid, auth_token)
call = @client.calls.create(
url: 'http://demo.twilio.com/docs/voice.xml',
to: '+15017122661',
from: '+15558675310'
)
puts call.sid
// Download the helper library from https://www.twilio.com/docs/node/install
// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = require('twilio')(accountSid, authToken);
client.calls
.create({
url: 'http://demo.twilio.com/docs/voice.xml',
to: '+15017122661',
from: '+15558675310'
})
.then((call) => console.log(call.sid));
# Download the helper library from https://www.twilio.com/docs/python/install
import os
from twilio.rest import Client
# Find your Account SID and Auth Token at twilio.com/console
# and set the environment variables. See http://twil.io/secure
account_sid = os.environ['TWILIO_ACCOUNT_SID']
auth_token = os.environ['TWILIO_AUTH_TOKEN']
client = Client(account_sid, auth_token)
call = client.calls.create(
url='http://demo.twilio.com/docs/voice.xml',
to='+15017122661',
from_='+15558675310'
)
print(call.sid)
<?php
// Update the path below to your autoload.php,
// see https://getcomposer.org/doc/01-basic-usage.md
require_once '/path/to/vendor/autoload.php';
use Twilio\Rest\Client;
// Find your Account SID and Auth Token at twilio.com/console
// and set the environment variables. See http://twil.io/secure
$sid = getenv("TWILIO_ACCOUNT_SID");
$token = getenv("TWILIO_AUTH_TOKEN");
$twilio = new Client($sid, $token);
$call = $twilio->calls
->create("+15017122661", // to
"+15558675310", // from
["url" => "http://demo.twilio.com/docs/voice.xml"]
);
print($call->sid);
Bandwidth:
- Request Payload
- cURL
- Java
- C#
- Ruby
- NodeJS
- Python
- PHP
Note: Remember to add authentication for your application if needed!
POST https://voice.bandwidth.com/api/v2/accounts/{accountId}
//Make sure an authentication header is added with your BANDWIDTH_USERNAME and BANDWIDTH_PASSWORD
{
"from": "{BW_NUMBER}",
"to": "{$USER_NUMBER}",
"applicationId": "{APPLICATION_ID}",
"answerUrl": "http://example.test/callbacks/answer",
}
Note: Remember to add authentication for your application if needed!
curl 'https://voice.bandwidth.com/api/v2/accounts/{BW_ACCOUNT_ID}/calls' \
-X POST \
-u '{BANDWIDTH_USERNAME}:{BANDWIDTH:PASSWORD}' \
-H 'Content-Type: application/json' \
-d '{
"from": "{BW_NUMBER}",
"to": "{$USER_NUMBER}",
"applicationId": "{APPLICATION_ID}",
"answerUrl": "http://example.test/callbacks/answer",
}'
import com.bandwidth.sdk.ApiClient;
import com.bandwidth.sdk.ApiException;
import com.bandwidth.sdk.Configuration;
import com.bandwidth.sdk.auth.*;
import com.bandwidth.sdk.models.*;
import com.bandwidth.sdk.api.CallsApi;
public class Example {
public static void main(String[] args) {
ApiClient defaultClient = Configuration.getDefaultApiClient();
defaultClient.setBasePath("http://localhost");
// Configure HTTP basic authorization: Basic
HttpBasicAuth Basic = (HttpBasicAuth) defaultClient.getAuthentication("Basic");
Basic.setUsername("YOUR USERNAME");
Basic.setPassword("YOUR PASSWORD");
CallsApi apiInstance = new CallsApi(defaultClient);
String accountId = "9900000"; // String | Your Bandwidth Account ID.
CreateCall createCall = new CreateCall(); // CreateCall | JSON object containing information to create an outbound call
try {
CreateCallResponse result = apiInstance.createCall(accountId, createCall);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling CallsApi#createCall");
System.err.println("Status code: " + e.getCode());
System.err.println("Reason: " + e.getResponseBody());
System.err.println("Response headers: " + e.getResponseHeaders());
e.printStackTrace();
}
}
}
using System;
using System.Threading.Tasks;
using Bandwidth.Standard;
using Bandwidth.Standard.Exceptions;
using Bandwidth.Standard.Voice.Models;
class Program
{
static async Task Main(string[] args)
{
var username = System.Environment.GetEnvironmentVariable("BW_USERNAME");
var password = System.Environment.GetEnvironmentVariable("BW_PASSWORD");
var accountId = System.Environment.GetEnvironmentVariable("BW_ACCOUNT_ID");
var applicationId = System.Environment.GetEnvironmentVariable("BW_VOICE_APPLICATION_ID");
var to = System.Environment.GetEnvironmentVariable("USER_NUMBER");
var from = System.Environment.GetEnvironmentVariable("BW_NUMBER");
var baseUrl = System.Environment.GetEnvironmentVariable("BASE_CALLBACK_URL");
var answerUrl = string.Concat(baseUrl, "/callbacks/answer");
var client = new BandwidthClient.Builder()
.VoiceBasicAuthCredentials(username, password)
.Build();
var request = new CreateCallRequest()
{
ApplicationId = applicationId,
To = to,
From = from,
AnswerUrl = answerUrl
//remember to add auth for your application if needed!
};
try
{
var response = await client.Voice.APIController.CreateCallAsync(accountId, request);
Console.WriteLine(response.Data);
}
catch (ApiException e)
{
Console.WriteLine(e.Message);
}
}
}
require 'bandwidth-sdk'
Bandwidth.configure do |config|
config.username = ENV.fetch('BW_USERNAME')
config.password = ENV.fetch('BW_PASSWORD')
end
calls_api_instance = Bandwidth::CallsApi.new
call_body = Bandwidth::CreateCall.new(
application_id: ENV.fetch('BW_VOICE_APPLICATION_ID'),
to: ENV.fetch('USER_NUMBER'),
from: ENV.fetch('BW_NUMBER'),
answer_url: "#{ENV.fetch('BASE_CALLBACK_URL')}/callbacks/answer",
)
begin
result = calls_api_instance.create_call(ENV.fetch('BW_ACCOUNT_ID'), call_body)
p result.call_id
rescue Bandwidth::ApiError => e
p e.code
end
import { CallsApi, Configuration, CallbackMethodEnum } from 'bandwidth-sdk';
const BW_USERNAME = process.env.BW_USERNAME;
const BW_PASSWORD = process.env.BW_PASSWORD;
const BW_ACCOUNT_ID = process.env.BW_ACCOUNT_ID;
const BW_VOICE_APPLICATION_ID = process.env.BW_VOICE_APPLICATION_ID;
const BW_NUMBER = process.env.BW_NUMBER;
const USER_NUMBER = process.env.USER_NUMBER;
const BASE_CALLBACK_URL = process.env.BASE_CALLBACK_URL;
const config = new Configuration({
BW_USERNAME,
BW_PASSWORD
});
const callsApi = new CallsApi(config);
const callBody = {
applicationId: BW_VOICE_APPLICATION_ID,
to: USER_NUMBER,
from: BW_NUMBER,
displayName: 'NodeJS SDK',
answerUrl: `${BASE_CALLBACK_URL}/callbacks/answer`,
answerMethod: CallbackMethodEnum.Post,
disconnectUrl: `${BASE_CALLBACK_URL}/callbacks/disconnect`,
disconnectMethod: CallbackMethodEnum.Get,
callTimeout: 30.0,
callbackTimeout: 15.0
};
const { status, data } = await callsApi.createCall(BW_ACCOUNT_ID, callBody);
import os
import bandwidth
from pprint import pprint
configuration = bandwidth.Configuration(
username=os.environ["BW_USERNAME"],
password=os.environ["BW_PASSWORD"]
)
with bandwidth.ApiClient(configuration) as api_client:
api_instance = bandwidth.CallsApi(api_client)
account_id = os.environ["BW_ACCOUNT_ID"]
create_call = bandwidth.CreateCall(
to=os.environ["USER_NUMBER"],
var_from=os.environ["BW_NUMBER"],
answer_url=os.environ["VOICE_CALLBACK_URL"],
application_id=os.environ["BW_VOICE_APPLICATION_ID"],
)
try:
api_response = api_instance.create_call(account_id, create_call)
print("The response of CallsApi->create_call:\n")
pprint(api_response)
except Exception as e:
print("Exception when calling CallsApi->create_call: %s\n" % e)
require "vendor/autoload.php";
$BW_USERNAME = getenv("BW_USERNAME");
$BW_PASSWORD = getenv("BW_PASSWORD");
$BW_ACCOUNT_ID = getenv("BW_ACCOUNT_ID");
$BW_VOICE_APPLICATION_ID = getenv("BW_VOICE_APPLICATION_ID");
$BW_NUMBER = getenv("BW_NUMBER");
$USER_NUMBER = getenv("USER_NUMBER");
$VOICE_CALLBACK_URL = getenv("VOICE_CALLBACK_URL");
$config = new BandwidthLib\Configuration(
array(
'voiceBasicAuthUserName' => $BW_USERNAME,
'voiceBasicAuthPassword' => $BW_PASSWORD,
)
);
$client = new BandwidthLib\BandwidthClient($config);
$voiceClient = $client->getVoice()->getClient();
$body = new BandwidthLib\Voice\Models\CreateCallRequest();
$body->from = $BW_NUMBER;
$body->to = $USER_NUMBER;
$body->answerUrl = $VOICE_CALLBACK_URL;
$body->applicationId = $BW_VOICE_APPLICATION_ID;
#remember to add auth for your application if needed!
try {
$response = $voiceClient->createCall($BW_ACCOUNT_ID, $body);
print_r($response->getResult()->callId);
} catch (BandwidthLib\APIException $e) {
print_r($e->getResponseCode());
}
These are the two primary ways you may have implemented TwiML into your platform, and based on those options, here's how that pathway would look like to Bandwidth:
-
With Twilio, you can place an outbound call with a URL that contains your TwiML. The same is true for Bandwidth, where the answerUrl expects BXML to continue the call with your chosen action.
-
With Twilio, you can also place an outbound call and directly specify your TwiML. However, this is not possible with Bandwidth, but your answerUrl can contain all your equivalent BXML actions.
How to transfer a call
In this example, we will show you the process of refactoring your code to migrate your existing application from Twilio to Bandwidth. All it takes is changing just a few lines of code to transfer a call.
Twilio:
- Java
- C#
- Ruby
- NodeJS
- Python
- PHP
import com.twilio.twiml.voice.Dial;
import com.twilio.twiml.VoiceResponse;
import com.twilio.twiml.voice.Say;
import com.twilio.twiml.TwiMLException;
public class Example {
public static void main(String[] args) {
Dial dial = new Dial.Builder("415-123-4567").build();
Say say = new Say.Builder("Goodbye").build();
VoiceResponse response = new VoiceResponse.Builder().dial(dial)
.say(say).build();
try {
System.out.println(response.toXml());
} catch (TwiMLException e) {
e.printStackTrace();
}
}
}
using System;
using Twilio.TwiML;
using Twilio.TwiML.Voice;
class Example
{
static void Main(string[] args)
{
var response = new VoiceResponse();
response.Dial(415-123-4567);
response.Say(Goodbye);
Console.WriteLine(response.ToString());
}
}
require 'twilio-ruby'
response = Twilio::TwiML::VoiceResponse.new
response.dial(number: '415-123-4567')
response.say(message: 'Goodbye')
puts response
const VoiceResponse = require('twilio').twiml.VoiceResponse;
const response = new VoiceResponse();
response.dial('415-123-4567');
response.say('Goodbye');
console.log(response.toString());
from twilio.twiml.voice_response import Dial, VoiceResponse, Say
response = VoiceResponse()
response.dial('415-123-4567')
response.say('Goodbye')
print(response)
<?php
require_once './vendor/autoload.php';
use Twilio\TwiML\VoiceResponse;
$response = new VoiceResponse();
$response->dial('415-123-4567');
$response->say('Goodbye');
echo $response;
Bandwidth:
This shows how to use Bandwidth XML to transfer a phone call with a pre-transfer announcement.
- XML
- Java
- C#
- Ruby
- NodeJS
- Python
- PHP
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Transfer transferCallerId="+15555555555">
<PhoneNumber transferAnswerUrl="/announcement">+15555555554</PhoneNumber>
</Transfer>
</Response>
> The announcement endpoint response from `/announcement` is:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<SpeakSentence>Hey! There's a customer on the line.</SpeakSentence>
</Response>
@Post /incoming_calls endpoint
public String transfer_to_bob() {
PhoneNumber phoneNumber = new PhoneNumber("+15555555554").builder()
.transferAnswerUrl("/announcement")
.build();
Transfer transfer = new Transfer().builder()
.transferCallerId("+15555555555")
.destinations(List.Of(phoneNumber))
.build();
Response response = new Response()
.with(transfer);
System.out.println(response.toBXML());
return response.toBXML();
}
@POST /announcement endpoint
public byte[] alert() {
SpeakSentence speakSentence = new SpeakSentence("Hey! There's a customer on the line.");
Response response = new Response()
.with(speakSentence);
System.out.println(response.toBXML());
return response.toBXML();
}
@Post [/incoming_calls]
public ActionResult transfer_to_bob() {
PhoneNumber phoneNumber = new PhoneNumber
{
Number = "+15555555554",
TransferAnswerUrl = "/announcement"
};
Transfer transfer = new Transfer
{
TransferCallerId = "+15555555555",
PhoneNumbers = new PhoneNumber[] { phoneNumber }
};
Response response = new Response();
response.Add(transfer);
Console.WriteLine(response.ToBXML());
return new OkObjectResult(response.ToBXML());
}
@Post [/announcement]
public ActionResult alert() {
SpeakSentence speakSentence = new SpeakSentence
{
Sentence = "Hey! There's a customer on the line.",
};
Response response = new Response();
response.Add(speakSentence);
Console.WriteLine(response.ToBXML());
return new OkObjectResult(response.ToBXML());
}
post '/incoming_calls' do
phone_number = Bandwidth::Bxml::PhoneNumber.new('+15555555554', { transfer_answer_url: '/announcement' })
transfer = Bandwidth::Bxml::Transfer.new([phone_number], { transfer_caller_id: '+15555555555' })
response = Bandwidth::Bxml::Response.new([transfer])
return response.to_bxml
end
post '/announcement' do
speak_sentence = Bandwidth::Bxml::SpeakSentence.new("Hey! There's a customer on the line.")
response = Bandwidth::Bxml::Response.new([speak_sentence])
return response.to_bxml
end
@POST ['/incoming_calls'] (req, res) => {
const phoneNumber = new Bxml.PhoneNumber('+15555555554', {
transferAnswerUrl: '/announcement'
});
const transfer = new Bxml.Transfer(
{
transferCallerId: "+15555555555"
},
[phoneNumber]
);
const response = new Bxml.Response(transfer);
console.log(response.toBxml());
res.status(200).send(response.toBxml());
}
@POST ['/announcement'] (req, res) => {
const speakSentence = new Bxml.SpeakSentence("Hey! There's a customer on the line.");
const response = new Bxml.Response(speakSentence);
console.log(response.toBxml());
res.status(200).send(response.toBxml());
}
@POST '/incoming_calls'
def transfer_to_bob():
phone_number = PhoneNumber(
number="+15555555554",
transfer_answer_url="/announcement"
)
transfer = Transfer(
transfer_caller_id="+15555555555",
phone_numbers=[phone_number]
)
response = Response()
response.add_verb(transfer)
print(response.to_bxml())
return response.to_bxml()
@POST '/announcement'
def alert():
speak_sentence = SpeakSentence(
text="Hey! There's a customer on the line."
)
response = Response()
response.add_verb(speak_sentence)
print(response.to_bxml())
return response.to_bxml()
@POST('/incoming_calls)
function transfer_to_bob(Request $request, Response $response) {
$number = new BandwidthLib\Voice\Bxml\PhoneNumber("+15555555554");
$transfer = new BandwidthLib\Voice\Bxml\Transfer();
$transfer->transferCallerId("+15555555555");
$transfer->phoneNumbers(array($number));
$response = new BandwidthLib\Voice\Bxml\Response();
$response->addVerb($transfer);
echo $response->toBxml();
$bxml = $bxmlResponse->toBxml();
$response = $response->withStatus(200)->withHeader('Content-Type', 'application/xml');
$response->getBody()->write($bxml);
return $response;
}
@POST('/announcement)
function alert(Request $request, Response $response) {
$speakSentence = new BandwidthLib\Voice\Bxml\SpeakSentence("Hey! There's a customer on the line.");
$response = new BandwidthLib\Voice\Bxml\Response();
$response->addVerb($speakSentence);
$response = $response->withStatus(200)->withHeader('Content-Type', 'application/xml');
$response->getBody()->write($response->toBxml());
return $response;
}
Twilio uses the <Dial>
verb in TwiML to connect the current caller to another party during an active call. For Bandwidth the equivalent function is <Bridge>
.
How to use text-to-speech
In this example, we will show you the process of refactoring your code to migrate your existing application from Twilio to Bandwidth for utilizing text-to-speech for outbound calls.
Twilio:
- Java
- C#
- Ruby
- NodeJS
- Python
- PHP
import com.twilio.twiml.VoiceResponse;
import com.twilio.twiml.voice.Say;
import com.twilio.twiml.TwiMLException;
public class Example {
public static void main(String[] args) {
Say say = new Say.Builder("Chapeau!").voice(Say.Voice.WOMAN)
.language(Say.Language.FR_FR).build();
VoiceResponse response = new VoiceResponse.Builder().say(say).build();
try {
System.out.println(response.toXml());
} catch (TwiMLException e) {
e.printStackTrace();
}
}
}
using System;
using Twilio.TwiML;
using Twilio.TwiML.Voice;
class Example
{
static void Main()
{
var response = new VoiceResponse();
response.Say("Chapeau!", voice: "woman", language: "fr-FR");
Console.WriteLine(response.ToString());
}
}
require 'twilio-ruby'
response = Twilio::TwiML::VoiceResponse.new
response.say(voice: 'woman', language: 'fr-FR', message: 'Chapeau!')
puts response
const VoiceResponse = require('twilio').twiml.VoiceResponse;
const response = new VoiceResponse();
response.say(
{
voice: 'woman',
language: 'fr-FR'
},
'Chapeau!'
);
console.log(response.toString());
from twilio.twiml.voice_response import VoiceResponse, Say
response = VoiceResponse()
response.say('Chapeau!', voice='woman', language='fr-FR')
print(response)
<?php
require_once './vendor/autoload.php';
use Twilio\TwiML\VoiceResponse;
$response = new VoiceResponse();
$response->say('Chapeau!', ['voice' => 'woman', 'language' => 'fr-FR']);
echo $response;
Bandwidth:
- XML
- Java
- C#
- Ruby
- NodeJS
- Python
- PHP
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<SpeakSentence voice="julie">
This is a test.
</SpeakSentence>
</Response>
SpeakSentence speakSentence = new SpeakSentence("This is a test.").builder()
.voice("julie")
.build();
Response response = Response()
.with(speakSentence);
System.out.println(response.toBXML());
SpeakSentence speakSentence = new SpeakSentence
{
Sentence = "This is a test.",
Voice = "julie"
};
Response response = new Response();
response.Add(speakSentence);
Console.WriteLine(response.ToBXML());
speak_sentence = Bandwidth::Bxml::SpeakSentence.new('This is a test.', { voice: 'julie' })
response = Bandwidth::Bxml::Response.new([speak_sentence])
p response.to_bxml
const speakSentence = new Bxml.SpeakSentence('This is a test.', {
voice: 'julie'
});
const response = new Bxml.Response(speakSentence);
console.log(response.toBxml());
speak_sentence = SpeakSentence(
text="This is a test.",
voice="julie"
)
response = Response()
response.add_verb(speak_sentence)
print(response.to_bxml())
$speakSentence = new BandwidthLib\Voice\Bxml\SpeakSentence("This is a test.");
$speakSentence->voice("julie");
$response = new BandwidthLib\Voice\Bxml\Response();
$response->addVerb($speakSentence);
echo $response->toBxml();
With Twilio, the <Say>
verb in TwiML is used for converting text-to-speech that is then read back to the caller. For Bandwidth the equivalent function is <SpeakSentence>
.
Additionally, Bandwidth uses Amazon Polly for text-to-speech services with the support of SSML tags. So if you are using Amazon Polly as your text-to-speech provider in Twilio, you can discover the same speaker voice here.
Where to next?
Now that you have seen how easy and comparable Twilio's API is to Bandwidth, check out our in-depth guides to continue to build out your application:
- How to play media and perform text-to-speech
- How to record calls & transcribe
- How to gather user input (IVR)
- How to use voicemail detection
- How to create conference calls
- How to retrieve call logs
Need additional help?
Our Bandwidth Signature Support is included for free for every customer. Our support comes with a 24/7 Network Operations Center (NOC), Technical Assistance Center (TAC), and a clear path of escalation. We are here for you when you need actual human support that a forum can't cover.
Porting your numbers from Twilio to Bandwidth
Whether you are purchasing new phone numbers to use with Bandwidth or looking to keep your existing phone numbers purchased from Twilio, the process couldn't be easier.
You can port your numbers from Twilio to Bandwidth without devoting any downtime by following a few simple steps in our Porting Numbers guide.
Other API features
Bandwidth has comparable APIs to Twilio fo`r SMS, WebRTC calling, Video, Multi-factor Authentication, Phone Numbers, and 911 Access, all on our own network, providing you with additional cost savings.
Discover our other services today.