Human Handoff is the mechanism that prevents the AI from responding while a human support agent is actively handling a conversation in Chatwoot. Without it, a human agent’s reply would be received by the customer alongside an AI-generated response to the same message — creating a confusing, potentially contradictory experience. The solution is a Redis key that acts as a per-conversation lock: when the key is present, n8n silences the AI pipeline entirely and lets the human remain in control. When the key expires or is explicitly deleted, the AI resumes handling messages normally.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/DevMauricio03/n8n-whatsapp-ai-agent/llms.txt
Use this file to discover all available pages before exploring further.
How it works
The lock is implemented as a simple Redis key-value pair with a time-to-live (TTL). n8n sets the key the moment it detects an outgoing message from a human agent, and checks for it before invoking the AI on every subsequent inbound message from the customer.Current vs. recommended key format:The workflow currently uses a key in the form:This format uses the customer’s phone number as the identifier, which can cause collisions when the same phone number exists across multiple Chatwoot accounts or inboxes. For new implementations, use the recommended format:This ties the lock to a specific conversation rather than a phone number, eliminating ambiguity and making the key safe to use across multi-inbox deployments.
| Property | Value |
|---|---|
| Key (current) | human_mode:human_mode:<telefono> |
| Key (recommended) | human_mode:<account_id>:<conversation_id> |
| Value | true |
| TTL | 1800 seconds (30 minutes) |
Activation flow
Human agent sends a message from Chatwoot
A support agent composes and sends a reply to the customer from within the Chatwoot inbox. This is the triggering action.
Chatwoot emits an outgoing webhook event
Chatwoot fires a webhook event to n8n with the message direction set to
outgoing. This event carries the account ID, conversation ID, and sender phone number needed to construct the Redis key.n8n detects the outgoing direction
The
msg_from_client node identifies that the message direction is not incoming. Instead of entering the AI pipeline, execution is routed to the Human Handoff activation path.n8n sets the Redis key with TTL
n8n writes the key to Redis with a value of
true and a TTL of 1800 seconds. If a key already exists for this conversation from a previous handoff, the TTL is renewed from this moment.AI stays silent for subsequent inbound messages
Every new message from the customer triggers the n8n webhook. At the Human Handoff check step, n8n finds the key in Redis, confirms the value is
true, and terminates the execution without reaching the AI agent node. The human agent’s replies are the only responses the customer receives.Deactivation
Automatic expiry
The lock expires automatically when the TTL reaches zero. After 1800 seconds (30 minutes) without a new human agent message renewing the TTL, the key is deleted by Redis and the next inbound customer message will be processed by the AI normally.Explicit deletion (recommended)
The safer and more predictable deactivation method is to explicitly delete the key when the conversation is resolved or closed in Chatwoot. This prevents a situation where the AI resumes responding in the middle of an ongoing human-managed conversation simply because the agent paused for more than 30 minutes.TTL renewal
Each new message sent by a human agent from Chatwoot should renew the TTL, resetting the 30-minute countdown from the time of the latest agent reply. This behavior prevents the AI from re-activating in the middle of a long-running support session simply because 30 minutes passed since the previous reply. If your support team routinely handles conversations that exceed 30 minutes, adjust the TTL based on actual measured conversation durations — do not increase it arbitrarily, as a longer TTL means the AI remains silenced for longer if an agent forgets to resolve the conversation.Verification commands
Use these commands to inspect the Human Handoff state for a specific conversation directly from the Redis container. Check whether the key exists and read its value:-1 means no expiry, -2 means the key does not exist):
<telefono> with the full phone number as it appears in Chatwoot, including the country code and any prefix used in the current key format.
Edge cases
Redis unavailable — fail closed
Redis unavailable — fail closed
Agent replies near TTL expiry
Agent replies near TTL expiry
If a human agent sends a reply when the TTL has only a few seconds remaining, there is a narrow race condition where n8n processes an inbound customer message before the new agent reply arrives and renews the TTL. In this window, the AI could generate a response. To reduce this risk, TTL renewal should be applied eagerly — any outgoing message from Chatwoot, even a partial draft being sent, should reset the countdown. Monitor your Redis TTL values during high-volume periods to identify whether this race occurs in practice.
Automatic outgoing events confused with human messages
Automatic outgoing events confused with human messages
Chatwoot can emit
outgoing webhook events for messages that were generated automatically — for example, system notifications, bot responses, or assignment messages. If n8n cannot distinguish between an automated outgoing event and a genuine human agent reply, it may activate the Human Handoff lock unnecessarily, silencing the AI for conversations that are not actually being handled by a human. Review your Chatwoot webhook payload structure to confirm whether automated events include distinguishing fields (such as message_type or sender.type) that can be used to filter them before the Human Handoff activation step.Phone number format change breaks key lookup
Phone number format change breaks key lookup
The current key format uses the phone number as stored in the Chatwoot webhook payload. If a phone number is later stored or formatted differently — for example, with or without a leading
+, with or without the country code, or with spaces removed — the key written at activation time may not match the key checked at inbound message time. This would cause the AI to respond even though a Human Handoff key exists under a slightly different key name. Normalizing the phone number to a canonical E.164 format before constructing any Redis key eliminates this class of bug entirely, and is another reason to prefer the human_mode:<account_id>:<conversation_id> format.Test cases
The following test scenarios validate Human Handoff behavior end to end. Each is defined in the test suite referenced in Testing:| ID | Scenario |
|---|---|
| HH-01 | Agent sends from Chatwoot → AI is silenced for subsequent customer messages |
| HH-02 | TTL expires naturally → AI resumes on next customer message |
| HH-03 | Explicit DEL command → AI resumes immediately |
| HH-04 | Redis unavailable → execution terminates without AI response |