Navbar
Logo icon Name

What is LaML?

Simple LaML document example

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say>Welcome to SignalWire!</Say>
</Response>

LaML is the language used by SignalWire to determine how the phone numbers in your account react during calls or text messages. When a call or message comes into one of your SignalWire phone numbers, SignalWire makes an HTTP request to the URL endpoint you configured for that number. Your response to that request instructs SignalWire on what to do next.

Responses to the HTTP request are in an XML format we call LaML. LaML allows you to specify instructions using simple LaML commands called verbs. SignalWire starts at the top of your LaML document and executes your LaML commands in order, from top to bottom.

How LaML works

When an message or call is received by one of your SignalWire phone numbers, SignalWire lookup the URL endpoint you configured for that phone number and make an HTTP request to it. The URL endpoint then responds to the request with a LaML document that determines what to do next.

SignalWire will read the instructions in the LaML document, from top to bottom, and execute the commands in order.

You can generate and respond with raw XML yourself, or utilize one of the SignalWire helper libraries to help you generate it easily.

Outbound calls and messages started via the LaML REST API are controlled the same way. When you start an outbound call or message, you also pass a link to a LaML document. SignalWire will make a request to this document to determine how it should proceed with the call or message.

While a single LaML document is executed at a time, many documents can be linked together and generated dynamically to create complex applications to fit any need.

LaML Syntax

<?xml version="1.0" encoding="UTF-8"?>
<!-- All responses must contain the Response element -->
<Response>
  <!-- Say and Dial are examples of Verbs -->
  <Say>Connecting you...</Say>
  <Dial>
    <!-- Number is an example of a Dial Noun -->
    <Number>+15551234567</Number>
  </Dial>
</Response>

LaML is XML-based and consists of the following elements:

  • the <Response> element -- tag defining the body of the LaML document
  • verb -- an XML tag denoting the action that you want SignalWire to take
  • noun -- the item for the action specified in the associated verb

Response Element

The root element of all LaML documents is a <Response> tag. All messaging verbs in a document must be nested within a single <Response> element, and each document can only have a single one.

Empty Response

Empty response example

<?xml version="1.0" encoding="UTF-8"?>
<Response></Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()
<?php
  use SignalWire\LaML;
  $response = new LaML;
?>
using Twilio.TwiML;
using Twilio.TwiML.Voice;
using System;

class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
    }
}
from signalwire.voice_response import VoiceResponse

response = VoiceResponse()

require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new

puts response.to_s

When an incoming SMS, MMS, or call to a SignalWire phone number is received, SignalWire will automatically respond with the proper LaML directions to handle those incoming messages. Even if no actions are required to handle these messages, a <Response> must be used. To receive incoming messaging without requiring further actions, respond with <Response></Response>.

Verbs

A verb identifies the action to take.

Verbs are executed sequentially, so one instruction must complete fully before the next one is executed. Some verbs have optional attributes that can override the flow of execution, allowing you to dynamically change what happens based on events within the call.

All verbs are case sensitive, so calling <ThisAction> is different from calling <thisaction>.

Voice Verbs

The following verbs cause the specified action to take place during the call:

Verb Action
<Dial> Initiates a call to another phone number.
<Gather> Collects input from the remote number, either as pressed digits or as speech.
<Play> Plays an audio file in the call.
<Record> Records and saves the audio in the call.
<Say> Reads the supplied text into the call.

The following verbs control what happens to the call itself:

Verb Action
<Enqueue> Place the call into a queue.
<Hangup> Disconnect the call.
<Leave> Remove the call from the queue it is currently in.
<Pause> Wait before continuing to execute further instructions.
<Redirect> Stop executing the instructions in this LaML document, and start executing those in another specified document.
<Reject> Decline an incoming call. Rejected calls will not be billed.

Messaging Verbs

The following verbs are used to manage messages and responses:

Verb Action
<Message> Sends a message to another phone number.
<Redirect> Stop executing the instructions in this LaML document, and start executing those in another specified document.

Nouns

An example of using a <Conference> noun within a <Dial> verb:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Dial>
    <Conference>my-example-conference</Conference>
  </Dial>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

dial = response.dial()
dial.conference('my-example-conference')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $dial = $response->dial();
  $dial->conference('my-example-conference');
  echo $response;
?>
using Twilio.TwiML;
using Twilio.TwiML.Voice;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        var dial = new Dial();
        dial.Conference("my-example-conference");
        response.Append(dial);

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Dial, Conference

response = VoiceResponse()
dial = Dial()
dial.conference('my-example-conference')
response.append(dial)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.dial do |dial|
    dial.conference('my-example-conference')
  end
end

puts response.to_s

A noun is what the verb uses to complete its action. Placed inside a verb tab, it can be the text that is read in a call, or other XML or LaML elements that represent the target of the action, such as Conference or Number.

Each verb has its own set of supported nouns. See the documentation for a specific verb for more details.

Data Formats

Dates and Times

All dates and times in requests to and from SignalWire LaML API are UTC, and presented in RFC 2822 format.

For example, the date and time of 8:01 AM CDT on July 23rd, 2018 is presented as: Mon, 23 Jul 2018 13:01:00 +0000

Phone Numbers

All phone numbers in requests to or from the SignalWire LaML API are in E.164 format, an unambiguous general format for specifying international phone numbers. Numbers in this format start with a plus sign ("+") and the country code.

For example, a US-based phone number like (555) 123-4567 would be formatted like: +15551234567.

If a number cannot be represented in E.164 format, then SignalWire uses the raw Caller ID string that was received.

Voice LaML

Voice LaML is a set of actions defined in an XML document you can use to tell SignalWire what to do when you receive an incoming call or instructions for outbound calls.

Overview

When a call is made to one of your SignalWire phone numbers, SignalWire looks up the Voice LaML document from the URL you configured, and reads the instructions you provided to determine what to do.

Voice LaML allows you to dynamically control what happens, responding with specific instructions based on the caller, time of day, incoming call, and much more.

Request for LaML

SignalWire makes an HTTP request to your configured endpoint just like a regular web form submission (POST) or page load (GET). The request includes contextual information about the call, allowing you to respond dynamically and fluidly to the call to meet the needs of your application.

You can configure the endpoint URL and HTTP Method in your phone number settings panel on your SignalWire dashboard, or via the REST API.

Request Parameters

SignalWire sends the following parameters, as either URL query parameters or POST parameters, to your endpoint when it receives a call:

Parameter
CallSid string A unique identifier for the call. May be used to later retrieve this message from the REST API.
AccountSid string The unique ID of the Account this call is associated with.
From string The phone number that sent this call, in E.164 format.
To string The phone number of the call recipient, in E.164 format.
CallStatus string The status of the call. Can be one of the following values: ringing, in-progress, queued, failed, busy, no-answer, or completed.
ApiVersion string The version of the SignalWire API. Incoming calls use the API version placed on the number called. Outgoing calls use the version of the REST API request.
Direction string An identifier to describe the direction of the call:
outbound-dial: calls launched through the <Dial> verb
outbound-api: calls launched through the REST API
inbound: for inbound calls
ParentCallSid string A unique identifier for the call that created this call.

CallStatus Values

The following are the possible CallStatus parameter values. These are also used in <Dial>'s DialCallStatus:

Value
ringing The call is ringing.
in-progress The call was answered and is in progress.
queued The call is ready and in line to initiate.
failed The call could not be completed. Usually occurs when phone number does not exist.
busy The caller encountered a busy signal.
no-answer The call ended without an answer.
completed The call was answered and ended normally.
canceled The REST API canceled the call while it was ringing or queued.

Responding to SignalWire

An example of a LaML document that reads a message to the caller before playing an audio file.

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Say>Hello, World!</Say>
    <Play>https://your-application.com/audio.mp3</Play>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.say('Hello, World!')
response.play('https://your-application.com/audio.mp3')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->say('Hello, World!');
  $response->play('https://your-application.com/audio.mp3');
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Say("Hello, World!");
        response.Play(new Uri("https://your-application.com/audio.mp3"));

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Say, Play

response = VoiceResponse()
response.say('Hello, World!')
response.play('https://your-application.com/audio.mp3')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.say(message: 'Hello World!')
  response.play(url: 'https://your-application.com/audio.mp3')
end

puts response.to_s

When a message comes into one of your SignalWire phone numbers, SignalWire makes an HTTP request to the URL endpoint you configured for that number. Your response to that request instructs SignalWire on what to do next.

Responses to the HTTP request are in LaML. SignalWire starts at the top of your LaML document and executes your LaML commands in order, from top to bottom.

Status Callbacks

SignalWire can send your application callbacks at various lifecycle stages of your call. Status callbacks do not allow you change the application execution directly, so callbacks do not have to respond with LaML, but they allow your application to get updates as a call is happening.

You should respond to any callbacks with a 200 OK or 204 No Content, otherwise you will see failures in your application log on SignalWire.

The StatusCallback request contains the Standard Request Parameters plus the following optional parameters:

Parameter
CallDuration integer The duration, in seconds, of the call that was just completed.
RecordingUrl string The URL of the phone call's recorded audio. Only included if Record is set to true.
RecordingSid string The unique ID of the Recording of the call.
RecordingDuration integer The duration, in seconds, of the recorded audio.

<Dial>

The <Dial> verb connects an existing call to another phone number. <Dial> will end this new call if: the called number does not answer, the number does not exist, or SignalWire receives a busy signal.

Verb Attributes

