TwiML verbs
Every TwiML verb with its attributes. All verbs live inside <Response> and execute in order.
<Say>
Speak text to the caller using text-to-speech.
Welcome to Ruut Voice.
| Parameter | Type | Description |
|---|---|---|
voice optional | string | TTS voice (e.g. alice, man). |
language optional | string | Language code (e.g. en-NG, en). |
loop optional | integer | Times to repeat (0 = infinite). Default 1. |
SDK: response.say("…", { voice: "alice", language: "en-NG" })
<Play>
Play an audio file. The element content is the audio URL.
https://cdn.example.com/greeting.mp3
| Parameter | Type | Description |
|---|---|---|
loop optional | integer | Times to repeat (0 = infinite). Default 1. |
SDK: response.play("https://cdn.example.com/greeting.mp3", { loop: 1 })
<Gather>
Collect DTMF digits (or a spoken keypress) from the caller, then request the action URL with the input.
Press 1 for sales. Press 2 for support.
No input received.
| Parameter | Type | Description |
|---|---|---|
action optional | string | URL to request when gathering finishes (with Digits). |
method optional | string | HTTP method for action: GET or POST. |
numDigits optional | integer | Number of digits to collect before proceeding. |
finishOnKey optional | string | Digit that ends gathering (e.g. #). |
timeout optional | integer | Seconds to wait for input. Default 5. |
actionOnEmptyResult optional | boolean | Request action even when no input is received. |
SDK: response.gather({ numDigits: 1, action: "/twiml/menu" }, (g) => g.say("Press 1 for sales."))
<Record>
Record the caller's voice — a message, a greeting, or a conversation — and optionally transcribe it.
Please leave a message after the tone.
| Parameter | Type | Description |
|---|---|---|
action optional | string | URL to request when recording completes. |
method optional | string | HTTP method for action. |
timeout optional | integer | Seconds of silence before finishing. Default 5. |
finishOnKey optional | string | Key that ends the recording. |
maxLength optional | integer | Maximum recording length in seconds. Default 3600. |
playBeep optional | boolean | Play a beep before recording. Default true. |
transcribe optional | boolean | Transcribe the recording after it completes. |
transcribeCallback optional | string | URL to receive the transcription webhook. |
recordingStatusCallback optional | string | URL to receive recording status webhooks. |
SDK: response.record({ transcribe: true, transcribeCallback: "/twiml/transcription" })
<Dial>
Transfer the call to a phone number, SIP URI, client, or conference. Nested nouns choose the target.
+2348000000009
| Parameter | Type | Description |
|---|---|---|
callerId optional | string | Caller ID presented to the destination. |
record optional | string | Recording mode: do-not-record, record-from-answer, record-from-ringing, record-from-answer-dual, record-from-ringing-dual. |
recordingTrack optional | string | Track(s) to record: inbound, outbound, or both. |
recordingStatusCallback optional | string | URL for recording status webhooks. |
recordingStatusCallbackMethod optional | string | HTTP method for the callback. |
recordingStatusCallbackEvent optional | string | Events to notify on (e.g. in-progress completed absent). |
timeout optional | integer | Seconds to ring before giving up. Default 60. |
Nested nouns
<Number>— dial an E.164 number.<Sip>— dial a SIP URI (e.g.sip:agent-1001@sip.ruut.chat).<Client>— dial a registered client/softphone identity.<Conference>— join a conference; see recording for recording conferences.
// Conference with recording
new VoiceResponse()
.dial({ record: "record-from-answer-dual" }, (d) => {
d.conference("support-room", { startConferenceOnEnter: true, endConferenceOnExit: false });
})
.toXml();
<Pause>
Wait for a number of seconds.
Checking your account.
| Parameter | Type | Description |
|---|---|---|
length optional | integer | Seconds to pause. Default 1. |
<Redirect>
Fetch new TwiML from a URL and continue executing from there.
https://app.example.com/twiml/next
| Parameter | Type | Description |
|---|---|---|
method optional | string | HTTP method for the URL: GET or POST. |
<Reject>
Reject an incoming call without answering (useful for blocking numbers).
| Parameter | Type | Description |
|---|---|---|
reason optional | string | Rejection reason: rejected or busy. |
<Hangup>
End the call immediately.
Goodbye.
<Connect>
Connect the call to a media stream (e.g. for a voice AI agent or live transcription).
| Parameter | Type | Description |
|---|---|---|
url optional | string | WebSocket URL to stream audio to (on <Stream>). |
name optional | string | Stream name. |
track optional | string | Track(s): inbound_track, outbound_track, or both_tracks. |
See the receive calls guide for a full IVR example, and the TwiML overview for structure and content-type notes.