***

title: play
slug: /reference/typescript/relay/call/play
description: Play audio content on a call.
max-toc-depth: 3
---------------------

For a complete index of all SignalWire documentation pages, fetch https://signalwire.com/docs/llms.txt

[playaction]: /docs/server-sdks/reference/typescript/relay/actions

[calling-call-play]: /docs/server-sdks/reference/typescript/relay/call#events

[call-events]: /docs/server-sdks/reference/typescript/relay/call#events

[play]: /docs/swml/reference/play

[swml-play-reference]: /docs/swml/reference/play

Play audio content on the call. Supports TTS (text-to-speech), audio file URLs,
silence, and ringtone. Returns a [`PlayAction`][playaction]
that you can use to pause, resume, stop, adjust volume, or wait for completion.

<Info>
  This method emits [`calling.call.play`][calling-call-play] events. See [Call Events][call-events] for payload details.
</Info>

<Info>
  This method corresponds to the SWML [`play`][play] verb. See the
  [SWML play reference][swml-play-reference] for the full specification.
</Info>

## **Parameters**

<ParamField path="media" type={"Record<string, unknown>[]"} required={true} toc={true}>
  Array of media items to play. Each item is an object with a `type` key and
  type-specific fields:

  * `{ type: 'tts', text: 'Hello', language: 'en-US', gender: 'female' }` -- text-to-speech
  * `{ type: 'audio', url: 'https://example.com/audio.mp3' }` -- audio file URL
  * `{ type: 'silence', duration: 2 }` -- silence for a duration in seconds
  * `{ type: 'ringtone', name: 'us' }` -- play a standard ringtone
</ParamField>

<ParamField path="volume" type="number | undefined" toc={true}>
  Volume adjustment in dB, from `-40.0` to `40.0`.
</ParamField>

<ParamField path="direction" type="string | undefined" toc={true}>
  Audio direction. Valid values:

  * `"listen"` -- play to the caller only
  * `"speak"` -- play to the remote party only
  * `"both"` -- play to both sides
</ParamField>

<ParamField path="loop" type="number | undefined" toc={true}>
  Number of times to repeat the media. `0` loops indefinitely.
</ParamField>

<ParamField path="controlId" type="string | undefined" toc={true}>
  Custom control ID for this operation. Auto-generated if not provided.
</ParamField>

<ParamField path="onCompleted" type="(event: RelayEvent) => void | Promise<void>" toc={true}>
  Callback invoked when playback reaches a terminal state. Can be a regular function or async function.
</ParamField>

## **Returns**

`Promise<`[`PlayAction`][playaction]`>` -- An action handle with
`stop()`, `pause()`, `resume()`, `volume()`, and `wait()` methods.

## **Examples**

### Text-to-Speech

```typescript {11}
import { RelayClient } from '@signalwire/sdk';

const client = new RelayClient({
  project: process.env.SIGNALWIRE_PROJECT_ID!,
  token: process.env.SIGNALWIRE_TOKEN!,
  contexts: ['default']
});

client.onCall(async (call) => {
  await call.answer();
  const action = await call.play([{ type: 'tts', text: 'Welcome to SignalWire!' }]);
  await action.wait();
});

await client.run();
```

### Audio File with Loop

```typescript {12}
import { RelayClient } from '@signalwire/sdk';

const client = new RelayClient({
  project: process.env.SIGNALWIRE_PROJECT_ID!,
  token: process.env.SIGNALWIRE_TOKEN!,
  contexts: ['default']
});

client.onCall(async (call) => {
  await call.answer();
  // Play hold music on loop
  const action = await call.play(
    [{ type: 'audio', url: 'https://example.com/hold-music.mp3' }],
    { loop: 0, direction: 'listen' }
  );
  // Later, stop the music
  await action.stop();
});

await client.run();
```

### Multiple Media Items

```typescript {11}
import { RelayClient } from '@signalwire/sdk';

const client = new RelayClient({
  project: process.env.SIGNALWIRE_PROJECT_ID!,
  token: process.env.SIGNALWIRE_TOKEN!,
  contexts: ['default']
});

client.onCall(async (call) => {
  await call.answer();
  const action = await call.play([
    { type: 'tts', text: 'Please hold while we connect you.' },
    { type: 'silence', duration: 1 },
    { type: 'audio', url: 'https://example.com/hold-music.mp3' },
  ]);
  await action.wait();
});

await client.run();
```