Attribute
action optional The action attribute takes in an absolute URL. SignalWire will make a GET or POST request to this URL after the dialed call ends. If no action is provided, SignalWire will continue to the next verb in the document. SignalWire will end the call if there are no more verbs following the <Dial> verb in the document. See below for request parameters.
answerOnBridge optional If set to true, the inbound call will ring until the number that was dialed answers the call. If the inbound call is a SIP call, SignalWire will send a 180 or 183 to your SIP server as soon as it connects to SignalWire. When the <Dial> call is connected, a 200 will be sent. Default value is false.
callerId optional The inbound caller's phone number, which is displayed to the number that was dialed. The caller ID must be a valid E.164 number.
hangupOnStar optional The initiator of the call can hangup on the dialed number by using the * key. Default value is false.
method optional The method attribute specifies whether the request to action is a GET or a POST. Valid values are GET or POST, default value is POST.
record optional The record attribute allows the ability to record both legs of a call. Recordings are available as mono-channel or dual-channel. See below for a detailed explanation of these channels. Default value is do-not-record.
recordingStatusCallback optional The recordingStatusCallback attribute takes in an absolute or relative URL. SignalWire will make a GET or POST request to this URL when recording is available. Default value is POST. See below for request parameters.
recordingStatusCallbackEvent optional Specifies which status value should be connected to the recordingStatusCallback URL. Available values are: in-progress: the recording has begun; failed: the recording is unavailable because of a failure; completed: the recording is completed and accessible . Default value is completed and failed.
ringTone optional The ability to change the ringback tone played to the caller when dialing a number. Default value is the ringback tone from the carrier. Available values are the following ISO 3166-1 alpha-2 country codes: at, au, bg, br, be, ch, cl, cn, cz, de, dk, ee, es, fi, fr, gr, hu, il, in, it, lt, jp, mx, my, nl, no, nz, ph, pl, pt, ru, se, sg, th, uk, us, us-old, tw, ve, za.
timeLimit optional Maximum duration, in seconds, for a <Dial>. Default value is 4 hours.
timeout optional The time, in seconds, that SignalWire will wait for a call to be answered before setting the status of the call to no-answer. Default is 30 seconds. Minimum value is 5 seconds and maximum value is 600 seconds.
trim optional Whether or not silence in the beginning and end of recordings are removed. Use trim-silence to achieve this behavior. Default value is do-not-trim.



The action URL request contains the Standard Request Parameters as well as:

Parameter
DialCallStatus string The status of the dialed call attempt. See below for status values.
DialCallSid string The unique identifier of the new call leg.
DialCallDuration integer The duration, in seconds, of the dialed call.
RecordingUrl string The URL of the recorded audio file. This parameter is only present if record is set on a <Dial>.



The DialCallStatus parameter of the action attribute can be one of the following values:

Value
completed The number that was dialed answered the call and was successfully connected to the caller.
answered When calling to a conference, the number that was dialed answered the call and was successfully connected to the caller.
busy SignalWire received a busy signal when connecting to the dialed number.
no-answer The number that was dialed did not answer the call in time.
failed SignalWire was unable to connect to the dialed number. This usually occurs when the dialed number does not exist.
canceled The call was canceled through a REST API before it was answered.

record Channels

The record attribute allows for recordings in mono-channel or dual-channel:

  • mono-channel: both legs of a call are combined into one channel in one recording file
    • record-from-answer: starts the recording when the call is answered
    • record-from-ringing: starts the recording when ringing begins
  • dual-channel: both legs of a call use separate channels in one recording file
    • record-from-answer-dual: starts the recording when the call is answered
    • record-from-ringing-dial: starts the recording when ringing begins



The recordingStatusCallback request contains the Standard Request Parameters as well as:

Parameter
AccountSid string The unique ID of the Account this call is associated with.
CallSid string A unique identifier for the call. Always refers to the initial caller.
RecordingSid string The unique identifier for the recording.
RecordingUrl string The URL for the audio recording.
RecordingStatus string The status of the recording. Possible values are: in-progress, completed, failed.
RecordingDuration integer The duration, in seconds, of the recording.
RecordingChannels integer The number of channels in the recording. Can be 1 or 2.
RecordingSource string The type of call that initiated the recording.

Nouns

The noun of a LaML verb is nested within the verb upon which the verb acts. <Dial> has the following nouns:

Noun
<Conference> A conference call between two or more callers.
<Number> A phone number with additional attributes.
<Queue> A line for callers to wait in. The current call will be connected to the call at the front of the queue.

<Conference>

<Dial> verb's <Conference> noun permits the connection to a named conference room.

Noun Attributes

Attribute
muted optional Whether or not a caller can speak in a conference. Default is false.
beep optional Whether or not a sound is played when callers leave or enter a conference. Default is true. See below for all possible values.
startConferenceOnEnter optional The conference begins once a specific caller enters into the conference room, unless it has already started. If a participant joins and startConferenceOnEnter is false, that participant will hear background music and stay muted until a participant with startConferenceOnEnter set to true joins the call. Default is true.
endConferenceOnExit optional If a participant with endConferenceOnExit set to true leaves a conference, the conference terminates and all participants drop out of the call. Default is false.
waitUrl optional URL for the music to play in the background while participants are waiting to enter a conference room. Only supports <Play>, <Pause>, and <Redirect>. If no waitUrl is provided, SignalWire will use its hold music.
waitUrlMethod optional Specifies whether the request to waitUrl is a GET or a POST. The default value is POST.
maxParticipants optional The maximum number of participants allowed in a named conference room.
record optional Can be used to record an entire <Conference>. record-from-start will begin recording the conference call once the first two participants join in on the call. Wait music is not recorded. Default is do-not-record.
trim optional Whether or not silence in the beginning and end of recordings are removed. Default value trim-silence follows this behavior.
statusCallbackEvent optional Specifies conference state changes. The first participant to join the named conference is able to manipulate and set events. All other changes made by other participants will be ignored. See below for all possible events.
statusCallback optional The URL to make requests to for each statusCallbackEvent event. The URL is set by the first participant to enter a conference. All other information provided by other participants will be ignored. See below for request parameters.
statusCallbackMethod optional The type of HTTP request to use when requesting a statusCallback. Default is POST.
recordingStatusCallback optional The recordingStatusCallback attribute takes in an absolute URL. SignalWire will make a GET or POST request to this URL when recording is accessible. See below for request parameters.
recordingStatusCallbackMethod optional The type of HTTP request to use when requesting a recordingStatusCallback. Default is POST.
recordingStatusCallbackEvent optional Specifies recording status changes. To specify multiple values, separate them by a space. Default is completed and failed. See below for details.
eventCallbackUrl optional The 'eventCallbackUrl' attribute takes a URL as an argument and makes a POST request to it when a conference ends.



The beep attribute has the following values:

Value
true Plays a beep when a caller leaves or enters a conference. The default value for beep.
false Disables the beep when callers leave and enter conferences.
onEnter Only plays a beep when a caller enters a conference.
onExit Only plays a beep when a caller leaves a conference.



The statusCallbackEvent attribute has the following events:

Event
start The conference has started as long as there are at least two people in the conference room and one of the participant's startConferenceOnEnter is set to true.
end The conference ends when the last participant in the call or a participant with endConferenceOnExit set to true leaves the call.
join When a participant joins a conference.
leave When a participant leaves a conference.
mute When a participant has been muted or un-muted.
hold When a participant has been put on hold or put out of hold.
speaker When a participant has begun or stopped speaking.



The statusCallback request contains the Standard Request Parameters as well as:

Parameter
ConferenceSid string A unique identifier for the named Conference.
FriendlyName string Name of the conference.
AccountSid string A unique identifier for the Account this call is associated with.
Timestamp string The timestamp, in RFC 2822 format, of when an event occurred.
StatusCallbackEvent string Conference state changes. Possible events are: conference-end, conference-start, participant-leave, participant-join, participant-mute, participant-unmute, participant-hold, participant-unhold, participant-speech-start, participant-speech-stop.
CallSid string A unique identifier for the call.
Muted string Whether a participant is muted or not.
Hold string Whether a participant is on hold or not.
EndConferenceOnExit string When a participant has this set on true and they leave a call, conference ends.
StartConferenceOnEnter string When a participant has this set on true and they join a call, conference begins.
EventName string The name of the event.
RecordingUrl string The URL of the recorded audio file.
Duration integer The time, in seconds, of the conference call.
RecordingFileSize string The size of the recorded audio file.



The recordingStatusCallback request contains the Standard Request Parameters as well as:

Parameter
AccountSid string A unique identifier for the Account this recording is associated with.
ConferenceSid string A unique identifier for the Conference this recording is associated with.
RecordingSid string The unique identifier for the recording.
RecordingUrl string The URL for the audio recording.
RecordingStatus string The status of the recording. Possible values are: in-progress, complete, failed.
RecordingDuration integer The duration, in seconds, of the recording.
RecordingChannels integer The number of channels in the recording. Only 1 channel is supported for conference recordings.
RecordingSource string The type of call that initiated the recording.



The recordingStatusCallbackEvent attribute has the following status values:

Value
in-progress The recording has begun.
completed The recording has completed and is accessible.
failed The recording is not accessible because of a failure.

<Conference> Examples

A Simple Conference Call

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Dial>
    <Conference>Room 1234</Conference>
  </Dial>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

dial = response.dial()
dial.conference('Room 1234')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $dial = $response->dial();
  $dial->conference('Room 1234');
  echo $response;
?>
using Twilio.TwiML;
using Twilio.TwiML.Voice;
using System;

class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        var dial = new Dial();
        dial.Conference("Room 1234");

        response.Append(dial);
        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Dial, Conference

response = VoiceResponse()
dial = Dial()
dial.conference('Room 1234')
response.append(dial)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.dial do |dial|
    dial.conference('Room 1234')
  end
end

puts response.to_s

The first participant would join the conference "Room 1234" and listen to wait music in the background until a second participant joins the conference. Once participants have joined the conference, the wait music comes to an end, a beep is played, and the conference call begins.

A Moderated Conference Call

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Dial>
    <Conference startConferenceOnEnter="false">
      moderated-conference-room
    </Conference>
  </Dial>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

dial = response.dial()
dial.conference('moderated-conference-room', { startConferenceOnEnter: false })
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $dial = $response->dial();
  $dial->conference('moderated-conference-room', array( 'startConferenceOnEnter' => false ));
  echo $response;
?>
using Twilio.TwiML;
using Twilio.TwiML.Voice;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        var dial = new Dial();
        dial.Conference("moderated-conference-room",
            startConferenceOnEnter: false);

        response.Append(dial);
        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Dial, Conference

