Appearance
Objection Handling
Real callers don't follow scripts. This covers the 7 most common off-script moments and exactly how to handle each one.
Quick Reference
| Objection | Needs a tool? | Fix |
|---|---|---|
| "Call me later / I'm busy" | Yes — schedule_callback | Ask for preferred time, book it, confirm, end call |
| "Not interested" | No | One line in prompt |
| "Is this a bot?" | No | One line in prompt (two options) |
| "Transfer to a human" | Yes — request_human_transfer | Notify team, tell caller someone will call back |
| "Remove me from your list" | Yes — mark_do_not_call | Call DNC immediately, no confirmation needed |
| "What is this about?" | No | Clear first line in prompt |
| "I can't hear you" | No (use schedule_callback if available) | Ask to move, offer callback |
1. "Call me later / I'm busy"
What happens without config: The LLM says "of course, goodbye" and ends the call. Nothing is scheduled — no one follows up.
Fix — add a schedule_callback tool and one prompt line.
Tool definition:
json
{
"id": "tool-schedule-callback",
"name": "schedule_callback",
"description": "Schedule a callback for the customer. Call this when the customer says they are busy or asks to be called back later.",
"webhook_url": "https://your-api.com/callbacks",
"webhook_method": "POST",
"parameters": {
"properties": {
"phone_number": { "type": "string", "description": "Customer's phone number" },
"preferred_time": { "type": "string", "description": "When they want a callback (e.g. 'tomorrow at 3pm')" },
"notes": { "type": "string", "description": "Brief context note" }
},
"required": ["phone_number", "preferred_time"]
}
}Prompt instruction:
If the customer says they are busy or asks to be called back later, ask for their preferred callback time.
Call schedule_callback with their phone number and the time they give. Confirm the booking, then end the call.For flow agents — add a dedicated handle_callback node and escape hatch to every non-terminal node:
json
{
"node_key": "handle_callback",
"is_initial": false,
"is_terminal": false,
"task_messages": [{
"role": "system",
"content": "The customer wants to be called back. Ask for their preferred time. Call schedule_callback with their phone number and preferred time. Confirm the booking is done. Then call callback_booked."
}],
"functions": [{
"name": "callback_booked",
"description": "Callback has been scheduled and confirmed",
"next_node_key": "farewell",
"properties": {},
"required": []
}],
"tool_ids": ["tool-schedule-callback"],
"builtin_tools": ["end_call"]
}Add to every other node's functions:
json
{
"name": "customer_wants_callback",
"description": "Call this if the customer says they are busy or wants to be called back later",
"next_node_key": "handle_callback",
"properties": {},
"required": []
}2. "I'm not interested"
What happens without config: The LLM may try to overcome the objection and keep selling — which frustrates the caller.
Fix — one line in the prompt. No tool needed.
If the customer says they are not interested, acknowledge their response briefly,
wish them a good day, and call end_call. Never attempt to convince them further.The LLM will say something like: "That's completely fine. Have a wonderful day!" and hang up.
For flow agents — add to every non-terminal node's functions:
json
{
"name": "caller_not_interested",
"description": "Call this if the caller explicitly says they are not interested",
"next_node_key": "farewell",
"properties": {},
"required": []
}3. "Is this a robot? / Are you AI? / Am I speaking to a human?"
What happens without config: The LLM either denies being AI (dishonest) or launches into a lengthy explanation.
Fix — one line in the prompt. Two options:
Option A — Full disclosure (recommended):
If the customer asks whether you are a bot, AI, or human: answer honestly and say you are an AI
voice assistant from [Company Name]. Then immediately offer to continue helping.
Example: "Yes, I'm an AI assistant from [Company]. I can still help you with [purpose] — shall we continue?"Option B — Soft deflect:
If the customer asks whether you are a bot or human: say you are a voice assistant from [Company Name]
and redirect to the purpose of the call. Do not confirm or deny being AI.
Example: "I'm a voice assistant from [Company] here to help with [purpose]. How can I assist you?"Neither option requires a tool.
4. "Transfer me to a human / I want to speak to a manager"
What the platform can and cannot do: Live call transfer (handing audio to a human) is a carrier-level feature — not supported. What it can do is notify your team and end the call gracefully.
Fix — add a request_human_transfer tool.
Tool definition:
json
{
"id": "tool-human-transfer",
"name": "request_human_transfer",
"description": "Notify the support team that a customer wants to speak to a human agent. Call this when the customer asks to speak to a human, a manager, or a real person.",
"webhook_url": "https://your-api.com/transfer-request",
"webhook_method": "POST",
"parameters": {
"properties": {
"phone_number": { "type": "string", "description": "Customer phone number" },
"reason": { "type": "string", "description": "Why they want a human (e.g. complaint, complex issue)" }
},
"required": ["phone_number"]
}
}Your webhook should notify the right person — Slack message, CRM ticket, PagerDuty alert, etc.
Prompt instruction:
If the customer asks to speak to a human, a manager, or a real person:
call request_human_transfer with their phone number and reason.
Tell them: "I've flagged this for our team and someone will call you back shortly."
Then call end_call.
Note: live call transfer is not available — a human will follow up by phone.For flow agents — add tool-human-transfer to tool_ids on every node.
5. "Remove me from your list / Don't call me again"
This is the most important objection to handle. Failing to record a DNC request can result in repeat calls and compliance issues.
Fix — add a mark_do_not_call tool. Make it available on every node.
Tool definition:
json
{
"id": "tool-dnc",
"name": "mark_do_not_call",
"description": "Add a phone number to the Do Not Call list. Call this IMMEDIATELY when the customer says they do not want to be contacted again, says 'remove me', 'DNC', or any equivalent phrase.",
"webhook_url": "https://your-api.com/dnc",
"webhook_method": "POST",
"parameters": {
"properties": {
"phone_number": { "type": "string", "description": "Phone number to add to the DNC list" }
},
"required": ["phone_number"]
}
}Prompt instruction:
If the customer says "remove me", "do not call me again", "DNC", "stop calling", or any equivalent:
call mark_do_not_call IMMEDIATELY with their phone number — do not ask for confirmation.
Apologise for the inconvenience and call end_call.For flow agents — add "tool-dnc" to tool_ids on every node. This must be available regardless of which stage the caller is at.
6. "What is this about? / Who are you?"
What happens without config: The LLM answers based on the prompt — but if the prompt is vague, the answer will be vague.
Fix — write a clear purpose statement as the first sentence of your prompt. No tool needed.
Bad prompt:
You are a helpful assistant for ACME Corp.Good prompt:
You are Priya, a customer success agent from ACME Solar. You are calling customers
who recently installed solar panels to schedule a free system health-check visit.The first sentence should answer: who you are, which company, and why you're calling. When the caller asks "what is this about?", the LLM draws directly from this.
7. "I can't hear you / The line is bad"
What the platform can and cannot do: The platform has no control over carrier audio quality. The LLM cannot make itself louder at the network level.
Fix — prompt instruction + offer callback:
If the customer says they cannot hear you or the line is bad, ask them to move to a better location
and try again. If the problem persists, offer to call them back later using schedule_callback
(if available), then end the call.If you already have schedule_callback configured for objection 1, the LLM will use it here automatically. No extra setup needed.
Complete Objection Handler — Copy-Paste
Add all three tools and these four prompt lines to any agent for full coverage:
Tools to add:
json
[
{
"id": "tool-schedule-callback",
"name": "schedule_callback",
"description": "Schedule a callback. Call this when the customer is busy or asks to be called back later.",
"webhook_url": "https://your-api.com/callbacks",
"webhook_method": "POST",
"parameters": {
"properties": {
"phone_number": { "type": "string" },
"preferred_time": { "type": "string" }
},
"required": ["phone_number", "preferred_time"]
}
},
{
"id": "tool-human-transfer",
"name": "request_human_transfer",
"description": "Notify the team that a customer wants a human agent. Call this when the customer asks to speak to a human or manager.",
"webhook_url": "https://your-api.com/transfer-request",
"webhook_method": "POST",
"parameters": {
"properties": {
"phone_number": { "type": "string" },
"reason": { "type": "string" }
},
"required": ["phone_number"]
}
},
{
"id": "tool-dnc",
"name": "mark_do_not_call",
"description": "Add a number to DNC. Call this IMMEDIATELY when the customer asks not to be contacted again.",
"webhook_url": "https://your-api.com/dnc",
"webhook_method": "POST",
"parameters": {
"properties": {
"phone_number": { "type": "string" }
},
"required": ["phone_number"]
}
}
]Prompt additions:
OBJECTION HANDLING:
- If customer is busy or asks to be called back: ask for preferred time, call schedule_callback, confirm, end call.
- If customer says not interested: acknowledge briefly, wish them well, call end_call. Never push further.
- If customer asks for a human or manager: call request_human_transfer with their number and reason. Tell them someone will call back shortly. End call.
- If customer says remove me / do not call: call mark_do_not_call IMMEDIATELY. Apologise. End call.
- If asked whether you are a bot: confirm honestly that you are an AI assistant from [Company], offer to continue.For flow agents: Add all three tool IDs to tool_ids on every node.