Appearance
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
| Field | Type | Description |
|---|---|---|
type | string | Always "dtmf_received" |
digit | string | The key pressed: 0–9, *, or # |
session | object | Session 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 '', 204Node.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:
0–9,*,# - Each key press triggers a separate
dtmf_receivedevent - DTMF events can occur at any point during the call, including while the assistant is speaking
Next Steps
- Action Types - How to respond to events
- User Speak Event - Voice input alternative