response = VoiceResponse()
dial = Dial()
dial.conference('moderated-conference-room', start_conference_on_enter=False)
response.append(dial)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.dial do |dial|
    dial.conference('moderated-conference-room', start_conference_on_enter: false)
  end
end

puts response.to_s

You can set the startConferenceOnEnter to false so that a group of participants can join in the conference room but the conference cannot begin until the moderator has entered the call. As the participants wait for the conference to begin, hold music will be playing in the background.

Start A Moderated Conference Call

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Dial>
    <Conference startConferenceOnEnter="true" endConferenceOnExit="true">
      moderated-conference-room
    </Conference>
  </Dial>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

dial = response.dial()
dial.conference('moderated-conference-room', { startConferenceOnEnter: true, endConferenceOnExit: true })
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $dial = $response->dial();
  $dial->conference('moderated-conference-room', array(
    'startConferenceOnEnter' => true,
    'endConferenceOnExit' => true )
  );
  echo $response;
?>
using Twilio.TwiML;
using Twilio.TwiML.Voice;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        var dial = new Dial();
        dial.Conference("moderated-conference-room",
            startConferenceOnEnter: true, endConferenceOnExit: true);

        response.Append(dial);
        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Dial, Conference

response = VoiceResponse()
dial = Dial()
dial.conference('moderated-conference-room', start_conference_on_enter=True, end_conference_on_exit=True)
response.append(dial)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.dial do |dial|
    dial.conference('moderated-conference-room', start_conference_on_enter: true, end_conference_on_exit: false)
  end
end

puts response.to_s

Now, since the moderator has joined in on the conference call, startConferenceOnEnter is set to true which means the conference can begin. All the participants that were waiting on hold will now be connected to the conference room; the hold music will come to an end and a beep notification will play indicating conference entrance. Once the moderator leaves the call, the conference will come to an end and all participants will be disconnected from the call.

Joining a Conference Call Muted

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Dial>
    <Conference muted="true">ConferenceRoom</Conference>
  </Dial>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

dial = response.dial()
dial.conference({ muted: true }, 'ConferenceRoom')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $dial = $response->dial();
  $dial->conference('ConferenceRoom', array( 'muted' => true ));
  echo $response;
?>
using Twilio.TwiML;
using Twilio.TwiML.Voice;

class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        var dial = new Dial();
        dial.Conference("ConferenceRoom", muted: true);

        response.Append(dial);
        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Dial, Conference

response = VoiceResponse()
dial = Dial()
dial.conference('ConferenceRoom', muted=True)
response.append(dial)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.dial do |dial|
    dial.conference('ConferenceRoom', muted: true)
  end
end

puts response.to_s

Participants who enter a conference call muted can hear the other participants in the call who are un-muted. However, the un-muted participants cannot hear the muted callers. Muting and un-muting can be enable and disabled in real-time via a REST API.

Recording a Conference Call

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Dial>
    <Conference record="record-from-start"
                recordingStatusCallback="https://www.example.com/recording_update">
      ConferenceCall
    </Conference>
  </Dial>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

dial = response.dial()
dial.conference('ConferenceCall', { record: 'record-from-start', recordingStatusCallback: 'https://www.example.com/recording_update' })
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $dial = $response->dial();
  $dial->conference('ConferenceCall', array(
    'record' => 'record-from-start',
    'recordingStatusCallback' => 'https://www.example.com/recording_update' )
  );
  echo $response;
?>
using Twilio.TwiML;
using Twilio.TwiML.Voice;
using System;

class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        var dial = new Dial();
        dial.Conference("ConferenceCall", record: "record-from-start",
            recordingStatusCallback: new Uri("https://www.example.com/recording_update"));

        response.Append(dial);
        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Dial, Conference

response = VoiceResponse()
dial = Dial()
dial.conference('ConferenceCall', record='record-from-start', recording_status_callback='https://www.example.com/recording_update')
response.append(dial)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.dial do |dial|
    dial.conference('ConferenceCall', record: record-from-start, recording_status_callback: 'https://www.example.com/recording_update')
  end
end

puts response.to_s

The recording of the conference call will begin when at least two participants join the conference room. A recordingStatusCallback will be sent when the recording is accessible.

Notes On Usage

  • You can freely name the conference room to fit your preference. However, only callers within a project can join in on a named conference room. Callers from separate projects will not be able to connect to that same conference room.
  • You can customize the background music as callers are waiting to join a conference call
  • Conferences will not begin unless there are 2 or more parties present.

<Number>

<Dial> verb's <Number> noun specifies what phone number to dial. You can use up to 10 <Number>s within a <Dial> to simultaneously call several people. The first person to answer the call will be connected to the caller and the rest of the called numbers will be hung up.

Noun Attributes

Attribute
sendDigits optional Play DTMF tones when a call is answered. Useful when dialing numbers with extensions. SignalWire will initially dial the main phone number, then send the DTMF tones for the extension when the automated system answers.
url optional A specified URL for a document that runs on the caller's end after the dialed number answers but before the call is connected. This allows the caller to provide information to the dialed number, giving them the opportunity to decline the call, before they answer the call.
method optional The method attribute specifies whether the request to action is a GET or a POST. Valid values are GET or POST, default value is POST.
statusCallbackEvent optional The current status of the call. The call moves from initiated to ringing when the phone starts ringing. It moves from ringing to answered when the phone call is answered. Finally, it moves from answered to completed when the call is terminated. The status will be set to completed through the following reasons: busy, canceled, completed, failed, or no-answer. To specify multiple events, separate each one with a space. See below for the different call statuses.
statusCallback optional The URL to make requests to for each statusCallbackEvent event. See below for request parameters.
statusCallbackMethod optional The type of HTTP request to use when requesting a statusCallback. Default is POST.



The statusCallbackEvent attribute has the following call status values:

Value
initiated Dialing of a call has begun.
ringing The call has begun ringing.
answered The call has been answered.
completed The call has been terminated. The status will be set to completed through the following reasons: busy, canceled, completed, failed, or no-answer.



The statusCallback request contains the Standard Request Parameters as well as:

Parameter
CallSid string A unique identifier for the call.
ParentCallSid string A unique identifier for the parent call.
CallStatus string The current status of the call. Can be one of the following values: queued, initiated, ringing, in-progress, busy, failed, or no-answer.
CallDuration integer A duration, in seconds, of the finished call.
RecordingUrl string The URL for the audio recording of the call. Only present when CallStatus is completed.
RecordingSid string The unique identifier for the recording of the call. Only present when CallStatus is completed.
RecordingDuration integer The duration, in seconds, of the recorded audio of the call. Only present when CallStatus is completed.
Timestamp string The timestamp, in RFC 2822 format, of when an event occurred.
CallbackSource string The source of the call connection.

<Number> Examples

Dialing an Extension

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Dial>
        <Number sendDigits="www5645">
            123-456-7890
        </Number>
    </Dial>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

dial = response.dial()
dial.number({ sendDigits: 'www5645' }, '123-456-7890')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $dial = $response->dial();
  $dial->number('123-456-7890', array( 'sendDigits' => 'www5645' ));
  echo $response;
?>
using System;
using Twilio.TwiML;
using Twilio.TwiML.Voice;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        var dial = new Dial();
        dial.Number("123-456-7890", sendDigits: "www5645");

        response.Append(dial);
        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Dial, Number

response = VoiceResponse()
dial = Dial()
dial.number('123-456-7890', send_digits='www5645')
response.append(dial)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.dial do |dial|
    dial.number('123-456-7890', send_digits: 'www5645')
  end
end

puts response.to_s

After entering the phone number, we want to wait a little before entering in the extension. In order to do this, a w can be placed in front of the extension number. Each w will wait 0.5 seconds before dialing the extension. In this example, SignalWire will wait 1.5 seconds before dialing the extension 5645.

Concurrent Phone Calls

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Dial>
        <Number>123-456-7890</Number>
        <Number>987-654-3210</Number>
        <Number>102-938-4750</Number>
    </Dial>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

dial = response.dial()
dial.number('123-456-7890')
dial.number('987-654-3210')
dial.number('102-938-4750')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $dial = $response->dial();
  $dial->number('123-456-7890');
  $dial->number('987-654-3210');
  $dial->number('102-938-4750');
  echo $response;
?>
using Twilio.TwiML;
using Twilio.TwiML.Voice;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        var dial = new Dial();
        dial.Number("123-456-7890");
        dial.Number("987-654-3210");
        dial.Number("102-938-4750");

        response.Append(dial);
        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Dial, Number

response = VoiceResponse()
dial = Dial()
dial.number('123-456-7890')
dial.number('987-654-3210')
dial.number('102-938-4750')
response.append(dial)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.dial do |dial|
    dial.number('123-456-7890')
    dial.number('987-654-3210')
    dial.number('102-938-4750')
  end
end

puts response.to_s

You can simultaneously call up to 10 <Number>s. The first caller to pick up the phone will be connected to the caller and the rest of the called numbers will be hung up.

Notes on Usage

  • You can have up to 10 <Number>s within a <Dial>.
  • If you dial an office number or a phone on airplane mode, the call will be picked up within the first ring and all other calls will be hung up.

<Queue>

<Dial> verb's <Queue> noun specifies what queue to dial.

Noun Attributes

Attribute
url optional A specified URL for a document that runs on the caller's end before the call is connected. This allows the caller to inform the dialed number that the call will be connected to an agent or that the call may be monitored or recorded. See below for request parameters.
method optional The method attribute specifies whether the request to action is a GET or a POST. Valid values are GET or POST, default value is POST.



The url request contains the Standard Request Parameters as well as:

Parameter
QueueSid string The unique identifier for the Queue.
CallSid string The unique identifier for the dequeued call.
QueueTime string The time, in seconds, spent waiting in a queue.
DequeingCallSid string The unique identifier for the call dequeueing the caller.

<Queue> Examples

Dialing a Queue

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Dial>
        <Queue url="https://example.com/about_to_connect.xml">support</Queue>
    </Dial>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

