Skip to content

DTMF Received Event

Triggered when the user presses a key on their phone keypad during a call.

Event Structure

json
{
  "type": "dtmf_received",
  "digit": "1",
  "session": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "account_id": "account-123",
    "phone_number": "+1234567890",
    "direction": "inbound",
    "from_phone_number": "+9876543210",
    "to_phone_number": "+1234567890"
  }
}

Fields

FieldTypeDescription
typestringAlways "dtmf_received"
digitstringThe key pressed: 09, *, or #
sessionobjectSession information (see Base Event Structure)

Example

IVR Menu

python
@app.route('/webhook', methods=['POST'])
def webhook():
    event = request.json

    if event['type'] == 'session_start':
        return jsonify({
            'type': 'speak',
            'session_id': event['session']['id'],
            'text': 'Press 1 for sales, press 2 for support.'
        })

    if event['type'] == 'dtmf_received':
        digit = event['digit']
        session_id = event['session']['id']

        if digit == '1':
            return jsonify({
                'type': 'transfer',
                'session_id': session_id,
                'transfer_to': '+49211100200'
            })
        elif digit == '2':
            return jsonify({
                'type': 'transfer',
                'session_id': session_id,
                'transfer_to': '+49211100201'
            })
        else:
            return jsonify({
                'type': 'speak',
                'session_id': session_id,
                'text': 'Invalid selection. Press 1 for sales, press 2 for support.'
            })

    return '', 204

Node.js

javascript
app.post('/webhook', (req, res) => {
  const event = req.body;

  if (event.type === 'dtmf_received') {
    const { digit } = event;
    console.log(`User pressed: ${digit}`);

    if (digit === '#') {
      return res.json({
        type: 'hangup',
        session_id: event.session.id
      });
    }
  }

  res.status(204).send();
});

TypeScript SDK

typescript
const assistant = AiFlowAssistant.create({
  onDtmfReceived: async (event) => {
    console.log(`User pressed: ${event.digit}`);

    if (event.digit === '1') {
      return {
        type: 'transfer',
        session_id: event.session.id,
        transfer_to: '+49211100200'
      };
    }

    return {
      type: 'speak',
      session_id: event.session.id,
      text: `You pressed ${event.digit}.`
    };
  },
});

Use Cases

  • IVR menus — route calls based on key presses
  • PIN entry — collect numeric input without speech recognition
  • Confirmation flows — press 1 to confirm, 2 to cancel
  • Accessibility — provide keypad alternatives to voice commands

Notes

  • All standard DTMF tones are supported: 09, *, #
  • Each key press triggers a separate dtmf_received event
  • DTMF events can occur at any point during the call, including while the assistant is speaking

Next Steps