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

# on_agent_dtmf()

> Observe keypad presses sent by the agent

Register a handler that fires whenever the **agent** presses DTMF digits on the keypad.

<Tabs>
  <Tab title="Python">
    This callback covers both ways the agent's digits get pressed:

    * **Agentic** — the agent decided to press the digits itself, which it can do once you have called `call.set_agent_dtmf(enabled=True)` (e.g. to work through an IVR menu on a call it placed).
    * **Developer-requested** — you asked for the digits explicitly with `call.send_dtmf(...)`.

    The two are distinguished by `requested_by`, so a single handler can log every tone the agent sends.

    <Note>
      **Agent keypresses only:** for digits pressed by the person on the other end of the call, use [`on_caller_dtmf`](/sdk-reference/on-caller-dtmf) instead.
    </Note>

    The `AgentDTMFSentEvent` is a pydantic model imported from `guava.events`:

    ```python theme={null}
    from guava.events import AgentDTMFSentEvent

    class AgentDTMFSentEvent(BaseEvent):
        event_type: Literal["agent-dtmf"] = "agent-dtmf"
        digits: list[Literal["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "#", "A", "B", "C", "D"]]
        requested_by: Literal["agent", "developer"] = "agent"
    ```
  </Tab>

  <Tab title="TypeScript">
    This callback covers both ways the agent's digits get pressed:

    * **Agentic** — the agent decided to press the digits itself, which it can do once you have called `call.setAgentDtmf(true)` (e.g. to work through an IVR menu on a call it placed).
    * **Developer-requested** — you asked for the digits explicitly with `call.sendDtmf(...)`.

    The two are distinguished by `requested_by`, so a single handler can log every tone the agent sends.

    <Note>
      **Agent keypresses only:** for digits pressed by the person on the other end of the call, use [`onCallerDtmf`](/sdk-reference/on-caller-dtmf) instead.
    </Note>

    The `AgentDTMFSentEvent` type is exported from `@guava-ai/guava-sdk`:

    ```typescript theme={null}
    import type { AgentDTMFSentEvent } from "@guava-ai/guava-sdk";

    type AgentDTMFSentEvent = {
      event_type: "agent-dtmf";
      digits: ("0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "*" | "#" | "A" | "B" | "C" | "D")[];
      requested_by: "agent" | "developer"; // default: "agent"
    };
    ```
  </Tab>
</Tabs>

<Info>
  **Digits are reported, not confirmed:** the event fires when the agent sends the tones, which is the same moment the digits are handed to the carrier. It is not an acknowledgement that the far end registered them.
</Info>

## Signature

<Tabs>
  <Tab title="Python">
    ```python signature theme={null}
    @agent.on_agent_dtmf
    def on_agent_dtmf(call: guava.Call, event: AgentDTMFSentEvent) -> None:
        ...
    ```

    | Parameter | Type | Description |
    | - | - | - |
    | `call` | `Call` | The active call object. |
    | `event` | `AgentDTMFSentEvent` | Contains `digits` (list of strings): the keys the agent pressed, in order; and `requested_by` (string): `'agent'` if the agent chose to press them, `'developer'` if they came from `send_dtmf()`. |

    **Return value:** `None`
  </Tab>

  <Tab title="TypeScript">
    ```typescript signature theme={null}
    agent.onAgentDtmf((call: guava.Call, event: AgentDTMFSentEvent) => Promise<void>);
    ```

    | Parameter | Type | Description |
    | - | - | - |
    | `call` | `Call` | The active call object. |
    | `event` | `AgentDTMFSentEvent` | Contains `digits` (array of strings): the keys the agent pressed, in order; and `requested_by` (string): `'agent'` if the agent chose to press them, `'developer'` if they came from `sendDtmf()`. |

    **Return value:** `Promise<void>`
  </Tab>
</Tabs>

## Example

<Tabs>
  <Tab title="Python">
    ```python controller.py theme={null}
    import logging

    from guava.events import AgentDTMFSentEvent

    @agent.on_call_start
    def on_call_start(call: guava.Call):
        # Let the agent press digits on its own to work through IVR menus.
        call.set_agent_dtmf(enabled=True)

    @agent.on_agent_dtmf
    def on_agent_dtmf(call: guava.Call, event: AgentDTMFSentEvent):
        logging.info(
            "Agent pressed %s (requested by %s)",
            "".join(event.digits),
            event.requested_by,
        )
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript controller.ts theme={null}
    import * as guava from "@guava-ai/guava-sdk";
    import type { AgentDTMFSentEvent } from "@guava-ai/guava-sdk";

    agent.onCallStart(async (call: guava.Call) => {
      // Let the agent press digits on its own to work through IVR menus.
      await call.setAgentDtmf(true);
    });

    agent.onAgentDtmf(async (call: guava.Call, event: AgentDTMFSentEvent) => {
      console.log(`Agent pressed ${event.digits.join("")} (requested by ${event.requested_by})`);
    });
    ```
  </Tab>
</Tabs>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.