dial = response.dial()
dial.queue({ url: 'https://example.com/about_to_connect.xml' }, 'support')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $dial = $response->dial();
  $dial->queue('support', array( 'url' => 'https://example.com/about_to_connect.xml' ));
  echo $response;
?>
using Twilio.TwiML;
using Twilio.TwiML.Voice;
using System;

class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        var dial = new Dial();
        dial.Queue("support", url: new Uri("https://example.com/about_to_connect.xml"));

        response.Append(dial);
        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Dial, Queue

response = VoiceResponse()
dial = Dial()
dial.queue('support', url='https://example.com/about_to_connect.xml')
response.append(dial)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.dial do |dial|
    dial.queue('support', url: 'https://example.com/about_to_connect.xml')
  end
end

puts response.to_s

This is an example of a caller in the 'support' queue waiting to be dequeued.

Bridging Out of a Queue

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Say>You will now be connected to an agent.</Say>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.say('You will now be connected to an agent.')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->say('You will now be connected to an agent.');
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Say("You will now be connected to an agent.");

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Say

response = VoiceResponse()
response.say('You will now be connected to an agent.')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.say(message: 'You will now be connected to an agent.')
end

puts response.to_s

Once a caller is first in line in the queue and ready to be bridged, they will be informed of the connection to an agent.

Examples

A Simple Dial

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Dial>123-456-7890</Dial>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.dial('123-456-7890')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->dial('123-456-7890');
  echo $response;
?>
using Twilio.TwiML;
using System;

class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Dial("123-456-7890");

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Dial

response = VoiceResponse()
response.dial('123-456-7890')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.dial('123-456-7890')
end

puts response.to_s

If the dialed number answers the call, the two parties can talk to each other until one of them hangs up the phone.

Dial a Number from a SignalWire Client

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Dial callerId="+18007778899">
        <Number>+18004445566</Number>
    </Dial>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

dial = response.dial({ callerId: '+18007778899' })
dial.number('+18004445566')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $dial = $response->dial(array( 'callerId' => '+18007778899' ));
  $dial->number('+18004445566');
  echo $response;
?>
using Twilio.TwiML;
using Twilio.TwiML.Voice;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        var dial = new Dial(callerId: "+18007778899");
        dial.Number("+18004445566");
        response.Append(dial);

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Dial, Number

response = VoiceResponse()
dial = Dial(caller_id='+18007778899')
dial.number('+18004445566')
response.append(dial)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.dial(caller_id: '+18007778899') do |dial|
    dial.number('+18004445566')
  end
end

puts response.to_s

In order to dial from a SignalWire client, you need to make sure you are inputting a valid phone number. If the number in the callerID is not valid, the call will fail.

Mono-Channel Recording

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Dial record="record-from-ringing"
          recordingStatusCallback="https://example.com/recording_status">
        <Number>+10123456789</Number>
    </Dial>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

dial = response.dial({ record: 'record-from-ringing', recordingStatusCallback: 'https://example.com/recording_status' })
dial.number('+10123456789')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $dial = $response->dial(array(
    'record' => 'record-from-ringing',
    'recordingStatusCallback' => 'https://example.com/recording_status' )
  );
  $dial->number('+10123456789');
  echo $response;
?>
using Twilio.TwiML;
using Twilio.TwiML.Voice;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        var dial = new Dial(record: "record-from-ringing",
            recordingStatusCallback: new Uri("https://example.com/recording_status"));
        dial.Number("+10123456789");
        response.Append(dial);

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Dial, Number

response = VoiceResponse()
dial = Dial(record='record-from-ringing', recording_status_callback='https://example.com/recording_status')
dial.number('+10123456789')
response.append(dial)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.dial(record: 'record-from-ringing', recording_status_callback: 'https://example.com/recording_status') do |dial|
    dial.number('+10123456789')
  end
end

puts response.to_s

With mono-channel recording, each participant in the call will be recorded on the same channel. The recording will then be stored in a single recording file. Since we have set record to record-from-ringing, the recording will begin when the phone starts to ring.

Dual-Channel Recording for a Conference Call

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Dial record="record-from-ringing-dual"
          recordingStatusCallback="https://example.com/recording_status">
        <Conference>teamcall</Conference>
    </Dial>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

dial = response.dial({ record: 'record-from-ringing-dual', recordingStatusCallback: 'https://example.com/recording_status' })
dial.conference('teamcall')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $dial = $response->dial(array(
    'record' => 'record-from-ringing-dual',
    'recordingStatusCallback' => 'https://example.com/recording_status' )
  );
  $dial->conference('teamcall');
  echo $response;
?>
using Twilio.TwiML;
using Twilio.TwiML.Voice;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        var dial = new Dial(record: "record-from-ringing-dual",
            recordingStatusCallback: new Uri("https://example.com/recording_status"));
        dial.Conference("teamcall");
        response.Append(dial);

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Dial, Conference

response = VoiceResponse()
dial = Dial(record='record-from-ringing-dual', recording_status_callback='https://example.com/recording_status')
dial.conference('teamcall')
response.append(dial)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.dial(record: 'record-from-ringing-dual', recording_status_callback: 'https://example.com/recording_status') do |dial|
    dial.conference('teamcall')
  end
end

puts response.to_s

This example connects the caller to the conference call, teamcall. With dual-channel recording, each participant in the call will be recorded in a separate channel. The recording will then be stored in a single recording file. Since we have set record to record-from-ringing-dual, the recording will begin when the phone starts to ring.

<Enqueue>

The <Enqueue> verb places a call in a specified call queue. If the specified queue does not exist, a new queue will be created and the call will be placed into that new queue. Calls can be dequeued through the <Dial> verb or removed from the queue through the <Leave> verb.

Verb Attributes

Attribute
action optional The action attribute takes a absolute URL. When a call leaves the queue, a request to this URL is made. If a call is dequeued through the <Leave> verb, the URL is immediately requested. If the call has been bridged to another party via the <Dial> verb, then the HTTP request is made only after both parties have disconnected. If action is not provided, SignalWire will continue reading the next verb in the document. See below for specified request parameters.
method optional Specifies whether the redirect is a GET or a POST. Default value is POST.
waitUrl optional URL of the document to execute while the caller is in the queue. Default points to a playlist with classical music. waitUrl supports the following verbs: <Play>, <Say>, <Pause>, <Hangup>, <Redirect>, <Leave>, and <Gather>. See below for specified request parameters.
waitUrlMethod optional Specifies whether the request to waitUrl is a GET or a POST. The default value is POST.



The action request contains the Standard Request Parameters as well as:

Parameter
QueueResult string The result of the queued call. See below for all possible values.
QueueSid string The unique ID of the queue. Only available if a call is successfully placed into a queue.
QueueTime string The time a call was waiting in a queue. Only available if a call is successfully placed into a queue.



The parameter QueueResult has the following values:

Value
bridged The call was bridged and removed from the queue.
bridging-in-progress SignalWire is instructed to bridge the call.
error An error occurred either through the <Enqueue> verb or through the document retrieved from the waitUrl.
hangup The caller hung up while still in the queue.
leave The caller left the queue through the <Leave> verb.
redirected The call was redirected out of the queue, through a REST API request, while the caller was in the queue.
redirected-from-bridged The queued and bridged session was transferred out.
queue-full The queue was full, so the placement into the queue was not accepted.
system-error SignalWire had a malfunction while placing a call into a queue.



The waitUrl request contains the Standard Request Parameters as well as:

Parameter
QueuePosition integer The current position in the queue.
QueueSid string The unique ID of the queue a caller is in.
QueueTime integer The time a call was waiting in a queue.
AvgQueueTime integer The average time, in seconds, that callers have been waiting in a queue.
CurrentQueueSize integer The current number of callers in a queue.

Nouns

The noun of a LaML verb is nested within the verb upon which the verb acts. <Enqueue> has the following nouns:

Noun
plain text The name of a specific queue.

Nesting

No other verbs can be nested within <Enqueue> and you cannot nest
<Enqueue> within any other verbs.

Examples

A Simple Enqueue

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Enqueue waitUrl="https://example.com/hold-music.xml">support</Enqueue>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.enqueue({ waitUrl: 'https://example.com/hold-music.xml' }, 'support')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->enqueue('support', array( 'waitUrl' => 'https://example.com/hold-music.xml' ));
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Enqueue("support", waitUrl: new Uri("https://example.com/hold-music.xml"));

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Enqueue

response = VoiceResponse()
response.enqueue('support', wait_url='https://example.com/hold-music.xml')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.enqueue(name: 'support', wait_url: 'https://example.com/hold-music.xml')
end

puts response.to_s

While a caller is in the queue, SignalWire retrieves the LaML document 'hold-music.xml' and executes it.

Playing Wait Music

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Play>http://your-application.com/classical.mp3</Play>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.play('http://your-application.com/classical.mp3')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->play('http://your-application.com/classical.mp3');
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Play(new Uri("http://your-application.com/classical.mp3"));

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Play

response = VoiceResponse()
response.play('http://your-application.com/classical.mp3')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.play(url: 'http://your-application.com/classical.mp3')
end

puts response.to_s

While callers in a queue are waiting, classical music is played.

<Gather>

The <Gather> verb transcribes speech or collects digits during a call.

Verb Attributes

