Dial
Definition
The Dial verb connects the calling party with the dialed party. Once the call is set up, the participants can start talking.
When the call is ended successfully, or the dialed number is not reached, or the call is terminated, CarrierX will make a POST or GET request to the action URL.
If the Dial verb specifies an action URL, FlexML instructions after the Dial will not be executed. Control is tranferred to the Response returned from the action URL.
If no action URL is set, the call flow will move to the next verbs in the FlexML instructions.
You can also place a phone number inside the Number noun. This is done to allow specifying the additional parameters (e.g., sendDigits) when dialing a phone number. Refer to the this section for more information about the Number noun.
Additionally, you can use the Number noun for the simultaneous ring to several numbers feature.
When to Use
Use Dial when you want to connect the current caller to another phone number, SIP endpoint, or multiple phone numbers or SIP endpoints at once. Dial controls what happens if the call is answered, not answered, or terminated.
Dial can record a call, stream a call, or do both at the same time.
- To record a call, use the
recordattributes. - To stream a call, use the
streamattributes.
Dialworks with regular phone numbers. SIP URI dialing is supported only when routing through a configured trunk group (via a trunk group SID). Direct SIP-to-IP dialing (e.g., to arbitrary IP addresses) is not supported for security reasons.- Always handle your
actionURL to manage what happens next when aDialends, so you can gracefully redirect, play a message, or log the result.
Supported Attributes
These attributes can be used to modify the Dial verb. They are inserted as name-value pairs in the start-tag.
| Attribute | Data Type | Description |
|---|---|---|
| action | string | The link to another set of FlexML instructions. A request will be made to this URL when the call is ended or if the dialed party is not available. If no action URL is set, the rest of the verbs in the current FlexML instructions will be executed. The URL can be absolute or relative. When triggered, the callback includes standard call parameters such as CallStatus as well as detailed call timing fields with millisecond precision:
DialStartTime, DialEndTime, DialAnswerTime, DialCallDuration — timings specific to the last Dial operation. For more details about timing parameters included in callbacks, see Callback Timing Parameters. |
| background | boolean | When set to true, enables background dial mode. In this mode, audio from the current call is forked outbound to the specified number over SIP. FlexML execution continues immediately; the Dial verb does not block further instructions.
false. For details, see Background Dial. |
| callerId | string | The phone number that will appear on the caller ID of the called party. This phone number must be on the account, or have custom permission set up. Also supported for background dial calls. |
| callerName | string | The calling party CNAME that is used in the from field. |
| confirmKey | string | The key that the called party must press to start the phone talk. Values accepted in this field are: 0-9, #, and *. |
| confirmSound | string | The URL of the audio that contains the instructions for the key from the confirmKey field. It informs the called party which key they must press to start the talk. |
| containerSid | string | The secure ID of the container to which the recording will be written. |
| hangupOnStar | boolean | If this value is set to true, pressing * will hang up the call with the dialed number, and continue with the next FlexML instructions. Until * is pressed, the rest of the FlexML instructions will not be executed. |
| method | string | The type of request made to the action URL. Values accepted in this field are POST or GET. The default value is POST. |
| record | string | Determines whether or not to record the outbound call until hangup. Values accepted in this field are:
do-not-record. |
| recordDirection | string | The direction of the call that will be recorded. Values accepted in this field are:
any. |
| recordingStatusCallback | string | A callback is sent to this URL after the recording has ended. |
| recordingStatusCallbackEvent | string | The comma-separated list of events to be notified about. Options are completed, to indicate that the recording is successful, and failed, to indicate that the recording has failed. The default value is "completed,failed". |
| recordingStatusCallbackMethod | string | The method, either POST or GET that the callback to recordingStatusCallback is sent. The default value is POST. |
| ringing | string | Phone ringing management. Values accepted in this field are:
true if not specified. |
| stream | string | Determines whether or not to stream the outbound call audio. Values accepted in this field are:
do-not-stream. |
| streamEncoding | string | Determines the audio encoding format for the stream. Supported values:
|
| streamMaxLength | integer | The maximum length of the stream, in seconds. |
| streamName | string | A unique identifier for the stream. |
| streamTimestampStart | string | Defines how the timestamp attribute of the streamed media is represented. Values accepted in this field are:
|
| streamTrack | string | The audio track(s) to stream. Values accepted in this field are:
|
| streamUrl | string | The URL of the WebSocket server. Both ws and wss protocols are supported. |
| timeLimit | integer | The maximum number of seconds that the call will last. The default value is 0, meaning that the call time is not limited. Also applies to background dial calls. |
| timeout | integer | The number of seconds to wait for the destination number to answer. After the call times out, a request is made to the action URL. The default value is 30. |
| trim | string | Determines whether or not silence is removed from the beginning or ending of a recording. To trim the silence in the recording, set this field to trim-silence. The default value is do-not-trim. Also applies to background dial calls. |
-
recordDirection,recordingStatusCallback,recordingStatusCallbackEvent,recordingStatusCallbackMethod, andtrimare applicable only whenrecordis set torecord-from-answerorrecord-from-ringing. -
streamTrack,streamMaxLength,streamName,streamTimestampStart, andstreamUrlare applicable only whenstreamis set tostream-from-answerorstream-from-ringing.
Examples
To simply dial the number, include it directly inside the Dial verb without using the Number noun. In this case, FlexML instructions cannot include any additional parameters for the dialed number. In this example, the phone number inside the Dial tags will be dialed. The call total time will be limited to 15 seconds. The called party will be able to hang up by pressing the * key. If an action URL is added to the Dial verb as an attribute, a request will be made to that URL if the phone number cannot be reached, or when the call ends.
<Response>
<Dial timeLimit="15" hangupOnStar="true">15162065340</Dial>
</Response>
Dial with streaming
In this example, the Dial verb streams the call audio to a WebSocket server after the call is answered.
<Response>
<Dial stream="stream-from-answer" streamUrl="wss://example.com/stream" streamName="myStream" streamTrack="both"></Dial>
</Response>
Dial with streamEncoding
In this example, the Dial verb specifies the streamEncoding attribute to ensure audio is streamed using linear 16-bit encoding (audio/L16), which preserves HD quality if available.
<Response>
<Dial stream="stream-from-answer" streamEncoding="audio/L16" callerId="+14155550100" streamUrl="wss://example.com/stream" streamName="myStream" streamTrack="both">
+14155550101
</Dial>
</Response>
Number Noun
The Number noun can be nested inside the Dial verb. It specifies the DID number to be dialed. It supports dialing to standard phone numbers and can optionally specify a trunk group SID for forced routing.
You can append an @ symbol followed by a valid trunk group SID to force the call to be routed through that specific trunk group.
Example syntax:
<Dial>
<Number>15162065340@b435ee72-36f4-48f8-9204-ae62a3e73119</Number>
</Dial>
Direct SIP URI dialing to arbitrary IP addresses (for example, 12342342345@123.123.123.123) is not supported due to firewall restrictions. Instead, you can append an @ symbol followed by a valid trunk group SID to force routing through a specific trunk group.
When using background="true" in the Dial verb, only the first Number noun will be used - any additional numbers will be ignored. Simultaneous ringing is not supported in background dial mode.
Supported Attributes
| Attribute | Data Type | Description |
|---|---|---|
| sendDigits | string | The DTMF tones that will be played when the call is answered. This is especially useful when dialing a phone number with an extension. Values accepted in this field are: 0-9, #, *, ,, and the combinations of these characters. Each comma character defines a 0.5-second delay. |
CarrierX allows dialing to several numbers at once using the Number noun. Refer to the Simultaneous Ring to Several Numbers section of the Dial verb for more information about this.
Query Arguments
You can also send custom SIP headers using query arguments. Use the ? character after the phone number to add these headers. Multiple headers are joined with the XML-encoded & character.
In this example, two X- headers will be sent when dialing the phone number specified in the Number noun nested inside the Dial verb.
<Response>
<Dial>
<Number>15162065340?X-CustomHeader1=ABC&X-CustomHeader2=DEF</Number>
</Dial>
</Response>
The additional query arguments can be used to send custom headers inside the Number noun. Use the ? character after the phone number to add these headers. Several headers are joined with the XML-encoded & character.
Only X- headers are accepted as query arguments, any other headers or strings will be filtered out and not sent.
If you choose to send custom headers when dialing a phone number, you will need to additionally set the relay_sip_headers parameter of the Trunk object associated with your FlexML endpoint to successfully pass these headers to the destination.
Examples
DTMF with a Delay
In this example, once the call is answered, the system waits two seconds (four commas equal to 0.5-second each) before playing the 1928 DTMF tones.
<Response>
<Dial>
<Number sendDigits=",,,,1928">15162065340</Number>
</Dial>
</Response>
Forced Routing to a Trunk Group
In this example, the call to the number will be routed through a specific trunk group.
<Response>
<Dial>
<Number>15162065340@22a24d1b-e9ec-465d-9ff9-31b67817bb58</Number>
</Dial>
</Response>
Simultaneous Ring to Several Numbers
CarrierX supports dialing to several numbers at once. You need to specify the numbers in the Number noun tags inside the Dial verb. The first person to answer will be connected to the calling party. The calls to the other numbers will be hung up.
CarrierX supports up to 10 concurrent rings using the FlexML Dial verb.
You can see an example of the code that uses the simultaneous rings feature in our sample application, which is a part of the No-code CarrierX Apps collection.
Examples
Basic Simultaneous Ring
In this example, the phone numbers in the Number tags will be dialed all at the same time. The first person to answer is connected to the calling party.
<Response>
<Dial>
<Number>12345645585</Number>
<Number>96846465465</Number>
<Number>98133217461</Number>
</Dial>
</Response>
Simultaneous Ring with ConfirmKey and Recording
In this example, multiple phone numbers inside the Number tags will be dialed simultaneously. The first person to answer will be connected to the calling party, and they must press 1 (as instructed by the audio at confirmSound) to start the conversation. The call will be recorded starting from when it is answered, and the total call time is limited to 30 seconds.
<Response>
<Dial confirmKey="1" confirmSound="https://example.com/instructions.mp3" record="record-from-answer" timeLimit="30">
<Number>1234567890</Number>
<Number>0987654321</Number>
</Dial>
</Response>
Background Dial
Background dial lets you fork live call audio to a SIP connection, enabling use cases such as real-time transcription, voice recognition, and other audio processing applications.
Normally, the Dial verb is blocking: when executed, FlexML waits until the dialed call ends (either answered and completed, not answered, or failed) before continuing to the next verbs. Any verbs listed after Dial do not run until the dial completes.
When you set background="true", Dial becomes non-blocking. The outbound leg is initiated in parallel, audio from both directions is forked to your application, and FlexML execution continues immediately with the next verbs in your script. The flow does not wait for the background call to connect or finish.
Key differences from regular Dial
- Regular Dial: blocks FlexML until the dial attempt completes.
- Background Dial: non-blocking; execution continues immediately. Audio is forked outbound but not bridged.
Other characteristics
- Only the first
Numberspecified will be dialed; additional numbers are ignored. - Maximum of 3 concurrent background dial sessions are allowed (same as the background recording limit).
Example
<Response>
<Dial background="true" timeout="60">
<Number>18083842000</Number>
</Dial>
<Say>This message plays immediately while the background dial is active.</Say>
</Response>
Here, the caller's audio is forked to 18083842000 over SIP, while the call flow continues to play a message.
Callback Data
In addition to the standard callback fields the following fields are returned in the callback request body when the Dial verb completes:
- If an
actionURL is specified, these fields are sent immediately in the action request. - If no
actionURL is specified, FlexML continues with the next instruction, but the Dial-related fields are still included in all subsequent callbacks (including the final status callback).
| Attribute | Data Type | Description |
|---|---|---|
| AnswerTime | string | Timestamp when the call was fully connected and both parties could start talking. |
| CallDuration | integer | Duration in seconds from when the call was answered until it ended. Will be null if the call is still ongoing when the action URL is requested. |
| DialAnswerTime | string | Timestamp when the most recent Dial verb was fully connected. |
| DialCallDuration | integer | Duration in seconds of the talk time for the most recent Dial verb. |
| DialEndTime | string | Timestamp when the most recent Dial verb execution ended. |
| DialStartTime | string | Timestamp when the most recent Dial verb execution started. |
| EndTime | string | Timestamp (with millisecond precision) when the overall call ended. If the action callback is triggered before the call ends, this value will be null. |
| StartTime | string | Timestamzp (with millisecond precision) indicating when the FlexML flow initially started executing the Dial verb. |
If multiple Dial verbs are executed in the same call flow, the Dial* fields always reflect the most recent Dial verb.
If the callback occurs while the call is still active (e.g., an in-progress action callback), EndTime, CallDuration, and their Dial-specific equivalents may be null.
A typical callback returned when the Dial verb ends might look like this:
{
"AccountSid": "1234567890abcdef",
"AnswerTime": 1723480521.123,
"ApiVersion": "2.0",
"CallDuration": 17,
"CallerName": "Lucas",
"CallSid": "6aa6217e281e4872af59b79f813fdaf7",
"CallStatus": "completed",
"DialAnswerTime": 1723480521.123,
"DialCallDuration": 17,
"DialEndTime": 1723480538,
"DialStartTime": 1723480520,
"Direction": "inbound",
"EndTime": 1723480538,
"From": "15627317020"
"OriginalFrom": "15627317020",
"OriginalTo": "15162065599",
"PartnerSid": "32c51df0b2f54845aef695fcd07f3994",
"RequestUrl": "http://10.222.2.129:5005/stream",
"StartTime": 1723480518,
"To": "15162065599",
}
Early-Media Support for Ringing
With early_media_music and early_media_silence, you can now initiate media playback before the call is answered, using early media. This means the caller hears audio (music or silence), but the call leg to the callee is not yet answered, preserving signaling and avoiding billing triggers until answer.
These modes can reduce “click” artifacts or abrupt transitions when connecting — particularly useful for integrations that require a smooth audio handoff or want to defer formal answer until later in the call flow.
Example
<Response>
<Dial ringing="early_media_music" timeLimit="60">
1234567890
</Dial>
</Response>
This example will play early-media music to the caller without answering the call while dialing the destination. If the call is answered, the flow proceeds normally; if not, you can handle timeout or fallback accordingly.
StreamParameter
You can use the StreamParameter noun inside the Dial verb to pass custom key/value pairs along with the dialed call. This works in the same way as the Parameter noun that is used with Stream. Each StreamParameter requires a name and a value.
For more details on supported attributes, see Parameter.
Example
<Response>
<Dial>
<StreamParameter name="FirstName" value="John"/>
<StreamParameter name="LastName" value="Cleese"/>
15551234567
</Dial>
</Response>
Common Pitfalls
- If
actionis set, any verbs afterDialwon't run. TheResponsefrom theactionURL is executed. - To pass SIP headers or custom headers, use
?X-Header=Valuein theNumbernoun. - Remember to set
relay_sip_headersin your Trunk if you pass custom SIP headers.
Nesting Rules
-
You can nest the Number noun within the
Dialverb. - You can nest
StreamParameterwithinDialto pass custom key/value pairs for the dial stream.StreamParameterbehaves exactly like theParameternoun (same supported attributes and restrictions), but is scoped toDial. - You cannot nest the
Dialverb within other FlexML verbs.