Speak text on a call
Text-to-speech (TTS) reads text aloud on a live call, such as a booking confirmation or a menu.
You give SignalWire the text and a voice from the TTS voice catalog, and it speaks
the text into the call. Start with the SWML say: URL, then speak a message to your own phone
with SWML, Relay, or REST.
Speak text with a SWML say URL
In SWML’s play and prompt methods, a say: URL takes the place of an audio file URL.
SignalWire speaks whatever follows say: instead of fetching a file:
say_voice picks the voice, as an engine.voice string from the catalog. say_language and
say_gender are also available. Set them on one verb, or once for the whole document with
set; a value on a verb overrides the document-wide one.
Default voices and engines can change. Set a full engine.voice string so the call keeps
sounding the same.
These SWML methods speak text:
playspeaks asay:URL inurl. To mix speech with audio files and pauses, list several URLs inurls.promptspeaks asay:URL inplay, then collects key presses or speech.payspeaks custom payment prompts written asSayactions, with the text inphrase.aiagents speak in the voice set inlanguages. See Voice and language in the Server SDKs.
Relay clients and the REST Calling API speak a tts media item instead of a say: URL. Its
text, voice, language, and gender fields match the SWML settings above.
Prepare to speak text on a call
Start from working call setup in Make and receive calls, and test with a phone you can answer.
A trial project only calls and receives calls from numbers you’ve purchased or verified. Prepare for your first call shows how to verify your phone.
TTS counts as an artificial voice under consent, do-not-call, and calling-hour rules. Read the TCPA guide before you call anyone but yourself.
Replace these values in the samples:
Speak text on a call via SWML
The Server SDKs’ SWML builder writes the play for you: say() takes the text and the voice.
This program builds the document and places a call with it, as in
Place a call via SWML.
dial() signature depends on the SDK version
@signalwire/sdk@2.0.5 takes a single options object. Newer releases take the positional
dial(from, to, options) form.
Run the program and answer your phone. You hear the confirmation in the Rachel voice, then the
call ends. If the phone never rings, check that <YOUR_CALLER_ID> is a number in your Space or a
verified caller ID. If you hear a different voice, the voice string isn’t in SignalWire’s
catalog: voices from your own provider account fall back to a default
(Custom and cloned voices).
To speak to people who call your number, serve the same document as in Answer a call via SWML.
Speak text on a call via WebSocket (Relay)
A Relay client speaks with play() and a tts media item. Use it when your code needs to react
as the speech plays or ends, such as hanging up or asking the next question. This program dials
your phone as in Place a call via WebSocket (Relay), speaks the confirmation, and
hangs up when the speech finishes.
Run the program and answer your phone. You hear the confirmation, then the call ends. To speak on calls to your number instead, see Answer a call via WebSocket (Relay).
play() takes a list of media items and plays them in order, so tts items can mix with
audio, silence, and ringtone items. It returns an action once SignalWire accepts the
command: stop(), pause(), resume(), and volume() control the speech while it plays, and
volume() takes decibels from -40 to 40. To speak a menu and collect the caller’s input, use the
Relay client’s play-and-collect method, which takes the same media items.
Speak text on a call in progress via REST
When a different process needs to speak on a call that’s already up, such as a backend job
announcing an update, send calling.play with the call’s ID. It takes the same
tts media items as Relay. control_id names the playback so later commands can address it.
play() signature depends on the SDK version
@signalwire/sdk@2.0.5 takes the call ID and a single options object. Newer releases take the
positional play(callId, play, options) form.
The command returns once SignalWire accepts it. Your status_url then receives the playback’s
control_id and state: playing when the speech starts, then finished, or error if it
failed. See the webhooks guide to set up the endpoint.
direction sets who hears the speech: listen (the default) plays it to the caller, speak to
the called party, and both to both. loop repeats the list, and 0 repeats it until you stop
it. To control the speech, send calling.play.stop, calling.play.pause, calling.play.resume,
or calling.play.volume with the same control_id.
The REST Calling API can’t speak and collect input in one step. To speak a menu, start the call
with a SWML prompt or control it from a Relay client.