Navbar
Logo icon Name
  • LaML XML Specification
  • Voice LaML
  • Messaging LaML
  • Fax LaML
  • LaML REST API
  • LaML XML Specification

    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 { RestClient } = require('@signalwire/node')
    const response = new 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.
    <Stream> Streams a call to a websocket.

    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.
    <Refer> Send SIP REFER to transfer the call from SignalWire control
    <Reject> Decline an incoming call.

    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.

    Fax Verbs

    The following verbs are used to manage faxes:

    Verb Action
    <Receive> Receives an incoming fax.
    <Reject> Rejects an incoming fax.

    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 { RestClient } = require('@signalwire/node')
    const response = new 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.
    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 { RestClient } = require('@signalwire/node')
    const response = new 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
    CallbackSource string The source of the status callback.
    CallDuration integer The duration, in seconds, of the finished call. Only present on the completed event.
    Timestamp string The timestamp, in RFC 2822 format, of when the event occurred.

    <Denoise>

    The <Denoise> verb enables or disables noise reduction for call audio inbound to SignalWire. Reduce noise on calls before dialing into a conference or forwarding to another number.

    Verb Attributes

    Attribute

    Nesting

    No other verbs can be nested within <Denoise>.

    Examples

    Enable Noise Reduction

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Denoise>on</Denoise>
        <Dial><Sip>sip:user@example.com;transport=udp</Sip></Dial>
    </Response>
    

    This illustrates enabling noise reduction on an inbound phone call prior to forwarding the call.

    Disable Noise Reduction

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Denoise>off</Denoise>
        <Record timeout="5" transcribe="true"/>
    </Response>
    

    This illustrates disabling noise reduction prior to recording and transcribing.

    <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. Note that the number specified here must either be verified or purchased in the SignalWire dashboard.
    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 The different recording statuses. Possible values are completed, in-progress, and absent. To specify multiple events, separate with a space. Defaults to completed.
    recordingStatusCallbackMethod optional Whether the request to recordingStatusCallback URL is a GET or a POST. Default is POST.
    recordingStorageUrl optional The recordingStorageUrl attribute accepts an absolute URL as the destination to send a recording to, if you prefer to host your own recordings and bypass SignalWire storage. The recording files are in .wav format.
    recordingStorageUrlMethod optional Specifies which HTTP verb to use when sending the recording to the recordingStorageUrl. Available values are: POST and PUT. Defaults to POST.
    recordingTrack optional Specifies whether to record the inbound audio to SignalWire from the called party or the outbound audio from SignalWire to the called party or both the inbound and outbound audio. Defaults to both.
    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-dual: starts the recording when ringing begins



    The recordingStatusCallback request contains the following parameters:

    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.
    RecordingTrack string Which audio tracks are recorded. Can be inbound, outbound, or both.

    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.
    waitMethod 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.
    coach optional Coach accepts a call SID of a call that is currently connected to an in-progress conference. Specifying a call SID that does not exist or is no longer connected to the conference will result in the call failing to the action URL and throwing a 13240 error.
    statusCallbackEvent optional Which conference state changes will trigger a webhook to the URL provided in statusCallback. 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. To specify multiple events, separate them with a space.
    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 following parameters:

    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.
    RecordingStartTime integer The timestamp for when the recording started.
    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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 (Monitor)

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
      <Dial>
        <Conference muted="true">ConferenceRoom</Conference>
      </Dial>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new 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.

    Coaching A Conference Call

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
      <Dial>
        <Conference coach="AgentCallSid">
          Example-Room
        </Conference>
      </Dial>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.VoiceResponse()
    
    dial = response.dial()
    dial.conference('Example-Room', { coach: "AgentCallSid" })
    console.log(response.toString())
    
    <?php
      use SignalWire\LaML;
      $response = new LaML;
    
      $dial = $response->dial();
      $dial->conference('Example-Room', array( 'coach' => 'AgentCallSid' ));
      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("Example-Room",
                coach: 'AgentCallSid');
    
            response.Append(dial);
            Console.WriteLine(response.ToString());;
        }
    }
    
    from signalwire.voice_response import VoiceResponse, Dial, Conference
    
    response = VoiceResponse()
    dial = Dial()
    dial.conference('Example-Room', coach='AgentCallSid')
    response.append(dial)
    
    print(response)
    
    require 'signalwire/sdk'
    
    response = Signalwire::Sdk::VoiceResponse.new do |response|
      response.dial do |dial|
        dial.conference('Example-Room', coach: '')
      end
    end
    
    puts response.to_s
    

    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 { RestClient } = require('@signalwire/node')
    const response = new 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 callee'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
    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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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.

    <Sip>

    Dialing to a SIP destination.

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Dial>
            <Sip>sip:alice@example.com</Sip>
        </Dial>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.VoiceResponse()
    
    dial = response.dial()
    dial.sip('sip:alice@example.com')
    console.log(response.toString())
    
    <?php
      use SignalWire\LaML;
      $response = new LaML;
    
      $dial = $response->dial();
      $dial->sip('sip:alice@example.com');
      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.Sip(new Uri("sip:alice@example.com"));
            response.Append(dial);
    
            Console.WriteLine(response.ToString());
        }
    }
    
    from signalwire.voice_response import VoiceResponse, Dial, Sip
    
    response = VoiceResponse()
    dial = Dial()
    dial.sip('sip:alice@example.com')
    response.append(dial)
    
    print(response)
    
    require 'signalwire/sdk'
    
    response = Signalwire::Sdk::VoiceResponse.new do |response|
      response.dial do |dial|
        dial.sip('sip:alice@example.com')
      end
    end
    
    puts response.to_s
    

    <Dial> verb's <Sip> noun permits the set up of VoIP sessions using SIP (Session Initiation Protocol). You can send a call to any SIP endpoint.

    When dialing an SIP endpoint, the transport defaults to TLS. If the SIP destination does not support TLS, you can set the transport to UDP or TCP by setting the transport manually. For example: sip:alice@example.com;transport=udp.

    The <Sip> noun supports all of the <Dial> verb's attributes with one exception: callerId is supported but not limited to a valid E.164 number. When using the <Sip> noun, the callerId attribute can be any alphanumeric string and include the following characters: +-_., but no whitespace.

    Noun Attributes

    Attribute
    codecs optional A comma separated list of codecs to offer to the SIP user agent. Select from PCMU, PCMA, G722, G729, and OPUS. Codecs are offered in the order specified. Default value is PCMU,PCMA
    url optional A specified URL for a document that runs on the callee'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. 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.
    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.
    username optional Username for SIP authentication
    password optional Password for SIP authentication



    In addition to the standard request parameters, the following are parameters passed back to your application when SignalWire makes a request to the <Sip> noun's url attribute.

    Parameter
    SipCallId string The SIP call ID header of the request made to the remote SIP infrastructure.
    SipHeader string The name or value of any X-headers returned in the 200 response to the SIP INVITE request.



    After a Dial attempt is made, SignalWire can make a request to the <Dial> verb's action attribute. In addition to the standard request parameters, the following are parameters passed back to your application when SignalWire makes the request.

    Parameter
    DialSipCallId string The SIP call ID header of the request made to the remote SIP infrastructure.
    DialSipResponseCode string The SIP response code to the INVITE attempt.
    DialSipHeader_ string The name or value of any X-headers returned in the 200 response to the SIP INVITE request.



    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
    CallbackSource string The source of the status callback.
    CallDuration integer The duration, in seconds, of the finished call. Only present on the completed event.
    Timestamp string The timestamp, in RFC 2822 format, of when the event occurred.

    <Sip> Examples

    Dialing to a SIP Endpoint

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Dial>
            <Sip>sip:alice@example.com</Sip>
        </Dial>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.VoiceResponse()
    
    dial = response.dial()
    dial.sip('sip:alice@example.com')
    console.log(response.toString())
    
    <?php
      use SignalWire\LaML;
      $response = new LaML;
    
      $dial = $response->dial();
      $dial->sip('sip:alice@example.com');
      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.Sip(new Uri("sip:alice@example.com"));
            response.Append(dial);
    
            Console.WriteLine(response.ToString());
        }
    }
    
    from signalwire.voice_response import VoiceResponse, Dial, Sip
    
    response = VoiceResponse()
    dial = Dial()
    dial.sip('sip:alice@example.com')
    response.append(dial)
    
    print(response)
    
    require 'signalwire/sdk'
    
    response = Signalwire::Sdk::VoiceResponse.new do |response|
      response.dial do |dial|
        dial.sip('sip:alice@example.com')
      end
    end
    
    puts response.to_s
    

    In this example, in order to connect to 'alice@example.com' we have to nest a <Sip> within a <Dial>.

    Dialing to a SIP Endpoint With Authentication

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Dial>
            <Sip username="admin" password="1234">sip:bob@example.com</Sip>
        </Dial>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.VoiceResponse()
    
    dial = response.dial()
    dial.sip({ username: 'admin', password: '1234' }, 'sip:bob@example.com')
    console.log(response.toString())
    
    <?php
      use SignalWire\LaML;
      $response = new LaML;
    
      $dial = $response->dial();
      $dial->sip('sip:bob@example.com', array( 'username' => 'admin', 'password' => '1234' ));
      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.Sip(new Uri("sip:bob@example.com"), username: "admin",
                password: "1234");
            response.Append(dial);
    
            Console.WriteLine(response.ToString());
        }
    }
    
    from signalwire.voice_response import VoiceResponse, Dial, Sip
    
    response = VoiceResponse()
    dial = Dial()
    dial.sip('sip:bob@example.com', username='admin', password='1234')
    response.append(dial)
    
    print(response)
    
    require 'signalwire/sdk'
    
    response = Signalwire::Sdk::VoiceResponse.new do |response|
      response.dial do |dial|
        dial.sip('sip:bob@example.com', username:'admin', password:'1234')
      end
    end
    
    puts response.to_s
    

    Now, in order to connect to 'bob@example.com', you have to have the proper authentication credentials.

    Passing Custom Headers

    Pass custom headers to the SIP endpoint.

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Dial>
            <Sip>sip:charlie@example.com?customheader=foo&amp;othercustomheader=bar</Sip>
        </Dial>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.VoiceResponse()
    
    dial = response.dial()
    dial.sip('sip:charlie@example.com?customheader=foo&amp;othercustomheader=bar')
    console.log(response.toString())
    
    <?php
      use SignalWire\LaML;
      $response = new LaML;
    
      $dial = $response->dial();
      $dial->sip('sip:charlie@example.com?customheader=foo&amp;othercustomheader=bar');
      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
                .Sip(new Uri("sip:charlie@example.com?customheader=foo&amp;othercustomheader=bar"));
            response.Append(dial);
    
            Console.WriteLine(response.ToString());
        }
    }
    
    from signalwire.voice_response import VoiceResponse, Dial, Sip
    
    response = VoiceResponse()
    dial = Dial()
    dial.sip('sip:charlie@example.com?customheader=foo&amp;othercustomheader=bar')
    response.append(dial)
    
    print(response)
    
    require 'signalwire/sdk'
    
    response = Signalwire::Sdk::VoiceResponse.new do |response|
      response.dial do |dial|
        dial.sip('sip:charlie@example.com?customheader=foo&amp;othercustomheader=bar')
      end
    end
    
    puts response.to_s
    

    Dialing a SIP Endpoint with Dial attributes

    The Sip Noun supports of <Dial> attributes and can be used together.

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Dial
         record="record-from-answer"
         callerId="alice"
         method="GET"
         action="https://www.example.com/after_dial">
            <Sip
              url="https://www.example.com/whisper_audio"
              statusCallbackEvent='ringing answered'
              statusCallback='https://www.example.com/dial_events'>
                sip:dan@example.com?customheader=foo
            </Sip>
        </Dial>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.VoiceResponse()
    
    dial = response.dial({ record: 'record-from-answer', callerId: 'alice', method: 'GET', action: 'https://www.example.com/after_dial' })
    dial.sip({ url: 'https://www.example.com/whisper_audio', statusCallbackEvent: 'ringing answered', statusCallback: 'https://www.example.com/dial_events' }, 'sip:dan@example.com?customheader=foo')
    console.log(response.toString())
    
    <?php
      use SignalWire\LaML;
      $response = new LaML;
    
      $dial = $response->dial( array( 'record' => 'record-from-answer', 'callerId' => 'alice', 'method' => 'GET', 'action' => 'https://www.example.com/after_dial' ));
      $dial->sip('sip:dan@example.com?customheader=foo', array( 'url' => 'https://www.example.com/whisper_audio', 'statusCallbackEvent' => 'ringing answered', 'statusCallback' => 'https://www.example.com/dial_events' ));
      echo $response;
    ?>
    
    using System;
    using Twilio.TwiML;
    using Twilio.TwiML.Voice;
    
    
    class Example
    {
        static void Main()
        {
            var response = new VoiceResponse();
            var dial = new Dial(record: Dial.RecordEnum.RecordFromAnswer,
                callerId: "alice", method: Twilio
                .Http.HttpMethod.Get, action: new Uri("https://www.example.com/after_dial"));
            dial.Sip(new Uri("sip:dan@example.com?customheader=foo"),
                statusCallbackEvent: new []{Sip.EventEnum.Ringing, Sip.EventEnum.Answered}.ToList(),
                statusCallback: new Uri("https://www.example.com/dial_events"),
                url: new Uri("https://www.example.com/whisper_audio"));
            response.Append(dial);
    
            Console.WriteLine(response.ToString());
        }
    }
    
    from signalwire.voice_response import VoiceResponse, Dial, Sip
    
    response = VoiceResponse()
    dial = Dial(record='record-from-answer', caller_id='alice', method='GET', action='https://www.example.com/after_dial')
    dial.sip('sip:dan@example.com?customheader=foo', url='https://www.example.com/whisper_audio', status_callback_event='ringing answered', status_callback='https://www.example.com/dial_events')
    response.append(dial)
    
    print(response)
    
    require 'signalwire/sdk'
    
    response = Signalwire::Sdk::VoiceResponse.new do |response|
      response.dial(record:'record-from-answer', caller_id:'alice', method:'GET', action:'https://www.example.com/after_dial') do |dial|
        dial.sip('sip:dan@example.com?customheader=foo', url:'https://www.example.com/whisper_audio', status_callback_event:'ringing answered', status_callback:'https://www.example.com/dial_events')
      end
    end
    
    puts response.to_s
    

    Notes on Usage

    • SIP INVITE message includes CallSid, AccountSid, and the API version; can also pass custom SIP headers in the INVITE message.
    • You can have up to 10 <Sip>s within a <Dial>.
    • You cannot add other nouns in a <Dial> that contains a <Sip>.

    <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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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.

    <Echo>

    The <Echo> verb will echo audio back to the call.

    Verb Attributes

    Attribute
    timeout optional The number of seconds SignalWire will echo, from 5 up to 120 seconds. Defaults to 60 seconds if no value is provided.

    Nesting

    No other verbs can be nested within <Echo>.

    Examples

    A simple echo test

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Echo timeout="120"/>
        <Hangup/>
    </Response>
    

    SignalWire answers call and echoes what it hears for 2 minutes.

    <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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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.
    actionOnEmptyResult optional Send a webhook to the action URL even if there is no input. By default, if no input is detected, the next LaML instruction is executed but by setting actionOnEmptyResult to true, a callback to the action URL will be sent to continue call flow. Valid values are true or false. Default is false.
    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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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.
    recordingStatusCallbackEvent optional The different recording statuses. Possible values are completed, in-progress, and absent. To specify multiple events, separate with a space. Defaults to completed.
    recordingStatusCallbackMethod optional The type of HTTP request to use when requesting a recordingStatusCallback. Default is POST.
    storageUrl optional The storageUrl attribute accepts an absolute URL as the destination to send a recording to, if you prefer to host your own recordings and bypass SignalWire storage.
    storageUrlMethod optional Specifies which HTTP verb to use when sending the recording to the storageUrl. Available values are: POST and PUT. Defaults to 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.

    * Please note that if no audio data is received, a recording will not be saved, a request will not be made to any Action url that is set, and the document will continue to be processed with the next verb after Record. This also applies when only silence is detected and 'trim-silence' is set, resulting in no actual audio content remaining to save.



    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 following parameters:

    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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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.

    <Refer>

    The <Refer> verb transfers a SIP call in SignalWire to a transfer target using the SIP REFER method. This verb returns upon completion of transfer, on failure of transfer, on hangup, or on time out while waiting for NOTIFY. SignalWire will not hangup after <Refer> until all verbs have been processed.

    Verb Attributes

    Attribute
    action optional The action attribute takes an absolute or relative URL. On completion of the transfer, a request to this URL is made. 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 action is a GET or a POST. Default value is POST.



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

    Parameter
    ReferCallStatus string The result of the transfer based on the reply to the SIP REFER method and the SIP NOTIFY events received afterwards. This parameter will not be reported if no SIP NOTIFY events are received. See below for all possible values.
    ReferSipResponseCode string The code received in response to the SIP REFER method. 202 when accepted.
    NotifySipResponseCode string The last response code reported by the SIP NOTIFY events. This is the code sent by the transfer target in response to the SIP INVITE method. This parameter will not reported if no SIP NOTIFY events are received.



    The parameter ReferCallStatus has the following values:

    Value
    in-progress SIP REFER accepted and SignalWire received 200 via SIP NOTIFY.
    busy SIP REFER accepted and SignalWire received 486 or 600 via SIP NOTIFY.
    no-answer SIP REFER accepted and SignalWire received 487 via SIP NOTIFY.
    canceled SIP REFER accepted, however the call ended before the transfer completed.
    failed An error occurred through the <Refer> verb, an error received in response to SIP REFER, or a 4xx/5xx/6xx error was received via SIP NOTIFY.

    Nouns

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

    Noun
    <Sip> The SIP URI to which to transfer this call.

    Nesting

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

    Examples

    Transfer to SIP URI

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Refer action="https://example.com/refer-completed.xml" method="GET"><Sip>sip:transfer-target@example.com</Sip></Refer>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.VoiceResponse()
    
    const refer = response.refer({ action: 'https://example.com/refer-completed.xml', method: 'GET' })
    refer.sip('sip:transfer-target@example.com')
    console.log(response.toString())
    
    <?php
      use SignalWire\LaML;
      $response = new LaML;
    
      $refer = $response->refer(['action' => 'https://example.com/refer-completed.xml', 'method' => 'GET']);
      $refer->sip('sip:transfer-target@example.com');
      echo $response;
    ?>
    
    using Twilio.TwiML;
    using System;
    
    
    class Example
    {
        static void Main()
        {
            var response = new VoiceResponse();
            var refer = response.Refer(action: new Uri("https://example.com/refer-completed.xml"), method: Twilio.Http.HttpMethod.Get);
            refer.sip(new Uri("sip:transfer-target@example.com"));
            response.append(refer);
            Console.WriteLine(response.ToString());
        }
    }
    
    from signalwire.voice_response import VoiceResponse, Refer
    
    response = VoiceResponse()
    refer = response.refer(action='https://example.com/refer-completed.xml', method='GET')
    refer.sip('sip:transfer-target@example.com')
    response.append(refer)
    
    print(response)
    
    require 'signalwire/sdk'
    
    response = Signalwire::Sdk::VoiceResponse.new do |response|
      refer = response.refer(action: 'https://example.com/refer-completed.xml', method: 'GET') do |refer|
        refer.sip('sip:transfer-target@example.com')
      end
    end
    
    puts response.to_s
    

    <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.

    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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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: man, woman, alice, Amazon Polly voices by prefixing them with Polly., Amazon Polly Neural voices by prefixing them with Polly. and ending them with -Neural, Google Cloud voices by prefixing them with gcloud.. Polly Neural and Google Wavenet voices are charged a premium price compared to Polly Standard and Google Standard voices. Default is woman for most languages. alice is deprecated and provided for backward compatibility. See below for language specifications on each of these voices.
    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.

    The available Amazon Polly voices are here

    The available Google Cloud voices are here

    The following languages are permitted:

    Value
    language default: en arb [Arabic, Modern Standard]
    ar-AR [Arabic, Modern Standard]
    ar-XA [Arabic] gcloud
    bn-IN [Bengali, India] gcloud
    yue-HK [Chinese, Hong Kong] gcloud
    cmn-CN [Chinese, Mandarin] gcloud
    cmn-TW [Chinese, Mandarin] gcloud
    zh-CN [Chinese, Mandarin]
    cs-CZ [Czech, Czech Republic] gcloud
    cy-GB [Welsh, UK]
    da-DK [Danish, Denmark]
    de [German, Germany]
    de-DE [German, Germany]
    en [English, United States]
    en-AU [English, Australia]
    en-CA [English, Canada]
    en-GB [English, UK]
    en-GB-WLS [English, Wales]
    en-IN [English, India]
    en-US [English, United States]
    es [Spanish, United States]
    es-ES [Spanish, Spain]
    es-MX [Spanish, Mexico]
    es-US [Spanish, United States]
    fil-PH [Filipino, Phillipines] gcloud
    fi-FI [Finnish, Finland] gcloud
    fr [French, France]
    fr-CA [French, Canada]
    fr-FR [French, France]
    el-GR [Greek, Greece] gcloud
    gu-IN [Gujarati, India] gcloud
    hi-IN [Hindi, India]
    hu-HU [Hungarian, Hungary] gcloud
    is-IS [Icelandic, Iceland]
    id-ID [Indonesian, Indonesia] gcloud
    it [Italian, Italy]
    it-IT [Italian, Italy]
    ja-JP [Japanese, Japan]
    kn-IN [Kannada, India] gcloud
    ko-KR [Korean, Korea]
    ml-IN [Malayalam, India] gcloud
    morse [Morse Code, Dit Dah]
    nb-NO [Norwegian, Norway]
    nl-NL [Dutch, Netherlands]
    pl-PL [Polish, Poland]
    pt-BR [Portuguese, Brazil]
    pt-PT [Portuguese, Portugal]
    ro-RO [Romanian, Romania]
    ru-RU [Russian, Russia]
    sk-SK [Slovak, Slovakia] gcloud
    sv-SE [Swedish, Sweden]
    ta-IN [Tamil, India] gcloud
    te-IN [Telugu, India] gcloud
    th-TH [Thai, Thailand] gcloud
    tr-TR [Turkish, Turkey]
    uk-UA [Ukrainian, Ukraine] gcloud
    vi-VN [Vietnamese, Vietnam] gcloud

    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.

    SSML

    Speech Synthesis Markup Language (SSML) is an XML-based markup language that provides a standard way to mark up text for synthesized speech.

    SSML is usually wrapped within <speak> tags. But, when using SSML with the <Say> verb, you can ignore those <speak> tags. The rest of the SSML tags will be placed inside the <Say> verb.

    Below are the supported SSML tags.

    Tag
    <break> A pause in speech. Set the length of the pause with the time attribute. Maximum pause time is 10s. Include the unit s or ms when setting a time. The strength attribute can also be used for pauses. See below for possible values.
    <emphasis> Emphasize words or phrases. This tag changes the rate and volume of speech. More emphasis generates louder and slower speech while less emphasis generates quieter and faster speech. Emphasis can be modified with the level attribute. See below for possible values.
    <lang> Specify another language for specific words or phrases. Set the language with the xml:lang attribute. Possible languages are: en-US, en-GB, en-IN, en-AU, en-CA, de-DE, es-ES, it-IT, ja-JP, fr-FR (English, German, Spanish, Italian, Japanese, French).
    <p> Add a pause between paragraphs.
    <phoneme> Phonetic pronunciation for specified words or phrases. Set the phonetic alphabet to use with the alphabet attribute. See below for possible values. In addition, you can use the ph attribute to set the phonetic pronunciation to speak. See here for a list of supported symbols.
    <prosody> Modify the volume, pitch, and rate of the tagged speech.
    <s> Add a pause between sentences.
    <say-as> Describe how text should be interpreted. See below for all the possible values of the interpret-as attribute.
    <sub> Pronounce the specified word or phrase as a different word or phrase. Specify the pronunciation to substitute with the alias attribute.



    The strength attribute has the following values. Default is medium.

    Value
    none No pause. Can be used to remove a pause that would normally occur.
    x-weak No pause.
    weak Treat adjacent words as if separated by a single comma.
    medium Treat adjacent words as if separated by a single comma.
    strong Sentence break.
    x-strong Paragraph break.



    The level attribute has the following values. Default is moderate.

    Value
    strong Increase the volume and slow down the speaking rate. Speech is louder and slower.
    moderate Increase the volume and slow down the speaking rate, but not as much as strong.
    moderate Decrease the volume and speed up the speaking rate. Speech is softer and faster.



    The alphabet attribute has the following values.

    Value
    ipa The International Phonetic Alphabet (IPA).
    x-sampa The Extended Speech Assessment Methods Phonetic Alphabet (X-SAMPA).



    The volume attribute has the following values. Set the volume with one of the values below. Then, you can specify a percentage to increase or decrease the volume of the speech. See here for more information.

    Value
    silent No volume.
    x-soft Lowest volume.
    soft Lower volume.
    medium Normal volume.
    loud Louder volume.
    x-loud Loudest volume.



    The pitch attribute has the following values. Set the pitch with one of the values below. Then, you can specify a percentage to increase or decrease the pitch of the speech. See here for more information.

    Value
    x-low Lowest pitch.
    low Lower pitch.
    medium Normal pitch.
    high Higher pitch.
    x-high Highest pitch.



    The rate attribute has the following values. Set the rate with one of the values below. Then, you can specify a percentage to increase or decrease the speed of the speech. See here for more information.

    Value
    x-slow Slowest rate.
    slow Slower rate.
    medium Normal rate.
    fast Faster rate.
    x-fast Fastest rate.



    The interpret-as attribute has the following values.

    Value
    characters Spell out each letter.
    spell-out Spell out each letter.
    cardinal Interpret value as cardinal number.
    number Interpret value as cardinal number.
    ordinal Interpret value as ordinal number.
    digits Spell each digit separately.
    fraction Interpret value as fraction.
    unit Interpret value as measurement.
    date Interpret value as a date. Use format attribute to indicate format of date: mdy, dmy, ymd, md, dm, ym, my, d, m, y.
    time Interpret as a duration of minutes and seconds.
    telephone Interpret as telephone number.
    address Interpret as part of a street address.
    interjection Interpret as an interjection.
    expletive "Bleep" out content in tag.

    Example

    <Response>
      <Say>
        Welcome to SignalWire
        <break strength="x-weak" time="100ms"/>
        <emphasis level="moderate">Emphasized words</emphasis>
        <p>Words in a paragraph</p>
        <phoneme alphabet="x-sampa" ph="pɪˈkɑːn">Phonetic pronunciation</phoneme>
        <prosody pitch="-10%" rate="85%" volume="-6dB">Words to speak</prosody>
        <s>Words in a sentence.</s>
        <say-as interpret-as="spell-out">Words</say-as>
        <sub alias="alias">Words to be substituted</sub>
      </Say>
    </Response>
    

    Here is an example of how to use some of the SSML tags within the Say verb.

    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 { RestClient } = require('@signalwire/node')
    const response = new 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.

    A Simple Message to be Read using Amazon Polly voice

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
         <Say voice="Polly.Joanna">Hello World.</Say>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.VoiceResponse()
    
    response.say({voice:'Polly.Joanna'}, 'Hello World.')
    console.log(response.toString())
    
    <?php
      use SignalWire\LaML;
      $response = new LaML;
    
      $response->say('Hello World.', ['voice' => 'Polly.Joanna']);
      echo $response;
    ?>
    
    using Twilio.TwiML;
    using System;
    
    
    class Example
    {
        static void Main()
        {
            var response = new VoiceResponse();
            response.Say("Hello World.", voice: "Polly.Joanna");
    
            Console.WriteLine(response.ToString());;
        }
    }
    
    from signalwire.voice_response import VoiceResponse, Say
    
    response = VoiceResponse()
    response.say('Hello World.', voice='Polly.Joanna')
    
    print(response)
    
    require 'signalwire/sdk'
    
    response = Signalwire::Sdk::VoiceResponse.new do |response|
      response.say(voice: 'Polly.Joanna', message: 'Hello World.')
    end
    
    puts response.to_s
    

    'Hello World' will be read once using the Amazon Polly "Joanna" voice.

    A Simple Message to be Read using Amazon Polly Neural voice

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
         <Say voice="Polly.Joanna-Neural">Hello World.</Say>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.VoiceResponse()
    
    response.say({voice:'Polly.Joanna-Neural'}, 'Hello World.')
    console.log(response.toString())
    
    <?php
      use SignalWire\LaML;
      $response = new LaML;
    
      $response->say('Hello World.', ['voice' => 'Polly.Joanna-Neural']);
      echo $response;
    ?>
    
    using Twilio.TwiML;
    using System;
    
    
    class Example
    {
        static void Main()
        {
            var response = new VoiceResponse();
            response.Say("Hello World.", voice: "Polly.Joanna-Neural");
    
            Console.WriteLine(response.ToString());;
        }
    }
    
    from signalwire.voice_response import VoiceResponse, Say
    
    response = VoiceResponse()
    response.say('Hello World.', voice='Polly.Joanna-Neural')
    
    print(response)
    
    require 'signalwire/sdk'
    
    response = Signalwire::Sdk::VoiceResponse.new do |response|
      response.say(voice: 'Polly.Joanna-Neural', message: 'Hello World.')
    end
    
    puts response.to_s
    

    'Hello World' will be read once using the Amazon Polly "Joanna" Neural voice. Amazon Polly Neural voices are charged a premium price compared to Amazon Polly Standard voices.

    A Simple Message to be Read using Google Cloud text-to-speech voice

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
         <Say voice="gcloud.en-US-Standard-A">Hello World.</Say>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.VoiceResponse()
    
    response.say({voice:'gcloud.en-US-Standard-A'}, 'Hello World.')
    console.log(response.toString())
    
    <?php
      use SignalWire\LaML;
      $response = new LaML;
    
      $response->say('Hello World.', ['voice' => 'gcloud.en-US-Standard-A']);
      echo $response;
    ?>
    
    using Twilio.TwiML;
    using System;
    
    
    class Example
    {
        static void Main()
        {
            var response = new VoiceResponse();
            response.Say("Hello World.", voice: "gcloud.en-US-Standard-A");
    
            Console.WriteLine(response.ToString());;
        }
    }
    
    from signalwire.voice_response import VoiceResponse, Say
    
    response = VoiceResponse()
    response.say('Hello World.', voice='gcloud.en-US-Standard-A')
    
    print(response)
    
    require 'signalwire/sdk'
    
    response = Signalwire::Sdk::VoiceResponse.new do |response|
      response.say(voice: 'gcloud.en-US-Standard-A', message: 'Hello World.')
    end
    
    puts response.to_s
    

    'Hello World' will be read once using the Google Cloud text-to-speech en-US-Standard-A 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 { RestClient } = require('@signalwire/node')
    const response = new 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.

    <Sms>

    The <Sms> verb sends an SMS message to a phone number during a phone call.

    Verb Attributes

    Attribute
    to optional The to attribute takes a valid phone number as a value. SignalWire will send an SMS message to this number.

    When sending an SMS during an incoming call, to defaults to the caller. When sending an SMS during an outgoing call, to defaults to the called party. The value of to must be a valid phone number. NOTE: sending to short codes is not currently supported.

    Phone numbers should be formatted with a + and country code e.g., +17275551212 (E.164 format).
    from optional The from attribute takes a valid phone number as an argument. This number must be a phone number that you've purchased from or ported to SignalWire. When sending an SMS during an incoming call, from defaults to the called party. When sending an SMS during an outgoing call, from defaults to the calling party. This number must be an SMS-enabled phone number assigned to your account. If the phone number isn't SMS-enabled, then the <Sms> verb will not send an SMS message.
    action optional The action attribute takes a URL as an argument. After processing the <Sms> verb, SignalWire will make a GET or POST request to this URL with the form parameters SmsStatus and SmsSid. Using an action URL, your application can receive synchronous notification that the message was successfully enqueued.

    If you provide an action URL, SignalWire will use the LaML received in your response to the action URL request to continue the current call. Any LaML verbs occurring after an <Sms> which specifies an action attribute are unreachable.

    If no action is provided, <Sms> will finish and SignalWire will move on to the next LaML verb in the document. If there is no next verb, SignalWire will end the phone call. Note that this is different from the behavior of <Record> and <Gather>. <Sms> does not make a request to the current document's URL by default if no action URL is provided. 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. `
    statusCallback optional The URL to make requests to for each statusCallbackEvent event. See below for request parameters. The statusCallback attribute takes a URL as an argument. When the SMS message is actually sent, or if sending fails, SignalWire will make an asynchronous POST request to this URL with the parameters SmsStatus and SmsSid. Note, statusCallback always uses HTTP POST to request the given url.



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

    Parameter
    SmsSid string The Sid for the Sms message.
    SmsStatus string The current status of the Sms message. This is usually sending. But if you provide an invalid number, this is invalid.



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

    Parameter
    SmsSid string The Sid for the Sms message.
    SmsStatus string The current status of the Sms message. Either sent or failed.

    Nouns

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

    Noun
    plain text The text of the SMS message you want to send. Must be less than 1600 characters.

    Nesting

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

    Examples

    Simple SMS Sending

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Say>Our store is located at 123 Easy St.</Say>
        <Sms>Store Location: 123 Easy St.</Sms>
    </Response>     
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.VoiceResponse()
    
    response.say('Our store is located at 123 Easy St.');
    response.sms('Store Location: 123 Easy St.');
    
    console.log(response.toString());
    
    <?php
      use SignalWire\LaML;
      $response = new LaML;
      $response->say('Our store is located at 123 Easy St.');
      $response->sms('Store Location: 123 Easy St.');
    
      echo $response;
    ?>
    
    using System;
    using Twilio.TwiML;
    using Twilio.TwiML.Voice;
    
    
    class Example
    {
        static void Main()
        {
            var response = new VoiceResponse();
            response.Say("Our store is located at 123 Easy St.");
            response.Sms("Store Location: 123 Easy St.");
    
            Console.WriteLine(response.ToString());
        }
    }
    
    from signalwire.voice_response import VoiceResponse, Enqueue
    
    response = VoiceResponse()
    response.say('Our store is located at 123 Easy St.')
    response.sms('Store Location: 123 Easy St.')
    
    print(response)
    
    require 'signalwire/sdk'
    
    response =  Signalwire::Sdk::VoiceResponse.new
    response.say(message: 'Our store is located at 123 Easy St.')
    response.sms('Store Location: 123 Easy St.')
    
    puts response
    

    This is the simplest case for <Sms>. SignalWire first tells the caller where the store is located, and then sends the caller an SMS with the location as the message.

    SmsStatus reporting

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Say>Our store is located at 123 Easy St.</Say>
        <Sms action="/smsHandler.php" method="POST">
            Store Location: 123 Easy St.
        </Sms>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.VoiceResponse()
    
    response.say('Our store is located at 123 Easy St.');
    response.sms({
        action: '/smsHandler.php',
        method: 'POST'
    }, 'Store Location: 123 Easy St.');
    
    console.log(response.toString());
    
    <?php
      use SignalWire\LaML;
      $response = new LaML;
      $response->say('Our store is located at 123 Easy St.');
      $response->sms('Store Location: 123 Easy St.', ['action' => '/smsHandler.php',
        'method' => 'POST']);
    
    
      echo $response;
    ?>
    
    using System;
    using Twilio.TwiML;
    using Twilio.TwiML.Voice;
    
    
    class Example
    {
        static void Main()
        {
            var response = new VoiceResponse();
            response.Say("Our store is located at 123 Easy St.");
            response.Sms("Store Location: 123 Easy St.",
                action: new Uri("/smsHandler.php"), method: Twilio.Http.HttpMethod
                .Post);
    
            Console.WriteLine(response.ToString());
        }
    }
    
    from signalwire.voice_response import VoiceResponse, Enqueue
    
    response = VoiceResponse()
    response.say('Our store is located at 123 Easy St.')
    response.sms(
        'Store Location: 123 Easy St.', action='/smsHandler.php', method='POST'
    )
    print(response)
    
    require 'signalwire/sdk'
    
    response =  Signalwire::Sdk::VoiceResponse.new
    response.say(message: 'Our store is located at 123 Easy St.')
    response.sms('Store Location: 123 Easy St.', action: '/smsHandler.php',
                                                 method: 'POST')
    
    puts response
    

    In this use case, we provide action URL and method attributes. Now when the message is queued for delivery, SignalWire will make a request to the action URL passing the parameter SmsStatus. If the message is queued and waiting to be sent, SmsStatus will have the value sending. If an invalid attribute was provided, then SmsStatus will be invalid.

    Your web application can look at the SmsStatus parameter and decide what to do next.

    If an action URL is provided for <Sms>, flow of your application will continue with the TwiML received in response to the action request. All verbs remaining in the document are unreachable and ignored.

    statusCallback reporting

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Say>Our store is located at 123 Easy St.</Say>
        <Sms statusCallback="/smsHandler.php">Store Location: 123 Easy St.</Sms>
    </Response>     
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.VoiceResponse()
    
    response.say('Our store is located at 123 Easy St.');
    response.sms({
        statusCallback: '/smsHandler.php'
    }, 'Store Location: 123 Easy St.');
    
    console.log(response.toString());
    
    <?php
      use SignalWire\LaML;
      $response = new LaML;
      $response->say('Our store is located at 123 Easy St.');
      $response->sms('Store Location: 123 Easy St.',
        ['statusCallback' => '/smsHandler.php']);
    
      echo $response;
    ?>
    
    using System;
    using Twilio.TwiML;
    using Twilio.TwiML.Voice;
    
    
    class Example
    {
        static void Main()
        {
            var response = new VoiceResponse();
            response.Say("Our store is located at 123 Easy St.");
            response.Sms("Store Location: 123 Easy St.",
                statusCallback: new Uri("/smsHandler.php"));
    
            Console.WriteLine(response.ToString());
        }
    }
    
    from signalwire.voice_response import VoiceResponse, Enqueue
    
    response = VoiceResponse()
    response.say('Our store is located at 123 Easy St.')
    response.sms('Store Location: 123 Easy St.', status_callback='/smsHandler.php')
    
    print(response)
    
    require 'signalwire/sdk'
    
    response =  Signalwire::Sdk::VoiceResponse.new
    response.say(message: 'Our store is located at 123 Easy St.')
    response.sms('Store Location: 123 Easy St.', status_callback: '/smsHandler.php')
    
    puts response
    

    In this example we provide a statusCallback URL. When the message is finished sending (not just enqueued), SignalWire will asynchronously request the statusCallback URL with the parameter SmsStatus. If the messages was successfully sent, SmsStatus will be sent. If the message failed to send, SmsStatus will be failed.

    <Stream>

    The <Stream> instruction makes it possible to send raw audio streams from a running phone call over WebSockets in near real time, to a specified URL. The audio frames themselves are base64 encoded, embedded in a json string, together with other information like sequence number and timestamp. The feature can be used with Speech-To-Text systems and others.

    Attributes

    An example on how to use Stream.

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
      <Start>
         <Stream url="wss://your-application.com/audiostream" />
      </Start>
    </Response>
    

    This LAML will instruct Signalwire to make a copy of the audio frames of the current call and send them in near real-time over WebSocket to wss://your-application.com/audiostream.

    will start the audio stream asynchronous manner it will continue with the next LAML instruction at once. In case there is no instruction, Signalwire disconnect the call.

    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.VoiceResponse()
    
    const start = response.start();
    start.stream({
            name: 'Example Audio Stream',
            url: 'wss://your-application.com/audiostream'
    });
    
    console.log(response.toString());
    
    <?
    use SignalWire\LaML;
    
    $response = new LaML;
    $start = $response->start();
    $stream = $start->stream(['url' => 'wss://your-application.com/audiostream']);
    $stream->parameter(['name' => 'FirstName', 'value' => 'Jane']);
    $stream->parameter(['name' => 'LastName', 'value' => 'Doe']);
    
    echo $response;
    
    ?>
    
    using System;
    using Twilio.TwiML;
    using Twilio.TwiML.Voice;
    
    
    class Example
    {
        static void Main()
        {
            var response = new VoiceResponse();
            var start = new Start();
            start.Stream(name: "Example Audio Stream", url: "wss://your-application.com/audiostream");
            response.Append(start);
    
            Console.WriteLine(response.ToString());
        }
    }
    
    from twilio.twiml.voice_response import Parameter, VoiceResponse, Start, Stream
    
    response = VoiceResponse()
    start = Start()
    stream = Stream(url='wss://your-application.com/audiostream')
    stream.parameter(name='FirstName', value='Jane')
    stream.parameter(name='LastName', value='Doe')
    start.append(stream)
    response.append(start)
    
    print(response)
    
    require 'signalwire/sdk'
    
    response =  Signalwire::Sdk::VoiceResponse.new
    response.start do |start|
        start.stream(url: 'wss://your-application.com/audiostream') do |stream|
            stream.parameter(name: 'FirstName', value: 'Jane')
            stream.parameter(name: 'LastName', value: 'Doe')
    end
    end
    
    puts response
    
    Attribute
    url Absolute or relative URL. A WebSocket connection to the url will be established and audio will start flowing towards the Websocket server. The only supported protocol is wss. For security reasons ws is NOT supported.
    name optional Unique name for the Stream, per Call. It is used to stop a Stream by name.
    track optional This attribute can be one of: inbound_track, outbound_track, both_tracks . Defaults to inbound_track. For both_tracks there will be both inbound_track and outbound_track events.
    statusCallback optional Absolute or relative URL. SignalWire will make a HTTP GET or POST request to this URL when a Stream is started, stopped or there is an error.
    statusCallbackMethod optional GET or POST. The type of HTTP request to use when requesting a statusCallback. Default is POST.



    For a statusCallback, SignalWire will send a request with the following parameters:

    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.
    StreamSid string The unique identifier for this Stream.
    StreamName string If defined, this is the unique name of the Stream. Defaults to the StreamSid.
    StreamEvent string One of stream-started, stream-stopped, or stream-error.
    StreamError string If an error has occurred, this will contain a detailed error message.
    Timestamp string The time of the event in ISO 8601 format.

    Custom Parameters

    To pass parameters towards the wss server is possible to include additional key value pairs. It can be done by using the nested LAML noun. These parameters will be added to the Start message, as json.

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
       <Start>
         <Stream url="wss://your-application.com/audiostream" >
            <Parameter name="Cookie" value ="948f9938-299a-d43e-0df4-af3a7eccb0ac"/>
            <Parameter name="Type" value ="SIP" />
          </Stream>
        </Start>
    </Response>
    
    

    Stopping a Stream

    It is possible to stop a stream at any time by name. For instance by naming the Stream "mystream", you can later use the unique name of "mystream" to stop the stream.

    <Start>
        <Stream name="mystream" url="wss://mystream.ngrok.io/audiostream" />
    </Start>
    
    <Stop>
       <Stream name="mystream" />
    </Stop>
    

    WebSocket Messages

    There are 4 separate types of events that occur during the Stream's life cycle. These events are represented via WebSocket Messages: Connected, Start, Media and Stop. Each message sent is a JSON string. The type of event which is occurring can be identified by using the event property of every JSON object.

    Connected Message

    The first message sent once a WebSocket connection is established is the Connected event. This message describes the protocol to expect in the following messages.

    Event
    event The string value of "connected"
    protocol Defines the protocol for the WebSocket connections lifetime. eg: "Call"
    version Semantic version of the protocol.

    Example Connected Message

    {
     "event": "connected",
     "protocol": "Call",
     "version": "0.2.0"
    }
    
    

    Start Message

    This message contains important information about the Stream and is sent immediately after the Connected message. It is only sent once at the start of the Stream.

    Event
    event The string value of start
    sequenceNumber Number used to keep track of message sending order. First message starts with number "1" and then is incremented.
    start An object containing Stream metadata
    start.streamSid The unique identifier of the Stream.
    start.accountSid The Account identifier that created the Stream.
    start.callSid The Call identifier from where the Stream was started.
    start.tracks An array of values that indicates what media flows to expect in subsequent messages. Values are one of "inbound" or "outbound" or both.
    start.customParameters An object that represents the Custom Parameters that where set when defining the Stream.
    start.mediaFormat An object containing the format of the payload in the Media Messages.
    start.mediaFormat.encoding The encoding of the data in the upcoming payload. Default is "audio/x-mulaw".
    start.mediaFormat.sampleRate The Sample Rate in Hertz of the upcoming audio data. Default value is 8000, which is the rate of PCMU.
    start.mediaFormat.channels The number of channels in the input audio data. Default value is 1. For both_tracks it will be 2.

    Example Start Message

    {
     "event": "start",
     "sequenceNumber": "2",
     "start": {
       "streamSid": "c0c7d59b-df06-435e-afbc-9217ce318390",
       "accountSid": "123abc",
       "callSid": "a30d16a5-0368-4104-afbf-14247e76a63d",
       "tracks": [
         "inbound",
         "outbound"
       ],
       "customParameters": {
         "FirstName": "Jane",
         "LastName": "Doe",
         "RemoteParty": "Bob",
       },
       "mediaFormat": {
         "encoding": "audio/x-mulaw",
         "sampleRate": 8000,
         "channels": 1
       }
     }
    }
    
    

    Media Message

    This message type encapsulates the raw audio data.

    Event
    event The string value of media
    sequenceNumber Number used to keep track of message sending order. First message starts with number "1" and then is incremented for each message.
    media An object containing media metadata and payload.
    media.track One of the strings inbound or outbound.
    media.chunk The chunk for the message. The first message will begin with number "1" and increment with each subsequent message.
    media.timestamp Presentation Timestamp in Milliseconds from the start of the stream.
    media.payload Raw audio encoded in base64.

    Example Media Messages

    Outbound

    {
     "event": "media",
     "sequenceNumber": "3",
     "media": {
       "track": "outbound",
       "chunk": "1",
       "payload": "iY//DwkP/4+Jj/8PCQ//j4mP/w8JD/+PiY//DwkP/4+Jj/8PCQ//j4mP/w8JD/+PiY//DwkP/4+Jj/8PCQ//j4mP/w8JD/+PiY//DwkP/4+Jj/8PCQ//j4mP/w8JD/+PiY//DwkP/4+Jj/8PCQ//j4mP/w8JD/+PiY//DwkP/4+Jj/8PCQ//j4mP/w8JD/+PiY//DwkP/4+Jj/8PCQ//jw=="
     }
    }
    

    Inbound

    {
     "event": "media",
     "sequenceNumber": "4",
     "media": {
       "track": "inbound",
       "chunk": "1",
       "timestamp": "5",
       "payload": "/4+Jj/8PCQ//j4mP/w8JD/+PiY//DwkP/4+Jj/8PCQ//j4mP/w8JD/+PiY//DwkP/4+Jj/8PCQ//j4mP/w8JD/+PiY//DwkP/4+Jj/8PCQ//j4mP/w8JD/+PiY//DwkP/4+Jj/8PCQ//j4mP/w8JD/+PiY//DwkP/4+Jj/8PCQ//j4mP/w8JD/+PiY//DwkP/4+Jj/8PCQ//j4mP/w8JDw=="
     }
    }
    

    Stop Message

    A stop message will be sent when the Stream is either stopped or the Call has ended.

    Example Stop Message

    {
     "event": "stop",
     "sequenceNumber": "5"
    }
    
    Event
    event The string value of stop
    sequenceNumber Number used to keep track of message sending order. First message starts with number "1" and then is incremented for each message.

    Notes on Usage

    • The url does not support query string parameters. To pass custom key value pairs to the WebSocket, make use of Custom Parameters instead.
    • There is a one to one mapping of a stream to a websocket connection, therefore there will be at most one call being streamed over a single websocket connection. Information will be provided so that you can handle handle multiple inbound connections and manage the association between the unique stream identifier (StreamSid) and the connection.
    • On any given call there are inbound and outbound tracks, inbound represents the audio Signalwire receives from the call, outbound represents the audio generated by Signalwire for the Call.

    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 { RestClient } = require('@signalwire/node')
    const response = new 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.

    MIME Types

    The following are the MIME types supported by SignalWire:

    Type
    audio/mp4 mpeg layer 4 audio
    audio/mpeg mpeg layer 3 audio
    audio/mpeg3 mpeg layer 3 audio
    audio/ogg ogg audio
    audio/vorbis audio compression format
    audio/vnd.wav wav format audio
    audio/ac3 codec format audio
    audio/amr codec format audio
    audio/midi musical instrument digital interface format
    image/jpeg jpeg format image
    image/gif graphics interchange format
    image/png portable network graphics format
    image/bmp bitmap image format
    text/plain text file format
    text/calendar text file format
    text/vcard text file format
    text/x-vcard text file format
    video/mpeg mpeg video format
    video/mp4 mpeg layer 4 video format
    video/quicktime quicktime video
    video/h264 video compression format
    video/3gp media container format

    <Message>

    An example message that responds to the sender.

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Message>Hello from SignalWire!</Message>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 or short code. If no from is specified, it defaults to the number that received the message. You can only specify from phone numbers or short codes 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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 { RestClient } = require('@signalwire/node')
    const response = new 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.

    Fax LaML

    Fax 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 fax.

    Overview

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

    Fax LaML allows you to control what SignalWire will do when you receive an incoming fax.

    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 fax, allowing you to respond dynamically and fluidly to the fax 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 fax:

    Parameter
    FaxSid string A unique identifier for the fax.
    AccountSid string The account that the fax was sent from.
    To string The number or SIP URI the fax will be sent to.
    From string The number or SIP From the fax was sent from.
    ApiVersion string The version of the SignalWire API.

    Responding to SignalWire

    An example of a LaML document that receives an incoming fax.

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
      <Receive action="/fax/received"/>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.FaxResponse()
    
    response.receive({ action: "/fax/received" })
    console.log(response.toString())
    
    using Twilio.TwiML;
    using Twilio.TwiML.Fax;
    using System;
    
    
    class Example
    {
        static void Main()
        {
            var response = new FaxResponse();
            response.Receive(action: "/fax/received"));
    
            Console.WriteLine(response.ToString());;
        }
    }
    
    from signalwire.fax_response import FaxResponse, Receive
    
    response = FaxResponse()
    response.receive(action="/fax/received")
    
    print(response)
    
    require 'signalwire/sdk'
    
    response = Signalwire::Sdk::FaxResponse.new do |response|
      response.receive(action: "/fax/received")
    end
    
    puts response.to_s
    
    <?php
      use SignalWire\LaML;
      $response = new LaML;
    
      $response->receive(array( 'action' => '/fax/received' ));
      echo $response;
    ?>
    

    When a fax 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.

    <Receive>

    The <Receive> verb tells SignalWire to receive an incoming fax, which results in the creation of a new Fax instance resource.

    Verb Attributes

    Attribute
    action optional The URL to request when a fax has failed or has been received.
    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.
    mediaType optional The type of media used to store fax media. Valid values are application/pdf or image/tiff. Default is application/pdf.
    pageSize optional The size to interpret incoming pages as. Valid values are letter, legal, or a4. Default is letter.

    Action Callback

    If the verb attribute action is specified, the action callback will include the Standard Request Parameters plus the following optional parameters:

    Parameter
    RemoteStationId optional The transmitting subscriber identification (TSID) reported by the fax machine that sent in the fax.
    FaxStatus optional The status of the fax.
    NumPages optional The number of pages received from a successful fax.
    MediaUrl optional The media URL to request to retrieve incoming media.
    ErrorCode optional The error code provides more information on a failed fax.
    ErrorMessage optional The message explaining the reason for fax failure.

    Examples

    Receive a Fax

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
      <Receive action="/fax/received"/>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.FaxResponse()
    
    response.receive({ action: "/fax/received" })
    console.log(response.toString())
    
    using Twilio.TwiML;
    using Twilio.TwiML.Fax;
    using System;
    
    
    class Example
    {
        static void Main()
        {
            var response = new FaxResponse();
            response.Receive(action: "/fax/received"));
    
            Console.WriteLine(response.ToString());;
        }
    }
    
    from signalwire.fax_response import FaxResponse, Receive
    
    response = FaxResponse()
    response.receive(action="/fax/received")
    
    print(response)
    
    require 'signalwire/sdk'
    
    response = Signalwire::Sdk::FaxResponse.new do |response|
      response.receive(action: "/fax/received")
    end
    
    puts response.to_s
    
    <?php
      use SignalWire\LaML;
      $response = new LaML;
    
      $response->receive(array( 'action' => '/fax/received' ));
      echo $response;
    ?>
    

    SignalWire will receive the incoming fax and provide a URL endpoint.

    Store Fax Image

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
      <Receive mediaType="image/tiff"></Receive>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.FaxResponse()
    
    response.receive({ mediaType: "image/tiff" })
    console.log(response.toString())
    
    using Twilio.TwiML;
    using Twilio.TwiML.Fax;
    using System;
    
    
    class Example
    {
        static void Main()
        {
            var response = new FaxResponse();
            response.Receive(mediaType: "image/tiff"));
    
            Console.WriteLine(response.ToString());;
        }
    }
    
    from signalwire.fax_response import FaxResponse, Receive
    
    response = FaxResponse()
    response.receive(media_type="image/tiff")
    
    print(response)
    
    require 'signalwire/sdk'
    
    response = Signalwire::Sdk::FaxResponse.new do |response|
      response.receive(media_type: "image/tiff")
    end
    
    puts response.to_s
    
    <?php
      use SignalWire\LaML;
      $response = new LaML;
    
      $response->receive(array( 'mediaType' => 'image/tiff' ));
      echo $response;
    ?>
    

    This example shows that the media from the incoming fax will be stored on SignalWire's server in TIFF format.

    <Reject>

    The <Reject> verb tells SignalWire to reject an incoming fax, which results in a status of canceled.

    Verb Attributes

    The <Reject> verb does not have any attributes that modify its behavior.

    Examples

    Fax Reject

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
      <Reject/>
    </Response>
    
    const { RestClient } = require('@signalwire/node')
    const response = new RestClient.LaML.FaxResponse()
    
    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 FaxResponse();
            response.Reject();
    
            Console.WriteLine(response.ToString());;
        }
    }
    
    from signalwire.fax_response import FaxResponse, Reject
    
    response = FaxResponse()
    response.reject()
    
    print(response)
    
    require 'signalwire/sdk'
    
    response = Signalwire::Sdk::FaxResponse.new do |response|
      response.reject
    end
    
    puts response.to_s
    

    SignalWire will reject the incoming fax.