Hand-off & Assignment
Conversational Agents are in Beta and available on Professional, Scale and Enterprise.
A hand-off (escalation) stops the agent for this conversation and passes it to your team. It works the same way as for any SendSeven bot: the hand-off message is sent, the conversation appears in the inbox as escalated, and the assignment rules of the agent's bot record decide who gets it.
Hand-off only happens while escalation is enabled on the agent (escalation.enabled: true, see Agents API — Escalation settings).
What triggers a hand-off
| Trigger | Checked | handoff_reason |
|---|---|---|
A contact message contains a hand-off keyword (handoff_config.keywords, or the escalation keywords when not set) | Before any AI call | keyword:<word> |
The conversation exceeded handoff_config.max_turns | Before any AI call | max_turns:<n> |
handoff_config.max_consecutive_fallbacks fallback answers in a row (default 2) | Before any AI call | consecutive_fallbacks:<n> |
The agent decided to hand over with its handoff tool | During the turn | agent_handoff:<reason> |
A skill goal completed with after.type: "handoff" | After the goal | agent_goal_completed |
| The plan no longer includes Conversational Agents | Before any AI call | plan_gated |
Inside a Flow, a hand-off ends the agent's part and the Run AI Assistant node continues on its escalated branch (see Agents in Flows).
The handoff tool
The agent calls handoff with:
- a summary for your team,
- a reason:
user_requested,cannot_help,out_of_scope,sensitiveorother, - optionally one tag from
handoff_config.handoff_tag_ids.
The chosen tag is added to the conversation before assignment runs, so you can use it for tag-based inbox access and reporting. Configure the candidates in handoff_config (up to 20 tags). The tool is offered only when tools_config.handoff is on and escalation is enabled, and a skill's tool_allowlist never removes it.
Hand-off reasons
handoff_reason in the turn log:
| Value | Meaning |
|---|---|
keyword:<word> | A hand-off keyword matched |
max_turns:<n> | Turn limit exceeded |
consecutive_fallbacks:<n> | Too many fallback answers in a row |
agent_handoff:user_requested | The contact asked for a human |
agent_handoff:cannot_help | The agent could not help |
agent_handoff:out_of_scope | The request is outside the agent's scope |
agent_handoff:sensitive | A sensitive topic |
agent_handoff:other | Any other reason |
agent_task_completed | A Flow task completed |
agent_goal_completed | A skill goal completed and its after action is handoff |
plan_gated | The plan does not include Conversational Agents |
In the test console hand-offs are simulated: the response contains outcome: "handoff" and handoff: {summary, reason, tag_id}, and no tag is added.
Assignment on hand-off
Routing settings live on the agent's bot record. Use the agent's bot_id with the bots API:
PATCH /api/v1/automation/bots/{bot_id} — scope automation:update.
{
"escalation_routing_strategy": "round_robin",
"escalation_tag_id": "TAG_ID_SUPPORT_DE",
"escalation_fallback_minutes": 15
}
| Field | Notes |
|---|---|
escalation_routing_strategy | See the table below. null (default) keeps hand-overs unassigned. |
escalation_tag_id | The tag whose members receive the hand-over. Required for the by-tag strategies. Must be a tag in your workspace. |
escalation_fallback_minutes | 1..1440 or null. Sends an unattended alert if the conversation is still unassigned or unanswered after this many minutes. |
These fields cannot be set through PATCH /automation/agents/{agent_id}.
Strategies
escalation_routing_strategy | escalation_tag_id | What happens |
|---|---|---|
null | not set | Nothing: the conversation stays unassigned in the inbox. |
null | set | Treated as notify_only (older configurations). |
notify_only | required | The tag is added to the conversation and its members are notified. No one is assigned. |
round_robin | required | The tag is added, and an unassigned conversation is assigned to the next eligible tag member in turn. |
least_busy | required | The tag is added, and an unassigned conversation is assigned to the eligible tag member with the fewest open conversations. |
round_robin_all | ignored and cleared | Assigned to the next eligible member of the whole team, in turn. |
least_busy_all | ignored and cleared | Assigned to the eligible team member with the fewest open conversations. |
Rules:
- A conversation that is already assigned is never reassigned.
- Only team members who can see the conversation and are active are eligible; online members are preferred.
- If nobody is eligible, workspace admins and owners are notified instead.
- Saving a
*_allstrategy clearsescalation_tag_id.
Tag members are managed with member tags (GET/PUT /api/v1/users/{user_id}/tags, scopes team:read / team:update). See Skill-Based Routing for tag-based inbox access and the same strategies in Flows.
Unattended alert
With escalation_fallback_minutes set and a routing strategy in effect (including null + tag), SendSeven checks the conversation after that many minutes. If it is still unassigned, or the assigned member has not replied, Owners and Admins are alerted together with the tag members (by-tag strategies) or the assigned member (_all strategies).
The countdown is schedule-aware: when the bot has an escalation schedule (is_escalation_schedule_enabled with escalation_schedule) and the hand-over happens outside it, the countdown starts at the next opening of the schedule instead of immediately. A hand-over at 22:00 with a 15-minute fallback and a schedule opening at 09:00 is checked at 09:15.
Outside the schedule, the behaviour of the hand-over itself (outside-hours message, live chat offline behaviour) is described in Skill-Based Routing — Assignment on handoff.
Errors
| Status | detail |
|---|---|
422 | "escalation_tag_id is required when escalation_routing_strategy is set" (a by-tag strategy without a tag) |
422 | "escalation_tag_id does not reference a tag in this workspace" |
422 | escalation_fallback_minutes outside 1..1440, or an unknown strategy |
404 | Bot not found |
Skill goals and assignment
A skill goal has its own assign action (none, round_robin_all, least_busy_all, round_robin_by_tag, least_busy_by_tag). It runs when the goal completes, independently of the bot's hand-off routing. With after.type: "handoff", the goal then hands over through the normal hand-off path, so an already assigned conversation stays with its assignee.