Attribute
action optional The action attribute takes in an absolute URL. SignalWire will make a GET or POST request to this URL when entering of digits is completed. If there is no URL provided, SignalWire will re-request the URL that was previously used, which can cause an unwanted looping behavior. Be sure to provide the proper URL in order to avoid this outcome. See below for specified request parameters.
finishOnKey optional The set of digits, (0-9, *, #), that can end a recording. Default is #.
hints optional A list of words and phrases, each a max of 100 characters, a caller is likely to say during a call.
input optional The type of input received from a caller (i.e. speech or DTMF). Values can be dtmf, speech, or dtmf speech. Default is dtmf.
language optional The language in which you expect your callers to speak. Default is en-US.
method optional The method attribute specifies whether the request to action is a GET or a POST. Valid values are GET or POST, default value is POST.
numDigits optional The number of digits you expect to be pressed by a caller.
partialResultCallback optional The URL to request to during speech recognition. No URL is specified by default.
partialResultCallbackMethod optional The type of HTTP request to use when requesting a partialResultCallback. Default is POST.
profanityFilter optional Tells SignalWire whether or not to filter profane language when transcribing a call. Default is true.
speechTimeout optional The set time, in seconds, that SignalWire will wait before ending speech recognition. If set to auto, SignalWire will automatically end speech recognition when there is a pause in speech.
timeout optional The number of seconds of silence or inaction that denote the end of caller input. Default is 5 seconds.



The action request contains the Standard Request Parameters as well as:

Parameter
Confidence string The score, between 0.0 and 1.0, that determines the accuracy of a transcription.
SpeechResult string The transcribed result of the caller's speech.
Digits string The buttons pressed by a caller.

Nesting

The following verbs can be nested within a <Gather>:

  • <Play>: plays an audio file, that SignalWire fetches from the URL you configured, back to the caller.
  • <Pause>: waits silently for a distinctive number of seconds.
  • <Say>: reads supplied text back to the caller.

Examples

A Simple Gather

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Gather/>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.gather()
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->gather();
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Gather();

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Gather

response = VoiceResponse()
response.gather()

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.gather
end

puts response.to_s

SignalWire will collect any speech or digits pressed during a call.

Nesting Within a Gather

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Gather action="https://example.com/process_gather.php" method="GET">
        <Say>
            Please enter your account number,
            followed by the pound sign.
        </Say>
    </Gather>
    <Say>We did not receive any input. Goodbye!</Say>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

gather = response.gather({ action: 'https://example.com/process_gather.php', method: 'GET' })
gather.say('Please enter your account number, followed by the pound sign.')
response.say('We did not receive any input. Goodbye!')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $gather = $response->gather(array(
    'action' => 'https://example.com/process_gather.php',
    'method' => 'GET'
  ));
  $gather->say('Please enter your account number, followed by the pound sign.');
  $response->say('We did not receive any input. Goodbye!');
  echo $response;
?>
using Twilio.TwiML;
using Twilio.Http;
using Twilio.TwiML.Voice;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        var gather = new Gather(action: new Uri("https://example.com/process_gather.php"), method: HttpMethod.Get);
        gather.Say("Please enter your account number, followed by the pound sign.");

        response.Append(gather);
        response.Say("We did not receive any input. Goodbye!");

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Gather, Say

response = VoiceResponse()
gather = Gather(action='https://example.com/process_gather.php', method='GET')
gather.say('Please enter your account number, followed by the pound sign.')
response.append(gather)
response.say('We did not receive any input. Goodbye!')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.gather(action: 'https://example.com/process_gather.php', method: 'GET') do |gather|
    gather.say(message: 'Please enter your account number, followed by the pound sign.')
  end
  response.say(message: 'We did not receive any input. Goodbye!')
end

puts response.to_s

You can use the <Say> verb to prompt callers to enter the desired input. In this example, when a caller enters their account number, SignalWire will submit the result to the URL provided in the action attribute. If the caller does not enter any digits, SignalWire will prompt the 'Goodbye' statement.

Gather DTMF or Speech

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Gather input="speech dtmf" timeout="5" numDigits="1">
        <Say>Please press 3 or say account for account information.</Say>
    </Gather>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

gather = response.gather({ input: 'speech dtmf', timeout: 5, numDigits: 1 })
gather.say('Please press 3 or say account for account information.')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $gather = $response->gather(array(
    'input' => 'speech dtmf',
    'timeout' => 5,
    'numDigits' => 1
  ));
  $gather->say('Please press 3 or say account for account information.');
  echo $response;
?>
using Twilio.TwiML;
using Twilio.TwiML.Voice;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        var gather = new Gather(input: "speech dtmf", timeout: 5, numDigits: 1);
        gather.Say("Please press 3 or say account for account information.");

        response.Append(gather);
        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Gather, Say

response = VoiceResponse()
gather = Gather(input='speech dtmf', timeout=5, num_digits=1)
gather.say('Please press 3 or say account for account information.')
response.append(gather)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.gather(input: 'speech dtmf', timeout: 5, num_digits: 1) do |gather|
    gather.say(message: 'Please press 3 or say account for account information.')
  end
end

puts response.to_s

A caller can access their account information either through speech recognition or DTMF tones. SignalWire will wait 5 seconds before processing the information and sending the data.

Potential Issues

<Gather> doesn't receive caller input when the caller is using a VoIP phone.

Solution: Some VoIP phones have trouble sending DTMF tones. Phones typically use compressed bandwidth-conserving audio protocols that can interfere with the transmission of the digit's signal.

The Digits parameter is not sent to the <Gather> URL.

Solution: Verify that your application is not responding to the action URL with an HTTP 3xx redirect. SignalWire will follow this redirect but will not resend the Digits parameter.

<Hangup>

The <Hangup> verb ends a call. While <Reject>ed calls are never answered, calls that use the <Hangup> verb for disconnection are still answered, becoming subject to billing.

Verb Attributes

The <Hangup> verb does not support any attributes.

Nesting

No other verbs can be nested within <Hangup> and you cannot nest <Hangup> within any other verbs.

Examples

A Simple Hangup

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Hangup/>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.hangup()
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->hangup();
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Hangup();

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Hangup

response = VoiceResponse()
response.hangup()

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.hangup
end

puts response.to_s

SignalWire will answer the call then immediately hangup.

<Leave>

The <Leave> verb transfers a call out of the queue containing that call. It then returns the flow of execution to verb following the <Enqueue> that placed this call into the queue.

Verb Attributes

The <Leave> verb does not support any attributes.

Examples

Leaving a Closed Queue

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Enqueue waitUrl="https://example.com/wait.xml">support</Enqueue>
    <Say>Customer support is now closed. Please call back on the next business day. Thank you.</Say>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.enqueue({ waitUrl: 'https://example.com/hold-music.xml' }, 'support')
response.say('Customer support is now closed. Please call back on the next business day. Thank you.')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->enqueue('support', array( 'waitUrl' => 'https://example.com/wait.xml' ));
  $response->say('Customer support is now closed. Please call back on the next business day. Thank you.');
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Enqueue("support", waitUrl: new Uri("https://example.com/wait.xml"));
        response.Say("Customer support is now closed. Please call back on the next business day. Thank you.");

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Enqueue, Say

response = VoiceResponse()
response.enqueue('support', wait_url='https://example.com/wait.xml')
response.say('Customer support is now closed. Please call back on the next business day. Thank you.')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.enqueue(name: 'support', wait_url: 'https://example.com/wait.xml')
  response.say(message: 'Customer support is now closed. Please call back on the next business day. Thank you.')
end

puts response.to_s

Callers who are waiting in the queue for customer support will automatically be directed out of the queue after closing hours. SignalWire will notify these callers that they have left the queue and will have to try calling back another day.

Playing Audio

<?xml version="1.0" encoding="UTF-8"?>
<Response>
     <Play>http://your-application.com/music.mp3</Play>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.play('http://your-application.com/music.mp3')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->play('http://your-application.com/music.mp3');
  echo $response;
?>
using Twilio.TwiML;
using System;

class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Play(new Uri("http://your-application.com/music.mp3"));

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Play

response = VoiceResponse()
response.play('http://your-application.com/music.mp3')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.play(url: 'http://your-application.com/music.mp3')
end

puts response.to_s

SignalWire will play hold music for the callers in the queue until customer support hours are over.

Leave a Call

<?xml version="1.0" encoding="UTF-8"?>
<Response>
     <Leave />
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.leave()
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->leave();
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Leave();

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Leave

response = VoiceResponse()
response.leave()

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.leave
end

puts response.to_s

wait.xml will dequeue the callers after closing hours and prompt the <Say> statement in the first example.

<Pause>

The <Pause> verb waits silently for a distinctive number of seconds.

Verb Attributes

Attribute
length optional The number of seconds SignalWire will pause silently before moving on. Defaults to 1s of wait time if no value is provided.

Nesting

No other verbs can be nested within <Pause>. However, <Pause> can be nested within a <Gather>.

Examples

A Simple Pause

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Say>Please wait one moment while I check that for you.</Say>
    <Pause length="8"/>
    <Say>Yes, we are open Monday through Friday.</Say>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.say('Please wait one moment while I check that for you.')
response.pause({ length: 8 })
response.say('Yes, we are open Monday through Friday.')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->say('Please wait one moment while I check that for you.');
  $response->pause(array( 'length' => 8 ));
  $response->say('Yes, we are open Monday through Friday.');
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Say("Please wait one moment while I check that for you.");
        response.Pause(length: 8);
        response.Say("Yes, we are open Monday through Friday.");

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Say, Pause

response = VoiceResponse()
response.say('Please wait one moment while I check that for you.')
response.pause(length=8)
response.say('Yes, we are open Monday through Friday.')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.say(message: 'Please wait one moment while I check that for you.')
  response.pause(length: 10)
  response.say(message: 'Yes, we are open Monday through Friday.')
end

puts response.to_s

This illustrates the wait time between two statements.

Delaying a Response

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Pause length="3"/>
    <Say>Hello, how can I help you?</Say>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.pause({ length: 3 })
response.say('Hello, how can I help you?')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->pause(array( 'length' => 3 ));
  $response->say('Hello, how can I help you?');
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Pause(length: 3);
        response.Say("Hello, how can I help you?");

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Say, Pause

response = VoiceResponse()
response.pause(length=3)
response.say('Hello, how can I help you?')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.pause(length: 3)
  response.say(message: 'Hello, how can I help you?')
end

puts response.to_s

SignalWire waits 3 seconds before answering a call.

<Play>

The <Play> verb plays an audio file, that SignalWire fetches from the URL you configured, back to the caller.

Verb Attributes

An example of an audio file set to loop 15 times.

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Play loop="15">https://your-application.com/audio.mp3</Play>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.play({ loop: 15 }, 'https://your-application.com/audio.mp3')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->play('https://your-application.com/audio.mp3', array( 'loop' => 15 ));
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Play(new Uri("https://your-application.com/audio.mp3"), loop: 15);

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Play

response = VoiceResponse()
response.play('https://your-application.com/audio.mp3', loop=15)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.play(loop: 15, url: 'https://your-application.com/audio.mp3')
end

puts response.to_s
Attribute
loop optional The loop attribute determines how many times an audio file is played. If no loop is specified, it will default to 1, which means the audio file will only play once. If loop is set to '0', <Play> will continue looping until the call has ended.
digits optional The digits attribute allows you to play DTMF tones throughout a call. If pauses are required in between your DTMF tones, the character w can be used. w adds a pause of 0.5 seconds for each occurrence, so www would render a pause of 1.5 seconds.

Note that this attribute simply plays tones into a call. To enter an extension when making a call, use the sendDigits attribute for the noun <Number> of the verb <Dial>.

Nouns

The noun of a LaML verb is nested within the verb upon which the verb acts. <Play> has the following noun:

Noun
plain text The URL of the audio file that will be played to the caller.

MIME Types

The following are the MIME types supported by SignalWire:

Type
audio/mpeg mpeg layer 3 audio
audio/wav wav format audio
audio/wave wav format audio
audio/x-wav wav format audio
audio/aiff audio interchange file format
audio/x-aifc audio interchange file format
audio/x-aiff audio interchange file format
audio/x-gsm GSM audio format
audio/gsm GSM audio format
audio/ulaw μ-law audio format

Nesting

No other verbs can be nested within <Play>. However, <Play> can be nested within <Gather>. In this case, the verb attribute digits is not supported.

Examples

Play a Simple Audio File

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Play>https://your-application.com/audio.mp3</Play>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.play('https://your-application.com/audio.mp3')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->play('https://your-application.com/audio.mp3');
  echo $response;
?>
using Twilio.TwiML;
using System;

class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Play(new Uri("https://your-application.com/audio.mp3"));

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Play

response = VoiceResponse()
response.play('https://your-application.com/audio.mp3')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.play(url: 'https://your-application.com/audio.mp3')
end

puts response.to_s

The simplest case for <Play>: SignalWire downloads the specified audio file and plays it to the caller.

Use DTMF Tones in Calls

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Play digits="wwwww9"></Play>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.play({ digits: 'wwwww9' })
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->play(array( 'digits' => 'wwwww9' ));
  echo $response;
?>
using Twilio.TwiML;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Play("", digits: "wwwww9");

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Play

response = VoiceResponse()
response.play(digits='wwwww9')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.play(digits: 'wwwww9')
end

puts response.to_s

As described in the attributes section, the character w produces a 0.5 second pause. In this example, SignalWire will wait 2.5 seconds before playing the digit '9'.

Notes on Usage

  • Audio files that are longer than 40 minutes should be split into smaller files, as it may result in a dropped call.
  • Since it takes some time to download and cache files from your server, slight delays may occur the first time an audio file is played. In this case, SignalWire may play a tone during download.
  • SignalWire attempts to cache files only when allowed by HTTP headers (ETag and Last-Modified). Always check for a new version of the file with a response of Cache-Control: no-cache. This enables your server to respond with a new version, or with a '304 Not Modified', which tells SignalWire to use the cached version.
  • The degradation that occurs when transcoding high bitrate, lossy encoded files, such as 128kbps MP3 files, can take a long time, resulting in audio that sounds worse than those in lossless 8kbps formats.
  • SignalWire transcodes all audio files into a format that is identifiable by the telephone network. Telephones typically do not support high bitrate audio, so playback results in lower-quality audio.

<Record>

The <Record> verb creates an audio file with the caller's voice and returns the URL to you. Text transcriptions of these recorded calls can also be produced.

Verb Attributes

Attribute
action optional The action attribute takes in an absolute or relative URL. SignalWire will make a GET or POST request to this URL when recording is completed. The current document's URL will be requested if no action is provided. There is no way to return to any instructions listed after the <Record> verb. See below for specified request parameters.
method optional The method attribute specifies whether the request to action is a GET or a POST. Valid values are GET or POST, default value is POST.
timeout optional The timeout attribute specifies the number of seconds of silence that ends a recording.
finishOnKey optional The set of digits, (0-9, *, #), that can end a recording.
maxLength optional The maximum length, in seconds, of the recording.
playBeep optional Whether or not a sound is played before the start of a recording. Default is true.
trim optional Whether or not silence in the beginning and end of recordings are removed. Default value trim-silence follows this behavior.
recordingStatusCallback optional The recordingStatusCallback attribute takes in an absolute or relative URL. SignalWire will make a GET or POST request to this URL when recording is accessible. See below for specified request parameters.
recordingStatusCallbackMethod optional The type of HTTP request to use when requesting a recordingStatusCallback. Default is POST.
transcribe optional The transcribe attribute identifies whether to produce a text transcription of the recording. There is an additional charge for this service, so is turned off by default.
transcribeCallback optional The ability to define a URL to which SignalWire will make a POST request to once the transcription is complete. See below for specified request parameters.



The action request contains the Standard Request Parameters as well as:

Parameter
RecordingUrl string The URL of the recorded audio file.
RecordingDuration integer The duration, in seconds, of the audio recording.
Digits string The buttons pressed to end a recording.



The recordingStatusCallback request contains the Standard Request Parameters as well as:

Parameter
AccountSid string The unique ID of the Account this call is associated with.
CallSid string A unique identifier for the call. May be used to later retrieve this message from the REST API.
RecordingSid string The unique identifier for the recording.
RecordingUrl string The URL for the audio recording.
RecordingStatus string The status of the recording.
RecordingDuration integer The duration, in seconds, of the recording.
RecordingChannels integer The number of channels in the recording.
RecordingSource string The type of call that initiated the recording.



The transcribeCallback request contains the Standard Request Parameters as well as:

Parameter
TranscriptionSid string The unique, 34 character ID of the transcription.
TranscriptionText string The text of the transcription.
TranscriptionStatus string The status of the transcription (completed or failed).
TranscriptionUrl string The URL for the transcription's REST API resource.
RecordingSid string The unique, 34 character identifier for the recording from which the transcription was generated from.
RecordingUrl string The URL for the audio recording from which the transcription was generated from.

Nesting

No other verbs can be nested within <Record> and you cannot nest
<Record> within any other verbs.

Examples

A Simple Recording

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Record/>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.record()
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->record();
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Record();

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Record

response = VoiceResponse()
response.record()

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.record
end

puts response.to_s

The caller will hear a 'beep' and the recording will begin.

Recording a Voicemail

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Say>
        Please leave a message at the beep.
        Press the pound key when finished.
    </Say>
    <Record
        action="http://your-application.com/handleRecording.php"
        method="GET"
        maxLength="15"
        finishOnKey="#"
        />
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.say('Please leave a message at the beep. Press the pound key when finished.')
response.record({ action: 'http://your-application.com/handleRecording.php', method: 'GET', maxLength: 15, finishOnKey: '#' })
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->say('Please leave a message at the beep. Press the pound key when finished.');
  $response->record(array(
    'action' => 'http://your-application.com/handleRecording.php',
    'method' => 'GET',
    'maxLength' => 15,
    'finishOnKey' => '#'
  ));
  echo $response;
?>

using Twilio.TwiML;
using Twilio.Http;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Say("Please leave a message at the beep. Press the pound key when finished.");
        response.Record(action: new Uri("http://your-application.com/handleRecording.php"),
            method: HttpMethod.Get, maxLength: 15, finishOnKey: "#");

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Record, Say

response = VoiceResponse()
response.say('Please leave a message at the beep. Press the pound key when finished.')
response.record(action='http://your-application.com/handleRecording.php', method='GET', max_length=15, finish_on_key='#')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.say(message: 'Please leave a message at the beep. Press the pound key when finished.')
  response.record(action: 'http://your-application.com/handleRecording.php', method: 'GET', max_length: 15, finish_on_key: '#')
end

puts response.to_s

This prompt will play before the 'beep', asking the caller to leave a message. The caller can only leave a message that is 15s long.

Transcribing a Recording

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Record
        transcribe="true"
        transcribeCallback="http://your-application.com/handle_transcribe.php" />
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.record({ transcribe: true, transcribeCallback: 'http://your-application.com/handle_transcribe.php' })
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->record(array(
    'transcribe' => true,
    'transcribeCallback' => 'http://your-application.com/handle_transcribe.php'
  ));
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Record(transcribe: true,
            transcribeCallback: new Uri("http://your-application.com/handle_transcribe.php"));

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Record

response = VoiceResponse()
response.record(transcribe=True, transcribe_callback='http://your-application.com/handle_transcribe.php')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.record(transcribe: true, transcribe_callback: 'http://your-application.com/handle_transcribe.php')
end

puts response.to_s

SignalWire will record the caller and transcribe the recording once it is complete. Then, SignalWire will make a POST request to the
transcribeCallback URL with the transcription as a parameter.

Notes on Usage

  • SignalWire will trim leading and trailing silence from your audio files, causing the duration of calls to be less than the time spent recording.

<Redirect>

An example that redirects next LaML instruction to another call

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Redirect>https://www.your-application.com/next-instructions</Redirect>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.redirect('https://www.your-application.com/next-instructions')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->redirect('https://www.your-application.com/next-instructions');
  echo $response;
?>
using Twilio.TwiML;
using Twilio.Http;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Redirect(new Uri("https://www.your-application.com/next-instructions"));

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Redirect

response = VoiceResponse()
response.redirect('https://www.your-application.com/next-instructions')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.redirect('https://www.your-application.com/next-instructions')
end

puts response.to_s

The <Redirect> verb transfers control from the current call to another. It is effectively an exit statement from the current call, as there is no way to return to any instructions listed after the verb.

Verb Attributes

The following attribute is available for the verb <Redirect>:

Attribute
method optional Specifies whether the redirect is a GET or a POST. Default value is POST.

Nouns

Noun
plain text The URL, in plain text, of the call to execute.

Nesting

No other verbs can be nested within <Redirect> and you cannot nest <Redirect> within any other verbs.

Examples

Redirect to absolute URL

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Dial>310-123-0000</Dial>
    <Redirect>http://www.your-application.com/next-instructions</Redirect>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.dial('310-123-0000')
response.redirect('http://www.your-application.com/next-instructions')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->dial('310-123-0000');
  $response->redirect('http://www.your-application.com/next-instructions');
  echo $response;
?>
using Twilio.TwiML;
using System;

class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Dial("310-123-0000");
        response.Redirect(new Uri("http://www.your-application.com/next-instructions"));

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Dial, Redirect

response = VoiceResponse()
response.dial('310-123-0000')
response.redirect('http://www.your-application.com/next-instructions')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.dial(number: '310-123-0000')
  response.redirect('https://www.your-application.com/next-instructions')
end

puts response.to_s

SignalWire makes a request after the number has been dialed and transfers the call to the LaML received through the request.

<Reject>

The <Reject> verb rejects a call to your SignalWire number. It is effectively an exit statement from the current document, as there is no way to return to any instructions listed after the <Reject> verb. Rejected calls to your SignalWire numbers will still charge the initial minute to your account.

Verb Attributes

Attribute
reason optional The reason attribute takes in the following values: busy and rejected. These values specify what message is to be played when SignalWire rejects a call. If this value is set to busy, the caller receives a busy signal and the call is terminated with the status busy. If this value is set to rejected, the caller receives a standard "This number is not in service" response and the call is terminated with the status no answer. Default value is rejected.

Nesting

No other verbs can be nested within <Reject> and you cannot nest <Reject> within any other verbs.

Examples

A Simple Rejection of a Call

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Reject />
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.reject()
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->reject();
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Reject();

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Reject

response = VoiceResponse()
response.reject()

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.reject
end

puts response.to_s

SignalWire will reject the call and the caller will receive a standard "This number is not in service" response.

Busy Signal Rejection

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Reject reason="busy" />
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.reject({ reason: 'busy' })
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->reject(array( 'reason' => 'busy' ));
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Reject(reason: "busy");

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Reject

response = VoiceResponse()
response.reject(reason='busy')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.reject(reason: busy)
end

puts response.to_s

SignalWire will reject the call and the caller will receive a busy signal.

<Say>

The <Say> verb reads the supplied text back to the caller. It is useful for text that is difficult to pre-record. The gender and language in which the text will be read is customizable.

Verb Attributes

Attribute
voice optional The attribute voice supports 3 voice engines: man, woman, and alice. Default is man for limited languages and alice for extended languages. See below for language specifications on each of these engines.
loop optional The attribute loop specifies the number of times a text is to be repeated. If loop is set to 0, the text will be continuously repeated until the call is terminated. Default behavior is one repetition.
language optional The attribute language allows you to specify the dialect (language and locale) of voice. See below for all language specifications.



When voice is set to man or woman, the following languages are permitted:

Value
language default: en en, en-gb, es, fr, de (English, Spanish, French, German, Italian)



When voice is set to alice, the following languages are permitted:

Value
language default: en-US da-DK [Danish, Denmark]
de-DE [German, Germany]
en-AU [English, Australia]
en-CA [English, Canada]
en-GB [English, UK]
en-IN [English, India]
en-US [English, United States]
ca-ES [Catalan, Spain]
es-ES [Spanish, Spain]
es-MX [Spanish, Mexico]
fi-FI [Finnish, Finland]
fr-CA [French, Canada]
fr-FR [French, France]
it-IT [Italian, Italy]
ja-JP [Japanese, Japan]
ko-KR [Korean, Korea]
nb-NO [Norwegian, Norway]
nl-NL [Dutch, Netherlands]
pl-PL [Polish, Poland]
pt-BR [Portuguese, Brazil]
pt-PT [Portuguese, Portugal]
ru-RU [Russian, Russia]
sv-SE [Swedish, Sweden]
zh-CN [Chinese, Mandarin]
zh-HK [Chinese, Cantonese]
zh-TW [Chinese, Taiwanese Mandarin]

Nouns

The noun of a LaML verb is nested within the verb upon which the verb acts. <Say> has the following noun:

Noun
plain text limit: 4,096 unicode characters The text that will be read to the caller.

Nesting

No other verbs can be nested within <Say>. However, <Say> can be nested within <Gather>.

Examples

A Simple Message to be Read

<?xml version="1.0" encoding="UTF-8"?>
<Response>
     <Say>Hello World.</Say>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.say('Hello World.')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->say('Hello World.');
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Say("Hello World.");

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Say

response = VoiceResponse()
response.say('Hello World.')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.say(message: 'Hello World.')
end

puts response.to_s

'Hello World' will be read once in a male voice.

Repetition of a Message in a Foreign Language

<?xml version="1.0" encoding="UTF-8"?>
<Response>
     <Say voice="alice" language="fr-CA" loop="5">Bonjour.</Say>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.say({ voice: 'alice', language: 'fr-CA', loop: 5 }, 'Bonjour.')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->say('Bonjour', array(
    'voice' => 'alice',
    'language' => 'fr-CA',
    'loop' => 5
  ));
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Say("Bonjour.", voice: "alice", language: "fr-CA", loop: 5);

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import VoiceResponse, Say

response = VoiceResponse()
response.say('Bonjour.', voice='alice', language='fr-CA', loop=5)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.say(message: 'Bonjour.', voice: 'alice', language: 'fr-CA', loop: 5)
end

puts response.to_s

'Hello' will be repeated 5 times in Canadian French.

Notes on Usage

  • There is a 4,096 Unicode character limit on the text
  • Numbers are spoken, or read, based on context. For example, '234' is read as "two hundred thirty-four", whereas '2 3 4' is read as "two three four".
  • Short pauses in spoken text are accomplished by inserting punctuations, i.e. commas and periods, in the written text. For longer pauses, place text in a separate <Say> verbs and place a <Pause> verb in between them.
  • Dates, times, money amounts, and abbreviations may not follow intuitive pronunciations. Test these situations to ensure they are pronounced to your liking.

Messaging LaML

Messaging LaML is a set of actions defined in an XML document you can use to tell SignalWire what to do when you receive an incoming SMS or MMS message.

Overview

When an SMS or MMS message is sent to one of your SignalWire phone numbers, SignalWire looks up the Messaging LaML document from URL you configured, and reads the instructions you provided to determine what to do.

Messaging LaML allows you to dynamically control what happens, responding with specific instructions based on the caller, time of day, incoming message, and much more.

Request For LaML

SignalWire makes an HTTP request to your configured endpoint just like a regular web form submission (POST) or page load (GET). Including contextual information about the message in the request to your endpoint, allows you to respond dynamically and fluidly to the message to meet the needs of your application.

You can configure the endpoint URL and HTTP Method in your phone number settings panel on your SignalWire dashboard, or via the REST API.

Request Parameters

SignalWire sends the following parameters, as either URL query parameters or POST parameters, to your endpoint when it receives a message:

Parameter
MessageSid string A unique identifier for the message. May be used to later retrieve this message from the REST API.
AccountSid string The unique ID of the Account this message is associated with.
From string The phone number that sent this message, in E.164 format.
To string The phone number of the message recipient, in E.164 format.
Body string The text body of the message.
NumMedia integer The number of media items associated with the message.
MediaUrl{X} string
only if media present
The URL to the media received in the message. URLs are publicly available but unguessable. Each media entry has its own entry, where X is a zero-based index of the media. Example: MediaUrl0
MediaContentType{X} string
only if media present
The content-type of the media stored at MediaUrl{X}, where X is a zero-based index of the media. Example: MediaContentType0

Responding to SignalWire

An example LaML document that sends two messages back to the sender when a message is received.

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Message>Hello from SignalWire!</Message>
    <Message>Thanks for your message.</Message>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.MessagingResponse()

response.message('Hello from SignalWire!')
response.message('Thanks for your message.')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->message('Hello from SignalWire!');
  $response->message('Thanks for your message.');
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new MessagingResponse();
        response.Message("Hello from SignalWire!");
        response.Message("Thanks for your message.")

        Console.WriteLine(response.ToString());;
    }
}
from twilio.twiml.messaging_response import Message, MessagingResponse

