> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zeroruntime.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# DTMF Events

> Listen for caller key presses during a call to capture input and drive IVR flows.

DTMF (Dual-Tone Multi-Frequency) events occur when a caller presses keys (0–9, \*, #) during a call. Agents can listen for these events to capture input and respond immediately.

<Note>
  This page covers handling DTMF from your **agent code**. For the SIP gateway setup and the raw `DTMF_EVENT` payload, see [DTMF Events](/telephony/managing-calls/dtmf-events) in the Telephony platform docs.
</Note>

## Features

* Detect key presses during a call session.
* Deliver events in real time to the agent.
* Handle events with a user-defined callback.
* Trigger actions or IVR flows based on the input.

## Activation

DTMF detection is enabled on the Inbound SIP gateway, in one of two ways.

<Tabs>
  <Tab title="Via Dashboard">
    When creating an Inbound SIP gateway in the Zero Runtime dashboard, enable the `DTMF` option.

    <Frame>
      <img src="https://assets.videosdk.live/images/DTMF-events.png" alt="DTMF events" />
    </Frame>
  </Tab>

  <Tab title="Via API">
    Set `enableDtmf` to `true` when creating or updating a SIP gateway.

    ```bash theme={null}
    curl -H 'Authorization: $YOUR_TOKEN' \
      -H 'Content-Type: application/json' \
      -d '{
        "name": "Twilio Inbound Gateway",
        "enableDtmf": "true",
        "numbers": ["+0123456789"]
      }' \
      -XPOST https://api.videosdk.live/v2/sip/inbound-gateways
    ```
  </Tab>
</Tabs>

Once the gateway has DTMF enabled, implement the handler as shown below.

## Setup

Create a `DTMFHandler` and register per-digit (and optional per-sequence) handlers using `on_digit()` and `on_sequence()`. Attach the handler to your agent's `Pipeline`. Once the session is started with `zrt.invoke()`, the runtime automatically delivers DTMF events to the registered handlers.

<CodeGroup>
  ```python title="main.py" Python theme={null}
  from zrt import Pipeline, DTMFHandler
  from zrt.plugins import DeepgramSTT, GoogleLLM, CartesiaTTS, TurnDetector
  from zrt.inference import AICousticsDenoise

  dtmf_handler = DTMFHandler()

  async def route_sales(digit: str):
      await agent.session.say("Routing you to Sales. How can I help?")

  async def route_support(digit: str):
      await agent.session.say("Routing you to Support. What issue are you facing?")

  dtmf_handler.on_digit("1", route_sales)
  dtmf_handler.on_digit("2", route_support)

  # Match a multi-digit sequence (e.g. a PIN)
  dtmf_handler.on_sequence(
      "1234",
      lambda seq: agent.session.say("PIN accepted.")
  )

  pipeline = Pipeline(
      stt=DeepgramSTT(),
      llm=GoogleLLM(),
      tts=CartesiaTTS(),
      turn_detector=TurnDetector(model="echo-large"),
      dtmf_handler=dtmf_handler,
      denoise=AICousticsDenoise(model_id="quail-vf-2.2-l-16khz"),
  )
  ```
</CodeGroup>

<Note>
  A `DTMFHandler` attached to the `Pipeline` automatically subscribes to the room's DTMF events—no manual subscription is required. Register per-digit and per-sequence handlers with `on_digit()` and `on_sequence()` to build interactive IVR flows and respond to caller input.
</Note>

## What's Next

<CardGroup cols={2}>
  <Card title="Call Transfer" icon="phone-arrow-right" href="/build/telephony/call-transfer">
    Move a live call to another number.
  </Card>

  <Card title="Voice Mail Detection" icon="voicemail" href="/build/telephony/voicemail-detection">
    Handle voicemail on outbound calls.
  </Card>
</CardGroup>

## References

<Tabs>
  <Tab title="Python">
    #### SDK Reference

    <CardGroup cols={2}>
      <Card title="DTMF Handler" icon="hashtag" href="/api-reference/python/core/tools-and-mcp#dtmfhandler">
        DTMF Handler in the Python API reference.
      </Card>
    </CardGroup>
  </Tab>
</Tabs>
