***

title: play_and_collect
slug: /reference/python/relay/call/play-and-collect
description: Play audio and collect DTMF or speech input.
max-toc-depth: 3
---------------------

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

[collectaction]: /docs/server-sdks/reference/python/relay/actions

[calling-call-collect]: /docs/server-sdks/reference/python/relay/call#events

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

[play]: /docs/server-sdks/reference/python/relay/call/play

Play audio content as a prompt and simultaneously collect user input via DTMF
digits or speech recognition. Returns a
[`CollectAction`][collectaction] that resolves when
input is collected, the operation times out, or an error occurs.

<Note>
  The `CollectAction` resolves only on collect events, not on play events. This
  means `await action.wait()` blocks until the user provides input (or the
  operation terminates), not when the audio finishes playing.
</Note>

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

## **Parameters**

<ParamField path="media" type="list[dict]" required={true} toc={true}>
  List of media items to play as the prompt. Same format as
  [`play()`][play] media items.
</ParamField>

<ParamField path="collect" type="dict" required={true} toc={true}>
  Input collection configuration.
</ParamField>

<Indent>
  <ParamField path="collect.digits" type="dict" toc={true}>
    DTMF digit collection settings.
  </ParamField>

  <Indent>
    <ParamField path="collect.digits.max" type="int" toc={true}>
      Maximum number of digits to collect.
    </ParamField>

    <ParamField path="collect.digits.digit_timeout" type="float" toc={true}>
      Seconds to wait between digits before completing.
    </ParamField>

    <ParamField path="collect.digits.terminators" type="str" toc={true}>
      Characters that terminate digit collection (e.g., `"#"`).
    </ParamField>
  </Indent>

  <ParamField path="collect.speech" type="dict" toc={true}>
    Speech recognition settings.
  </ParamField>

  <Indent>
    <ParamField path="collect.speech.end_silence_timeout" type="float" toc={true}>
      Seconds of silence to wait before finalizing speech input.
    </ParamField>

    <ParamField path="collect.speech.speech_timeout" type="float" toc={true}>
      Maximum seconds to listen for speech.
    </ParamField>

    <ParamField path="collect.speech.language" type="str" toc={true}>
      Speech recognition language code (e.g., `"en-US"`).
    </ParamField>

    <ParamField path="collect.speech.hints" type="list[str]" toc={true}>
      Words or phrases to boost recognition accuracy.
    </ParamField>
  </Indent>
</Indent>

<ParamField path="volume" type="Optional[float]" toc={true}>
  Volume adjustment in dB for the prompt audio.
</ParamField>

<ParamField path="control_id" type="Optional[str]" toc={true}>
  Custom control ID. Auto-generated if not provided.
</ParamField>

<ParamField path="on_completed" type="Optional[Callable[[RelayEvent], Any]]" toc={true}>
  Callback invoked when collection completes.
</ParamField>

## **Returns**

[`CollectAction`][collectaction] -- An action handle with
`stop()`, `volume()`, `start_input_timers()`, and `wait()` methods.

## **Example**

```python {14}
from signalwire.relay import RelayClient

client = RelayClient(
    project="your-project-id",
    token="your-api-token",
    host="your-space.signalwire.com",
    contexts=["default"],
)

@client.on_call
async def handle_call(call):
    await call.answer()

    action = await call.play_and_collect(
        media=[{"type": "tts", "text": "Press 1 for sales, 2 for support."}],
        collect={
            "digits": {"max": 1, "digit_timeout": 5, "terminators": "#"},
        },
    )
    event = await action.wait()

    result = event.params.get("result", {})
    digits = result.get("digits", "")
    if digits == "1":
        await call.transfer("sales")
    elif digits == "2":
        await call.transfer("support")
    else:
        await call.hangup()

client.run()
```