Voice Tools
Voice Approvals (HITL)
Get verbal confirmation from callers before executing high-stakes actions like payments, bookings, or data changes.
Voice Approvals (HITL)
The Voice Approvals tool implements Human-in-the-Loop (HITL) for voice calls. Before executing high-stakes actions — payments, bookings, permanent changes — the agent asks for verbal confirmation and handles three intents: approve, reject, and clarify.
How It Works
Agent: "I'd like to place your order for $45.00. Should I go ahead?"
Caller: "Yes, go ahead."
-> Agent calls record_approval_decision with decision="approved"
-> Agent executes the action
-- OR --
Caller: "Wait, how much was shipping?"
-> Agent answers the clarification question naturally
-> Agent re-asks for confirmation
Caller: "Okay yes, that works."
-> Agent calls record_approval_decision with decision="approved"Approval Modes
| Mode | Behavior |
|---|---|
blocking | Agent cannot proceed until explicit approval or rejection |
confirm_tools | Agent asks confirmation before ANY tool that modifies external state |
audit | Logs approval requests but doesn't block execution |
Configuration
{
"voiceApprovalEnabled": true,
"voiceApprovalMode": "blocking",
"voiceApprovalMaxClarifications": 3,
"voiceApprovalTimeoutMinutes": 5,
"voiceApprovalPrompt": ""
}| Setting | Type | Default | Description |
|---|---|---|---|
voiceApprovalEnabled | boolean | false | Enable voice HITL approvals |
voiceApprovalMode | string | blocking | Mode: blocking, confirm_tools, audit |
voiceApprovalMaxClarifications | integer | 3 | Max clarification questions before forcing yes/no |
voiceApprovalTimeoutMinutes | integer | 5 | Approval timeout in minutes |
voiceApprovalPrompt | string | — | Custom approval protocol prompt (overrides defaults) |
LLM Tools
request_voice_approval
Request verbal confirmation from the caller before a high-stakes action.
Parameters:
action_description: string (what the agent wants to do)
impact_summary: string (brief summary of the impact)
Returns: Instructions for the LLM to speak the confirmation questionrecord_approval_decision
Record the caller's approval or rejection.
Parameters:
decision: string ("approved" or "rejected")
reason: string (optional reason)
Returns: Confirmation of the recorded decisionThree-Intent Handling
The LLM acts as a natural-language state machine:
- APPROVE — "Yes", "Go ahead", "Sure", "Do it" -> calls
record_approval_decisionwithdecision='approved' - REJECT — "No", "Cancel", "Never mind" -> calls
record_approval_decisionwithdecision='rejected' - CLARIFY — "Wait, how much?", "What's included?" -> Agent answers naturally, then re-asks. No tool call for clarifications.
Confirm Tools Mode
In confirm_tools mode, the agent automatically asks for confirmation before calling ANY tool that modifies external state:
- Creating records
- Sending messages
- Processing payments
- Booking appointments
- Updating databases
- Triggering webhooks
Read-only tools (lookups, searches, fetching information) are exempt.
Example — Create Agent with Voice Approvals
curl -X POST https://api.thinnest.ai/v1/agents \
-H "Authorization: Bearer $THINNESTAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Order Agent with Approvals",
"model": "gpt-4o",
"instructions": "You help customers place orders. Before processing any payment or order, you MUST get verbal confirmation from the caller.",
"voiceEnabled": true,
"transcriber": { "provider": "deepgram", "model": "nova-2-conversationalai" },
"voice": { "provider": "deepgram", "voiceId": "aura-2-thalia-en" },
"voiceApprovalEnabled": true,
"voiceApprovalMode": "blocking",
"voiceApprovalMaxClarifications": 3,
"voiceApprovalTimeoutMinutes": 5
}'System Prompt Example
Before performing any action that involves money, permanent changes, scheduling,
or sensitive operations, you MUST get verbal confirmation from the caller.
1. Call request_voice_approval with a description and impact summary
2. Speak the confirmation question naturally
3. Handle the response:
- APPROVE -> call record_approval_decision with decision='approved'
- REJECT -> call record_approval_decision with decision='rejected'
- CLARIFY -> answer naturally, then re-ask
4. Maximum 3 clarifications. If exceeded, summarize and ask for a final yes/no.