response = MessagingResponse()
response.message('Hello from SignalWire!')
response.message('Thanks for your message.')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::MessagingResponse.new do |response|
  response.message(body: 'Hello from SignalWire!')
  response.message(body: 'Thanks for your message.')
end

puts response.to_s

When a message comes into one of your SignalWire phone numbers, SignalWire makes an HTTP request to the URL endpoint you configured for that number. Your response to that request instructs SignalWire on what to do next.

Responses to the HTTP request are in LaML. SignalWire starts at the top of your LaML document and executes your LaML commands in order, from top to bottom.

Status Callbacks

SignalWire can send your application callbacks at various lifecycle stages of your message. Status callbacks do not allow you change the application execution directly, so callbacks do not have to respond with LaML, but they allow your application to get updates as a message is happening.

You should respond to any callbacks with a 200 OK or 204 No Content, otherwise you will see failures in your application log on SignalWire.

Message Opt Out

SignalWire handles opt-out messages according to industry standards. Keywords like STOP, UNSUBSCRIBE, END, QUIT, or CANCEL will prevent customers from receiving messages from the SignalWire phone number they are responding with these keywords to. If these keywords are received, SignalWire will essentially place that receiving phone number on a "blacklist", preventing any further messages from being sent to that number. Receiving phone numbers can resume message reception by responding with the keywords: START, YES, or UNSTOP.

