Custom Audio

The SDK supports uploading your own custom audio to later play out within a workflow. In this section, we will discuss how to upload an audio file and play it in a workflow.


URN Type for Custom Audio

The target URN that is needed to be passed into the play() and playAndWait() functions is an interaction URN.

Uploading an Audio File

Using the Relay CLI you can upload your own audio files to playback inside a workflow. To start, select a supported audio file: today we support .wav files with 16kHz sample rate, 16 bits per sample, mono, and shorter than 30 seconds in duration. For the name, pick a unique value, and remember what it is, you'll need it later for play.

$ relay login
$ relay audio create --help
$ relay audio create --name emergency --file emergency_audio.wav
Uploaded 'emergency' with ID 'hKDjDJc4sTDMIVx9C2WQmXC'

We can then list the audio files we've uploaded on this account with the audio:list command:

$ relay audio list
=== Uploaded Audio Files
Id                      Short name  Audio format
hKDjDJc4sTDMIVx9C2WQmXC emergency   wave

And if you later choose to, you can delete this audio file, using the id shown in the relay audio list command:

$ relay audio delete --id hKDjDJc4sTDMIVx9C2WQmXC

Playing an Audio File in a Workflow

To play this audio file from inside a workflow, we can use the play() or playAndWait() command. The URI in the play methods are prefixed with relay-static:// and then append the name you used during upload on the -n argument.

Here is an example of a custom audio being played on a device:

workflow.on(Event.INTERACTION_STARTED, async({source_uri: interaction_uri}) => {
    await relay.say(interaction_uri, 'This is an emergency!')
  	// Play the custom audio
    await relay.playAndWait(interaction_uri, 'relay-static://emergency')
async def lifecycle_handler(workflow, itype, interaction_uri, reason):
  if itype == relay.workflow.TYPE_STARTED:
    await workflow.say(interaction_uri, 'This is an emergency!')
    # Play the custom audio
    await workflow.play_and_wait(interaction_uri, 'relay-static://emergency')
public override async void OnInteractionLifecycle(IDictionary<string, object> dictionary)
  var type = (string) dictionary["type"];

  if (type == InteractionLifecycleType.Started)
    var interactionUri = (string) dictionary["source_uri"];
    await Relay.Say(interactionUri, 'This is an emergency!');
    // Play the custom audio
    await Relay.PlayAndWait(interactionUri, 'relay-static://emergency')
public void onInteractionLifecycle(Relay relay, InteractionLifecycleEvent lifecycleEvent) {
  super.onInteractionLifecycle(relay, lifecycleEvent);
  String interactionUri = lifecycleEvent.sourceUri;

  if (lifecycleEvent.isTypeStarted()) {
  	relay.say(interactionUri, "This is an emergency!");
    // Play the custom audio
    relay.playAndWait(interactionUri, "relay-static://emergency");
api.OnInteractionLifecycle(func(interactionLifecycleEvent sdk.InteractionLifecycleEvent) {
  interactionUri := interactionLifecycleEvent.SourceUri

  if interactionLifecycleEvent.LifecycleType == "started" {
    api.Say(interactionUri, "This is an emergency!", sdk.ENGLISH)
    // Play the custom audio
    api.PlayAndWait(interactionUri, "relay-static://emergency")