You can stack multiple hooks to handle different moments in the same call. This example warns the caller at 8 minutes and again at 9 minutes, then ends the call automatically after three rounds of silence:
{
"maxDurationSeconds": 600,
"hooks": [
{
"on": "call.timeElapsed",
"options": { "seconds": 480 },
"do": [{ "type": "say", "exact": "We're approaching our time limit for this call." }]
},
{
"on": "call.timeElapsed",
"options": { "seconds": 540 },
"do": [{ "type": "say", "exact": "We have about one minute left." }]
},
{
"on": "customer.speech.timeout",
"options": { "timeoutSeconds": 30, "triggerMaxCount": 3, "triggerResetMode": "onUserSpeech" },
"do": [
{ "type": "say", "exact": "I'll be ending the call now." },
{ "type": "tool", "tool": { "type": "endCall" } }
]
}
]
}
A filters array can further scope a hook — for instance, only running a fallback message-and-transfer sequence when a call is ending due to a pipeline error:
{
"on": "call.ending",
"filters": [
{ "type": "oneOf", "key": "call.endedReason", "oneOf": ["pipeline-error"] }
],
"do": [
{ "type": "say", "exact": "I apologize for the technical difficulty. Let me transfer you." },
{
"type": "tool",
"tool": {
"type": "transferCall",
"destinations": [{ "type": "number", "number": "+1234567890", "callerId": "+1987654321" }]
}
}
]
}