zoxaAI
Homepage

End Call Tool

Configure the End Call tool to let your voice agent programmatically hang up with an optional goodbye message and reason tracking.

What you'll learn

  • When to use the End Call tool
  • How to configure goodbye messages and end-call reason tracking
  • How reason codes flow into call analytics

The End Call tool gives the LLM the ability to programmatically end a call. When the LLM determines the conversation is complete (based on the tool's description), it triggers this tool to hang up -- optionally playing a goodbye message and recording a reason for analytics.


When to Use This Tool

Use the End Call tool when you want the LLM to decide when to end a call based on conversation context. Common scenarios:

  • The caller's issue has been resolved and they confirm they have no more questions.
  • The caller explicitly requests to end the call.
  • Voicemail is detected and the agent should hang up.
  • The conversation reaches a natural conclusion.
  • The caller is abusive or non-responsive.

Configuration Reference

Common Fields

FieldTypeConstraintsDescription
namestringMax 255 charactersDescriptive name for the tool (e.g., "End Call").
descriptionstring--Tells the LLM when to end the call. This is the primary signal for tool selection.

Example descriptions:

ScenarioDescription
General purposeUse this tool when the caller's issue is resolved and they confirm they have no more questions, or when the caller asks to end the call.
Voicemail detectionUse this tool when you detect that the call has reached a voicemail system. End the call immediately without leaving a message.
After task completionUse this tool after you have successfully completed the caller's request and confirmed the details with them.

End reason — captured automatically

You do not configure an end-reason field on this tool. The runtime captures it for you.

When the LLM fires this tool, the call ends with endedReason = "agent_hangup". The full ended-reason vocabulary (user_hangup, agent_hangup, silence_timeout, max_duration, voicemail, transferred, pipeline_error, cancelled, unknown) is stored on the call row at termination — visible in Call History, returned by the API, sent on webhooks, and filterable via ended_reason on GET /calls.


Goodbye Message

Controls what happens before the call is disconnected.

FieldTypeValid ValuesDefaultDescription
messageTypestring"none", "custom", "audio""custom"Whether to play a message before disconnecting.
customMessagestring or null--"Goodbye!"Text to speak before hanging up (when messageType is "custom"). In the inline agent format this field is customMessages — an array of up to 5 farewell variants, one picked at random each time the farewell plays.
audioRecordingIdstring or null--nullRecording ID of a pre-recorded audio file (when messageType is "audio").

Message Options

OptionBehavior
No Message ("none")End the call immediately without any announcement. Use for voicemail detection or non-interactive disconnects.
Custom Message ("custom")Speak a text message before disconnecting. Example: "Thank you for calling. Goodbye!" The text is synthesized by the agent's TTS provider and spoken as-is.
Pre-recorded Audio ("audio")Play a pre-recorded audio file before disconnecting. Use for branded sign-off messages.

When messageType is "none", the call disconnects immediately with no audio. This can feel abrupt to callers. For most use cases, a short goodbye message provides a better experience.


Tool Definition Schema

The full JSON schema for a saved End Call tool definition (POST /tools):

{
  "schema_version": 1,
  "type": "endCall",
  "config": {
    "messageType":     "custom",
    "customMessage":   "Thank you for calling. Have a great day!",
    "audioRecordingId": null
  }
}

For the inline format used in agent configs and transient POST /api/v1/call agents, see Inline tool format → endCall. The inline format carries customMessages (an array of farewell variants, random pick per call) instead of this single customMessage.


Example: Customer Support End Call

Configuration:

  • Name: End Call
  • Description: Use this tool when the caller's issue is resolved and they confirm they have no more questions, when the caller requests to end the call, or when voicemail is detected.
  • Message Type: Custom
  • Custom Message: Thank you for calling. If you need anything else, don't hesitate to call back. Goodbye!

What happens during a call:

  1. Caller: "That's everything, thanks for your help."
  2. LLM recognizes this as a natural end to the conversation and fires the endCall tool.
  3. The runner speaks the custom farewell — the LLM is told to skip its own goodbye to avoid a double-goodbye.
  4. The call is disconnected.
  5. The call row is finalized: endedReason = "agent_hangup" — the same value lands on the call.ended / call.completed webhooks.

Example: Voicemail Detection

Configuration:

  • Name: End on Voicemail
  • Description: Use this tool immediately when you detect that the call has reached a voicemail system or answering machine. Do not leave a message.
  • Message Type: None

What happens:

  1. The agent detects a voicemail greeting ("Hi, you've reached…").
  2. The LLM fires the endCall tool.
  3. The call disconnects immediately (no goodbye, messageType: "none").
  4. The call row records endedReason = "agent_hangup".

If the pipeline's answering-machine detection fires (rather than the LLM recognizing the greeting), the call ends with endedReason = "voicemail" instead — directly filterable via ended_reason=voicemail. LLM-triggered endCall on a suspected voicemail lands as agent_hangup; add a tag when you create the call if you need to separate those in analytics.


API Example: Create an End Call Tool

curl -X POST https://dashboard.zoxa.ai/api/v1/tools \
  -H "X-API-Key: zsk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "End Call",
    "description": "Use this tool when the caller confirms their issue is resolved and they have no more questions.",
    "category": "endCall",
    "definition": {
      "schema_version": 1,
      "type": "endCall",
      "config": {
        "messageType":     "custom",
        "customMessage":   "Thank you for calling. Goodbye!",
        "audioRecordingId": null
      }
    }
  }'

Best Practices

  1. Always include a goodbye message -- for any scenario where the caller is still on the line. Only skip it for voicemail detection or automated disconnects.
  2. Write specific trigger descriptions -- "end the call when appropriate" is too vague. Specify the exact conditions.
  3. Review endedReason for analytics -- you don't configure it; the runtime captures why every call ended automatically (see End reason — captured automatically). Filter on ended_reason in GET /calls for clean reporting.

On this page