Skip to navigation

Handoff reasons

Overview

When the AI Agent hands a conversation to a human agent through a Handoff, it records why. Use these reasons to find handoffs that you can reduce, such as a failing Tool or a gap in your Knowledge.

Each reason has two fields:

  • reason_code: one value from a fixed list of ten, or null when no code was recorded. Use it to count, filter and compare handoffs.
  • reasoning: an explanation, based on the conversation, the Tool results or the configuration of your AI Agent. Use it to understand a single handoff. It is null when no text was recorded.

The Data Export API returns both fields in the handoffs array. The get_conversation MCP tool returns both fields, and get_available_filters offers the HANDOFFREASON filter. See Where the fields appear.

Limitations

Handoff reasons have the following constraints:

  • The AI Agent records reason codes from 2026-10-07. Most earlier handoffs have a null reason code.
  • Some AI Agents do not choose a cause during a conversation. Their handoffs outside Playbooks record unclassified. These handoffs do not get a cause later.
  • The Data Export handoffs array includes only the handoffs that the AI Agent starts. The array can be empty for an escalated conversation. Use is_escalated to know whether a conversation was escalated.
  • The AI Agent writes the reasoning text in English. When it chooses one of the eight causes, the system asks for one or two sentences. Other text can be longer. Older text can be in the language of the conversation. Text that you set on a Playbook step can be in any language.

Use cases

Reason codes show where to start when you want fewer Handoffs.

  • Fix failing Tools: tool_failed handoffs can point to a Tool or an integration that failed or timed out.
  • Review Tool access: tool_unavailable handoffs show tasks that need a Tool the AI Agent does not have or cannot use.
  • Fill Knowledge gaps: knowledge_unavailable handoffs show information that the AI Agent did not have. Check whether your Knowledge needs more content.
  • Review your routing: handoff_configured handoffs show requests that your configuration sends to a human agent. Check whether the AI Agent could handle those requests.
  • Track requests for a person: end_user_requested handoffs show where the end user’s request for a human agent caused the handoff.

Reason codes

The first eight codes are causes. When the AI Agent chooses a cause for a Handoff during a conversation, it records the first cause in the table that applies. Only the system records system_failed and unclassified. A Playbook handoff step gets its reason in a different way, and its rules can differ from this table. See How the reason is assigned.

CodeMeaningExample reasoning
tool_failedA Tool, an integration, a credential or a connected platform failed, for example with a timeout or a rejected credential. The code stays tool_failed when the end user then asks for a human agent.The order lookup returned a timeout twice, so the Agent could not confirm the shipping status.
end_user_requestedThe end user asked for a human agent before the AI Agent offered one. Frustration alone does not count. Acceptance of the AI Agent’s offer does not count. A request for a task, such as closing an account, is not a request for a human agent.The end user asked to speak to a person in their first message and repeated the request after the Agent offered help.
out_of_scopeA policy does not let the AI Agent handle the request, so a human agent must handle it. A new Tool would not change this.The end user asked for a credit limit increase. Company policy requires a human agent to approve it.
tool_unavailableThe AI Agent may handle the request, but none of its Tools can do a necessary task. The Tool does not exist, or your configuration does not give the AI Agent access to it.The end user cannot sign in because both the email address and the password are unknown. The self-service reset requires the existing email address, so account recovery needs a human agent.
knowledge_unavailableThe AI Agent does not have the information it needs. A search that finds nothing useful counts, and so does Knowledge that does not cover the topic.The end user asked about the warranty on a discontinued model. The knowledge base has no article that covers it.
issue_unresolvedA relevant fix ran correctly, or the end user tried it, but the issue continued. The Knowledge and the Tools were adequate.The end user tried all the documented APN and connection steps. Mobile internet still does not work after activation.
handoff_configuredThe AI Agent could handle the request, but your configuration, such as a Playbook or a Process, sends it to a human agent. The AI Agent uses this code only when no cause above applies.The refund lookup ran. The Playbook sends overdue refunds to a human agent.
otherNone of the seven causes above describes the handoff. The reasoning text states what did not fit.The end user’s messages stayed unclear after two requests to rephrase, so the Agent could not identify the request.
system_failedThe handoff was the fallback for an error in Ada. An error from one of your Tools is tool_failed, not system_failed.Often null.
unclassifiedThe system did not assign one of the eight causes. For example, a Playbook handoff step ran before the system assigned its reason.Often null.
nullNo reason code was recorded. It is different from unclassified, which is a recorded value.Often null.

A handoff has a null reason code in these cases:

  • The handoff happened before 2026-10-07, when most handoffs had no recorded reason code.
  • The AI Agent did not give a valid reason code.
  • The AI Agent had to hand off, but no Handoff was available, so it sent an error message instead.

A handoff with a null reason code matches no IS value of the HANDOFFREASON filter. A count by reason code does not include these handoffs.

How the reason is assigned

A Handoff gets its reason at one of two moments, depending on how it was triggered.

  • During a conversation. When the AI Agent decides to hand off, it records the reason_code and the reasoning. When the AI Agent chooses one of the eight causes, the system is instructed not to include personal data. Personal data includes names, addresses, account numbers and card numbers.
  • Playbook handoff steps. Each handoff step in a Playbook can hold its own reason, and handoffs from the step record it.
    • You can set a step’s reason_code and reasoning with the edit_agent_behavior MCP tool or the Playbooks API. Set them on the run step that targets the Handoff. An MCP edit goes live when you promote its change set.
    • The reason_code must be one of the eight causes. The reasoning needs a reason_code and has a maximum of 300 characters.
    • Later saves keep the values that you set, including saves in the dashboard, which does not show these fields. To let the system assign the reason instead, set reason_code to null.
    • After you save a Playbook, the system assigns a reason to each handoff step that has none. It bases the reason on the steps that lead to the handoff step. Until then, or if that fails, handoffs from the step record unclassified. The system does not replace a reason that you set.
    • To read the reasons, use list_entities for one Playbook or the Playbooks API. These reads show the reasons that you set, not the reasons that the system assigns. A Snapshot API export and import also keep the reasons that you set.

Where the fields appear

Each location shows the Handoff reason fields in its own format.

LocationFieldsNotes
Data Export API, v2 Conversations endpointhandoffs[].reason_code, handoffs[].reasoningreasoning is a string, or null when no text was recorded. Each entry is the latest attempt for one handoff target, in time order. The export applies your redaction rules to reasoning, as it does to message bodies. See the Conversation object.
MCP get_conversationreason_code, reasoning.textReturned on the handoff_triggered transcript entry. When text exists, reasoning is an object, and its text field holds the explanation. Otherwise, reasoning is null. get_conversation applies your redaction rules to the reasoning text. See get_conversation.
MCP get_available_filtersHANDOFFREASONFilter conversations by reason code with IS or ISNOT. ISNOT also returns conversations with no handoff. See get_available_filters.

Handoff attempts and escalations

A handoff reason belongs to one attempt of a Handoff. The AI Agent records the reason when it starts the attempt, even if the attempt fails. So a reason does not show that the end user reached a human agent.

  • In the Data Export, each handoffs entry is the latest attempt for one handoff target. Its outcome_status gives the result, for example succeeded or failed.
  • With IS, the HANDOFFREASON filter also matches conversations where the attempt with that reason failed.
  • To find escalated conversations, use is_escalated in the Data Export or the HANDOFF filter in MCP. They show whether the conversation was escalated, not which handoff attempts the AI Agent made.