<Message>

An example message that responds to the sender.

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Message>Hello from SignalWire!</Message>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.MessagingResponse()

response.message('Hello from SignalWire!')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->message('Hello from SignalWire!');
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new MessagingResponse();
        response.Message("Hello from SignalWire!");

        Console.WriteLine(response.ToString());;
    }
}
from twilio.twiml.messaging_response import Message, MessagingResponse

response = MessagingResponse()
response.message('Hello from SignalWire!')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::MessagingResponse.new do |response|
  response.message(body: 'Hello from SignalWire!')
end

puts response.to_s

The <Message> verb sends an SMS or MMS message to a phone number.

Verb Attributes

An example message with further instructions returned from the action request.

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Message action="https://your-application.com/followup"
             method="GET">
        Hello from SignalWire!
    </Message>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.MessagingResponse()

response.message({ action: 'https://your-application.com/followup', method: 'GET' }, 'Hello from SignalWire!')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->message('Hello from SignalWire!', array(
    'action' => 'https://your-application.com/followup',
    'method' => 'GET'
  ));
  echo $response;
?>
using Twilio.TwiML;
using Twilio.Http;
using System;


class Example
{
    static void Main()
    {
        var response = new MessagingResponse();
        response.Message("Hello from SignalWire",
            action: new Uri("https://your-application.com/followup"), method: HttpMethod.Get);

        Console.WriteLine(response.ToString());;
    }
}
from twilio.twiml.messaging_response import Message, MessagingResponse

