Voice
Whether building a UCaaS solution, modernizing a legacy IVR, augmenting CX with AI, or migrating from another provider's APIs, our comprehensive technical references and guides have you covered.
Try it out
- SWML
- cXML
- Relay Realtime SDK (Server)
- Call Flow Builder
SWML
version: 1.0.0
sections:
main:
- record_call:
format: mp3
direction: "both"
cXML
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Record/>
</Response>
Relay Realtime SDK (Server)
import { SignalWire } from "@signalwire/realtime-api";
const client = await SignalWire({ project: "PROJECT_ID", token: "AUTH_TOKEN" })
const voiceClient = client.voice;
// Setup a voice client to listen for incoming calls
await voiceClient.listen({
topics: ['office'],
onCallReceived: async (call) => {
// Answer the call
call.answer();
// Record the call
call.recordAudio({
format: "mp3",
direction: "both"
});
}
});
Call Flow Builder
- SWML
- Relay Realtime SDK (Server)
- Call Flow Builder
- cXML
SWML
version: 1.0.0
sections:
main:
- connect:
from: "%{call.from}"
to: "+1XXXXXXXXXX"
Relay Realtime SDK (Server)
import { SignalWire, Voice} from "@signalwire/realtime-api";
const client = await SignalWire({ project: "ProjectID Here", token: "Token Here" })
const voiceClient = client.voice;
await voiceClient.listen({
topics: ["office"],
onCallReceived: async (call) => {
// Answer the call
call.answer();
// Connect the call to the device builder plan
let peer = await call.connectPhone({
// Replace the to parameter with a valid phone number
to: "+1XXXXXXXXXX",
from: call.from
});
// wait for peer to hangup
await peer.disconnected();
// hangup the call
call.hangup();
}
});
Call Flow Builder
cXML
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial callerId="{{From}}">+1XXXXXXXXXX</Dial>
</Response>
- Relay Realtime SDK (Server)
- REST
Relay Realtime SDK (Server)
import { SignalWire } from "@signalwire/realtime-api";
const client = await SignalWire({ project: "ProjectID Here", token: "Token Here" })
const voiceClient = client.voice;
try {
// Outbound Dial
const call = await voiceClient.dialPhone({
from: "+1XXXXXXXXXX",
to: "+1YYYYYYYYY",
timeout: 30
});
// Answering machine detection
await call.detectAnsweringMachine({
waitForBeep: true,
endSilenceTimeout: 4,
listen: {
onEnded: async (event) => {
console.log("Answering machine detection ended:", event.result);
}
}
});
} catch (e) {
console.log("Call not answered.", e);
}
REST
curl https://example.signalwire.com/api/laml/2010-04-01/Accounts/{AccountSid}/Calls.json \
-X POST \
--data-urlencode "Url=http://your-application.com/docs/voice.xml" \
--data-urlencode "To=+1YYYYYYYYY" \
--data-urlencode "From=+1XXXXXXXXXX" \
--data-urlencode "MachineDetection=DetectMessageEnd" \
--data-urlencode "MachineDetectionTimeout=45" \
--data-urlencode "AsyncAmd=true" \
--data-urlencode "AsyncAmdStatusCallback=https://your-api-endpoint.com/path" \
--data-urlencode "AsyncAmdStatusCallbackMethod=POST" \
-u "YourProjectID:YourAuthToken"
- SWML
- cXML
- Relay Realtime SDK (Server)
- Call Flow Builder
SWML
version: 1.0.0
sections:
main:
- answer: {}
- play:
urls:
- >-
say:Thank you for calling SignalWire!
Please listen closely to the options in order to direct your call.
- prompt:
play: >-
say:Press 1 to talk to sales, Press 2 to talk to Support, Press 3 to
talk to a Customer Representative
say_language: en-US
max_digits: 1
speech_hints:
- one
- two
- three
- switch:
variable: prompt_value
case:
'1':
- execute:
dest: sales
'2':
- execute:
dest: support
'3':
- execute:
dest: customer
one:
- execute:
dest: sales
two:
- execute:
dest: support
three:
- execute:
dest: customer
default:
- execute:
dest: sales
sales:
- play:
url: 'say:You have reached sales'
- connect:
to: +1XXXXXXXXXX
support:
- play:
url: 'say:You have reached support'
- connect:
to: +1YYYYYYYYYY
customer:
- play:
url: 'say:You have reached a Customer representative'
- connect:
to: +1ZZZZZZZZZZ
cXML
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>
Thank you for calling SignalWire!
Please listen closely to the options in order to direct your call.
</Say>
<!-- The action attribute is the URL of the webhook that will be called when the user presses a key. -->
<Gather action="https://example.com/IVR" input="dtmf" method="GET" timeout="3">
<Say>If you'd like to connect to our Sales team, press 1</Say>
<Say>If you'd like to connect to our Support Engineering Team, press 2</Say>
<Say>If you'd like to connect to our Customer Representative, press 3</Say>
</Gather>
</Response>
Relay Realtime SDK (Server)
import { SignalWire } from "@signalwire/realtime-api";
const client = await SignalWire({ project: "b08dacad-2f6c-4de1-93d6-cc732e0c69c5", token: "PT16d2254f1cf1be0766881a2043afe8ef9e2fc8e8f739750b" })
const voiceClient = client.voice;
// Setup a voice client to listen for incoming calls
await voiceClient.listen({
topics: ['office'],
onCallReceived: async (call) => {
// Answer the call
call.answer();
await call.playTTS({
text: "Thank you for calling SignalWire! Please listen closely to the options in order to direct your call.",
});
await handlePromptTTS(call);
}
})
async function handlePromptTTS(call) {
await call.promptTTS({
text: "Press 1 to talk to sales, Press 2 to talk to Support, Press 3 to talk to a Customer Representative",
digits: {
max: 1,
digitTimeout: 5,
},
listen: {
onEnded: async (prompt) => {
const digits = prompt.digits;
if (digits === "1") {
await connectCall(call, "sales", "+1XXXXXXXXXX");
}
else if (digits === "2") {
await connectCall(call, "support", "+1YYYYYYYYY");
}
else if (digits === "3") {
await connectCall(call, "a customer representative", "+1ZZZZZZZZZZ");
}
else {
await call.playTTS({
text: "Invalid option. Please try again.",
});
handlePromptTTS(call);
}
}
}
});
}
async function connectCall(call, destination, toNumber) {
await call.playTTS({
text: `Connecting you to ${destination}`,
});
let peer = await call.connectPhone({
from: call.from,
to: toNumber,
timeout: 30
});
await peer.disconnected();
call.hangup();
}
Call Flow Builder
- SWML
- cXML
- Relay Realtime SDK (Server)
- Call Flow Builder
SWML
version: 1.0.0
sections:
main:
- record_call:
format: mp3
direction: "both"
cXML
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Record/>
</Response>
Relay Realtime SDK (Server)
import { SignalWire } from "@signalwire/realtime-api";
const client = await SignalWire({ project: "PROJECT_ID", token: "AUTH_TOKEN" })
const voiceClient = client.voice;
// Setup a voice client to listen for incoming calls
await voiceClient.listen({
topics: ['office'],
onCallReceived: async (call) => {
// Answer the call
call.answer();
// Record the call
call.recordAudio({
format: "mp3",
direction: "both"
});
}
});
Call Flow Builder
- SWML
- Relay Realtime SDK (Server)
- Call Flow Builder
- cXML
SWML
version: 1.0.0
sections:
main:
- connect:
from: "%{call.from}"
to: "+1XXXXXXXXXX"
Relay Realtime SDK (Server)
import { SignalWire, Voice} from "@signalwire/realtime-api";
const client = await SignalWire({ project: "ProjectID Here", token: "Token Here" })
const voiceClient = client.voice;
await voiceClient.listen({
topics: ["office"],
onCallReceived: async (call) => {
// Answer the call
call.answer();
// Connect the call to the device builder plan
let peer = await call.connectPhone({
// Replace the to parameter with a valid phone number
to: "+1XXXXXXXXXX",
from: call.from
});
// wait for peer to hangup
await peer.disconnected();
// hangup the call
call.hangup();
}
});
Call Flow Builder
cXML
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial callerId="{{From}}">+1XXXXXXXXXX</Dial>
</Response>
- Relay Realtime SDK (Server)
- REST
Relay Realtime SDK (Server)
import { SignalWire } from "@signalwire/realtime-api";
const client = await SignalWire({ project: "ProjectID Here", token: "Token Here" })
const voiceClient = client.voice;
try {
// Outbound Dial
const call = await voiceClient.dialPhone({
from: "+1XXXXXXXXXX",
to: "+1YYYYYYYYY",
timeout: 30
});
// Answering machine detection
await call.detectAnsweringMachine({
waitForBeep: true,
endSilenceTimeout: 4,
listen: {
onEnded: async (event) => {
console.log("Answering machine detection ended:", event.result);
}
}
});
} catch (e) {
console.log("Call not answered.", e);
}
REST
curl https://example.signalwire.com/api/laml/2010-04-01/Accounts/{AccountSid}/Calls.json \
-X POST \
--data-urlencode "Url=http://your-application.com/docs/voice.xml" \
--data-urlencode "To=+1YYYYYYYYY" \
--data-urlencode "From=+1XXXXXXXXXX" \
--data-urlencode "MachineDetection=DetectMessageEnd" \
--data-urlencode "MachineDetectionTimeout=45" \
--data-urlencode "AsyncAmd=true" \
--data-urlencode "AsyncAmdStatusCallback=https://your-api-endpoint.com/path" \
--data-urlencode "AsyncAmdStatusCallbackMethod=POST" \
-u "YourProjectID:YourAuthToken"
- SWML
- cXML
- Relay Realtime SDK (Server)
- Call Flow Builder
SWML
version: 1.0.0
sections:
main:
- answer: {}
- play:
urls:
- >-
say:Thank you for calling SignalWire!
Please listen closely to the options in order to direct your call.
- prompt:
play: >-
say:Press 1 to talk to sales, Press 2 to talk to Support, Press 3 to
talk to a Customer Representative
say_language: en-US
max_digits: 1
speech_hints:
- one
- two
- three
- switch:
variable: prompt_value
case:
'1':
- execute:
dest: sales
'2':
- execute:
dest: support
'3':
- execute:
dest: customer
one:
- execute:
dest: sales
two:
- execute:
dest: support
three:
- execute:
dest: customer
default:
- execute:
dest: sales
sales:
- play:
url: 'say:You have reached sales'
- connect:
to: +1XXXXXXXXXX
support:
- play:
url: 'say:You have reached support'
- connect:
to: +1YYYYYYYYYY
customer:
- play:
url: 'say:You have reached a Customer representative'
- connect:
to: +1ZZZZZZZZZZ
cXML
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>
Thank you for calling SignalWire!
Please listen closely to the options in order to direct your call.
</Say>
<!-- The action attribute is the URL of the webhook that will be called when the user presses a key. -->
<Gather action="https://example.com/IVR" input="dtmf" method="GET" timeout="3">
<Say>If you'd like to connect to our Sales team, press 1</Say>
<Say>If you'd like to connect to our Support Engineering Team, press 2</Say>
<Say>If you'd like to connect to our Customer Representative, press 3</Say>
</Gather>
</Response>
Relay Realtime SDK (Server)
import { SignalWire } from "@signalwire/realtime-api";
const client = await SignalWire({ project: "b08dacad-2f6c-4de1-93d6-cc732e0c69c5", token: "PT16d2254f1cf1be0766881a2043afe8ef9e2fc8e8f739750b" })
const voiceClient = client.voice;
// Setup a voice client to listen for incoming calls
await voiceClient.listen({
topics: ['office'],
onCallReceived: async (call) => {
// Answer the call
call.answer();
await call.playTTS({
text: "Thank you for calling SignalWire! Please listen closely to the options in order to direct your call.",
});
await handlePromptTTS(call);
}
})
async function handlePromptTTS(call) {
await call.promptTTS({
text: "Press 1 to talk to sales, Press 2 to talk to Support, Press 3 to talk to a Customer Representative",
digits: {
max: 1,
digitTimeout: 5,
},
listen: {
onEnded: async (prompt) => {
const digits = prompt.digits;
if (digits === "1") {
await connectCall(call, "sales", "+1XXXXXXXXXX");
}
else if (digits === "2") {
await connectCall(call, "support", "+1YYYYYYYYY");
}
else if (digits === "3") {
await connectCall(call, "a customer representative", "+1ZZZZZZZZZZ");
}
else {
await call.playTTS({
text: "Invalid option. Please try again.",
});
handlePromptTTS(call);
}
}
}
});
}
async function connectCall(call, destination, toNumber) {
await call.playTTS({
text: `Connecting you to ${destination}`,
});
let peer = await call.connectPhone({
from: call.from,
to: toNumber,
timeout: 30
});
await peer.disconnected();
call.hangup();
}
Call Flow Builder
- SWML
- cXML
- Relay Realtime SDK (Server)
- Call Flow Builder
SWML
version: 1.0.0
sections:
main:
- record_call:
format: mp3
direction: "both"
cXML
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Record/>
</Response>
Relay Realtime SDK (Server)
import { SignalWire } from "@signalwire/realtime-api";
const client = await SignalWire({ project: "PROJECT_ID", token: "AUTH_TOKEN" })
const voiceClient = client.voice;
// Setup a voice client to listen for incoming calls
await voiceClient.listen({
topics: ['office'],
onCallReceived: async (call) => {
// Answer the call
call.answer();
// Record the call
call.recordAudio({
format: "mp3",
direction: "both"
});
}
});
Call Flow Builder
Get started
Buy a phone number
SignalWire phone numbers in the Dashboard
Quickstart with AI
Deploy a serverless voice AI Agent and call it over the PSTN in under 5 minutes with SWML
Make your first phone calls
The fundamentals of your first calling app
Migrate a Twilio application
Get started with our Compatibility API
No-code apps with Call Flow Builder
Create a drag-and-drop calling application
Choose an API
SignalWire's advanced APIs and elastic cloud infrastructure make it a breeze to build modern and powerful voice applications using both PSTN and SIP endpoints.
- SignalWire REST API: A robust, modern and flexible API for building integrated, advanced communications applications.
- Compatibility API: Ideal for porting code from other providers. It can run serverless, but it also supports Python, PHP, Node.js, and other languages.
- Realtime API: This API is ideal if you are an advanced developer and you want flexible, modern and realtime SDKs for Node.js.
SignalWire API
High-quality, scalable, and secure voice API
Compatibility API & cXML
Easily migrate from Twilio and other providers
RELAY Realtime Server SDK
Next-gen server telephony applications powered by our RELAY WebSocket API
RELAY Browser SDK
Bring telephone capabilities to the browser with our Node.js SDK
Low-code and no-code solutions
Call Flow Builder
Drag-and-drop, no-code call application builder
SWML
Write realtime, AI-integrated calling applications using simple JSON or YAML scripts
Popular guides
SIP trunking
Route SIP traffic through the SignalWire platform to your PBX system.
Answering machine detection
Setup AMD using our Compatibility API and Node.js.
Build an Interactive Voice Response (IVR) System
Learn how to build an IVR with Node.js.
Setting Up a SIP Endpoint
This guide will show how you can create a SIP endpoint and register it to a phone number for handling incoming calls.
Getting Started with SIP
Guides that focus on the basic setup for SIP calling.