Agent to human handoff packet

Shared by Pavel · Updated 2026-11-06

Direct answer: Pass ten fields, not one: record id, what they asked, what the agent promised, facts with sources, what it was unsure of, next step with deadline, thread link, owner, and a human_took_over flag. n8n's own human-fallback example passes only the user's message.

Below: the n8n schema to copy, a Slack layout, three failure modes, and a comparison with Intercom and Zendesk.

Label key: [vendor] = vendor documentation; [measured] = measured by someone; [opinion] = judgment. All sources read 2026-11-06.

What n8n's human-fallback example passes [vendor]

Source: https://docs.n8n.io/advanced-ai/examples/human-fallback/ and its workflow file https://raw.githubusercontent.com/n8n-io/n8n-docs/refs/heads/main/docs/_workflows/advanced-ai/examples/ask_a_human.json

The packet

FieldTypeNote
record_idstringthe CRM or ticket id
askedstringthe customer's request, their words
promisedarray of stringanything the agent said it would do
factsarray of {claim, source}each with a URL or record
unsurearray of stringwhat the agent could not confirm
next_stepstringone action
deadlinestringISO 8601 date-time
thread_urlstringfull conversation
ownerstringthe named human
human_took_overbooleanfalse until a human replies

Copy-ready n8n inputs (not yet tested end to end)

Receiving workflow, Execute Sub-workflow Trigger. Set Input data mode to "Define using JSON example" and paste. Per n8n's node source, a null value allows any type [vendor, https://github.com/n8n-io/n8n/blob/master/packages/nodes-base/nodes/ExecuteWorkflow/ExecuteWorkflowTrigger/ExecuteWorkflowTrigger.node.ts]:

{
  "record_id": "a string",
  "asked": "a string",
  "promised": [],
  "facts": [],
  "unsure": [],
  "next_step": "a string",
  "deadline": "a string",
  "thread_url": "a string",
  "owner": "a string",
  "human_took_over": false
}

Calling workflow, Execute Sub-workflow node. Source "Database", pick the workflow "From list"; the fields then appear to map [vendor, https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflow.md]. Map: record_id = {{ $json.record_id }}, and so on for each field. Turn on "Wait for Sub-Workflow Completion" if you need the reply.

Set node (JSON Output mode). The Edit Fields node offers a JSON Output mode [vendor, https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.set.md]; in n8n's source the parameters are mode: "raw" and jsonOutput (https://github.com/n8n-io/n8n/blob/master/packages/nodes-base/nodes/Set/v2/raw.mode.ts):

{
  "mode": "raw",
  "jsonOutput": "={{ { record_id: $json.record_id, asked: $json.asked, promised: [], facts: [], unsure: [], next_step: '', deadline: '', thread_url: '', owner: '', human_took_over: false } }}"
}

Checked against docs: the mode and parameter names and the null-for-any-type rule. Not checked: running it in an n8n instance.

Slack message layout (not yet tested)

*Handoff: {{record_id}}*  owner: {{owner}}  due: {{deadline}}
*Asked:* {{asked}}
*We promised:* {{promised}}
*Facts:* {{claim}} ({{source}})
*Unsure:* {{unsure}}
*Next step:* {{next_step}}
Thread: {{thread_url}}

[opinion] Put promises above facts. The human most needs to know what the customer already believes.

Failure modes [opinion unless marked]

  1. Double replies after takeover. The agent and the human both answer. Set human_took_over the moment a human replies and check it before every agent send. Evidence this happens: a third-party guide says Intercom's Fin keeps replying until a teammate sends a customer-facing message (https://www.getmacha.com/blog/intercom-fin-handoff-setup, secondhand, not confirmed in Intercom's own article).
  2. Lost promises. "I'll send the contract today" sits in the thread, not in a field. Extract promises into promised before handoff.
  3. Stale CRM fields. The packet copies a field that changed since. Store the record id and read the live record at takeover; keep facts as dated claims.

Public handoff docs compared

Intercom (Fin)Zendesk (AI agents)
Context to humanNot stated in the article readMessaging history is backfilled into the ticket; conversation metadata is mapped to the ticket at escalation
Why it escalatedAn attribute records the reasonA conversation tag such as async_escalation in the recipe
After handoffNot statedTicket becomes a regular, editable ticket
Sourcehttps://www.intercom.com/help/en/articles/12396892-manage-fin-ai-agent-s-escalation-guidance-and-ruleshttps://support.zendesk.com/hc/en-us/articles/9204149016346 and https://support.zendesk.com/hc/en-us/articles/11285019603098

All cells [vendor]. Neither page describes promises, uncertainty or a deadline field. Intercom's article also describes an "Ask for input" rule that keeps the conversation with Fin while a teammate reviews a draft.

Gaps