response = MessagingResponse()
response.message('Hello from SignalWire!', action='https://your-application.com/followup', method="GET")

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::MessagingResponse.new do |response|
  response.message(action: 'https://your-application.com/followup', method: 'GET', message: 'Hello from SignalWire!')
end

puts response.to_s
Attribute
to optional The to attribute takes a valid phone number in E.164 format as an argument. The message is sent to this phone number. If no to is specified, the message is sent as a reply to the incoming message sender.
from optional The from attribute takes a valid phone number in E.164 format. If no from is specified, it defaults to the phone number that received the message. You can only specify from phone numbers that you have purchased from SignalWire and which are capable of messaging.
action optional The action attribute takes a URL endpoint that is expected to return a LaML document to override control flow. The endpoint receives a callback with the standard message request parameters as well as MessageStatus and ErrorCode and expect a valid LaML document in return. The next instructions to be executed are the verbs returned in response to the action endpoint request.

For example, any verbs following a <Message> verb with its action attribute set are unreachable, as flow control will be passed onto the response from the action request.
method optional The method attribute specifies whether the request to action is a GET or a POST. Valid values are GET or POST, default value is POST.

Message Status

The MessageStatus parameter is sent with requests to the action endpoint or to statusCallback URLs. It determines whether the message was successfully sent or if there were problem with delivery.

Valid message statuses are: queued, sending, sent, failed, delivered

Nouns

An example Message verb using nested nouns

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Message>
        <Body>Hello from SignalWire!</Body>
        <Media>https://link.to/your-media-file</Media>
    </Message>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.MessagingResponse()

message = response.message()
message.body('Hello from SignalWire!')
message.media('https://link.to/your-media-file')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $message = $response->message('');
  $message->body('Hello from SignalWire!');
  $message->media('https://link.to/your-media-file');
  echo $response;
?>
using Twilio.TwiML;
using Twilio.TwiML.Messaging;
using System;


class Example
{
    static void Main()
    {
        var response = new MessagingResponse();
        var message = new Message();
        message.Body("Hello from SignalWire!");
        message.Media(new Uri("https://link.to/your-media-file"));

        response.Append(message);
        Console.WriteLine(response.ToString());;
    }
}
from twilio.twiml.messaging_response import Message, Media, Body, MessagingResponse

response = MessagingResponse()
message = Message()
message.body('Hello from SignalWire!')
message.media('https://link.to/your-media-file')
response.append(message)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::MessagingResponse.new do |response|
  response.message do |message|
    message.body('Hello from SignalWire!')
    message.media('https://link.to/your-media-file')
  end
end

puts response.to_s

The noun of a LaML verb is nested within the verb upon which the verb acts. <Message> has the following nouns:

Noun
plain text The text of the message you want to send.
<Body> The text of the message you want to send. If more than one <Body> noun is present, the text will be concatenated together into a single string. The maximum body size allowed is 1600 characters.
<Media> The URL of media to include in the message. If you wish to send multiple media in a single message, use multiple <Media> nouns. You can have a maximum of 10 media URLs per message.

Nesting

No other verbs can be nested within <Message> and you cannot nest <Message> within any other verbs.

Examples

Send a simple SMS

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Message>Hello from SignalWire!</Message>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.MessagingResponse()

response.message('Hello from SignalWire!')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->message('Hello from SignalWire!');
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new MessagingResponse();
        response.Message("Hello from SignalWire!");

        Console.WriteLine(response.ToString());;
    }
}
from twilio.twiml.messaging_response import Message, MessagingResponse

response = MessagingResponse()
response.message('Hello from SignalWire!')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::MessagingResponse.new do |response|
  response.message(body: 'Hello from SignalWire!')
end

puts response.to_s

The simplest case for <Message>: SignalWire responds to an inbound message with a "hello" message, from the number that received the message.

Send an image with your message (MMS)

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Message>
        <Body>Hello from SignalWire!</Body>
        <Media>https://link.to/your-media-file</Media>
    </Message>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.MessagingResponse()

message = response.message()
message.body('Hello from SignalWire!')
message.media('https://link.to/your-media-file')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $message = $response->message('');
  $message->body('Hello from SignalWire!');
  $message->media('https://link.to/your-media-file');
  echo $response;
?>
using Twilio.TwiML;
using Twilio.TwiML.Messaging;
using System;


class Example
{
    static void Main()
    {
        var response = new MessagingResponse();
        var message = new Message();
        message.Body("Hello from SignalWire!");
        message.Media(new Uri("https://link.to/your-media-file"));

        response.Append(message);
        Console.WriteLine(response.ToString());;
    }
}
from twilio.twiml.messaging_response import Message, Media, Body, MessagingResponse

response = MessagingResponse()
message = Message()
message.body('Hello from SignalWire!')
message.media('https://link.to/your-media-file')
response.append(message)

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::MessagingResponse.new do |response|
  response.message do |message|
    message.body('Hello from SignalWire!')
    message.media('https://link.to/your-media-file')
  end
end

puts response.to_s

Add a picture to the message by specifying a URL with a nested <Media> noun. The <Body> noun is optional if you are sending media and you do not want to send text with your media in the message.

Send a Message and Respond Based on Status

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Message action="https://your-application.com/followup"
             method="GET">
        Hello from SignalWire!
    </Message>
    <Message>I am unreachable!</Message>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.MessagingResponse()

response.message({ action: 'https://your-application.com/followup', method: 'GET' }, 'Hello from SignalWire!')
response.message('I am unreachable!')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->message('Hello from SignalWire!', array(
    'action' => 'https://your-application.com/followup',
    'method' => 'GET'
  ));
  $response->message('I am unreachable!');
  echo $response;
?>
using Twilio.TwiML;
using Twilio.Http;
using System;


class Example
{
    static void Main()
    {
        var response = new MessagingResponse();
        response.Message("Hello from SignalWire!",
            action: new Uri("https://your-application.com/followup"), method: HttpMethod.Get);
        response.Message("I am unreachable!");

        Console.WriteLine(response.ToString());;
    }
}
from twilio.twiml.messaging_response import Message, MessagingResponse

response = MessagingResponse()
response.message('Hello from SignalWire!', action='https://your-application.com/followup', method="GET")
response.message('I am unreachable!')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::MessagingResponse.new do |response|
  response.message(action: 'https://your-application.com/followup', method: 'GET', message: 'Hello from SignalWire!')
  response.message(body: 'I am unreachable!')
end

puts response.to_s

This example allows us to follow up with further actions based on whether the message is sent or not. The URL https://your-application.com/followup receives a GET request with the message's parameters and includes the MessageStatus, either invalid, sending or failed.

The LaML document returned from your application determines what to do next. You could do nothing, or if the MessageStatus was failed, you could alert the user with a different <Message>.

With the action attribute is present, the remaining verbs in the document are unreachable because control is passed off to the response rather than continuing on in the document.

See Also

Send messages without waiting for an inbound message by using our LaML REST API to create a message.

<Redirect>

An example message that redirects next LaML instruction to another document

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Redirect>https://your-application.com/next-instructions</Redirect>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.redirect('https://your-application.com/next-instructions')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->redirect('https://your-application.com/next-instructions');
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Redirect(new Uri("https://your-application.com/next-instructions"));

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import Redirect, VoiceResponse

response = VoiceResponse()
response.redirect('https://your-application.com/next-instructions')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.redirect('https://your-application.com/next-instructions')
end

puts response.to_s

The <Redirect> verb transfers control from the current document to another. It is effectively an exit statement from the current document, as there is no way to return to any instructions listed after the <Redirect> verb.

Verb Attributes

The following attribute is available for the verb <Redirect>:

Attribute
method optional Specifies whether the redirect is a GET or a POST. Default value is POST.

Nouns

The following item is accepted as a noun for the <Redirect> verb:

Noun
URL The URL, in plain text, of the document to execute.

Nesting

No other verbs can be nested within <Redirect> and you cannot nest <Redirect> within any other verbs.

Examples

Redirect to absolute URL

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Redirect>http://www.somesite.com/NextDoc.xml</Redirect>
</Response>
const signalwire = require('signalwire')
var response = new signalwire.RestClient.LaML.VoiceResponse()

response.redirect('http://www.somesite.com/NextDoc.xml')
console.log(response.toString())
<?php
  use SignalWire\LaML;
  $response = new LaML;

  $response->redirect('http://www.somesite.com/NextDoc.xml');
  echo $response;
?>
using Twilio.TwiML;
using System;


class Example
{
    static void Main()
    {
        var response = new VoiceResponse();
        response.Redirect(new Uri("http://www.somesite.com/NextDoc.xml"));

        Console.WriteLine(response.ToString());;
    }
}
from signalwire.voice_response import Redirect, VoiceResponse

response = VoiceResponse()
response.redirect('http://www.somesite.com/NextDoc.xml')

print(response)
require 'signalwire/sdk'

response = Signalwire::Sdk::VoiceResponse.new do |response|
  response.redirect('http://www.somesite.com/NextDoc.xml')
end

puts response.to_s

To continue processing this message using the instructions in another document, specify the absolute URL of that document as the noun to the <Redirect> verb.

Tutorials

Coming Soon!