How handoff works
When a handoff fires, OpenCX runs these steps in order:Update the Flex task attributes
OpenCX writes the handoff fields (see the table below) into the task’s
attributes JSON via TaskRouter’s API. Any attributes your workflow already set on the task are preserved.Workflow re-routes
TaskRouter re-evaluates the task against your workflow filters. The
handedOff == true filter matches, and the task is assigned to your human queue.What OpenCX writes to the task
| Attribute | Type | Purpose |
|---|---|---|
handedOff | boolean | Always true. The filter your workflow keys on. |
handoffReason | string | Short phrase the AI wrote when escalating — e.g. “customer wants to cancel subscription”. |
handoffSummary | string | One-paragraph summary of the conversation so far. |
handoffSentiment | string | Detected sentiment — positive, neutral, or negative. |
handoffLanguage | string | BCP-47 language code of the conversation — e.g. en, es, ar. |
handoffTimestamp | ISO 8601 string | When the handoff fired. |
OpenCX only adds these attributes. Every other attribute on the task — whatever your workflow set during routing — stays untouched.
What the rep sees in Flex
- The task in their queue with the six handoff attributes above, visible in the Task panel of the Flex UI.
- A system message at the top of the Flex conversation thread: the summary, sentiment, and reason formatted for human reading.
- The full above the handoff note — no replay, no separate tab.
- Any
flex_*custom data the workflow set during routing (see below) preserved on the task.
AI Support Agent, so the rep can distinguish them from the customer’s own messages.
Using Flex attributes in Autopilot
Every attribute your Flex workflow attaches to a task is flattened onto the OpenCX session’scustom_data with a flex_ prefix. Autopilot actions read from custom_data directly — no extra mapping.
Flattening rule
Flattening rule
A Flex attribute named
order_id becomes flex_order_id on the session. Nested attributes are flattened with underscores — customer.name becomes flex_customer_name. The flattening happens on every task event, so late-arriving attributes show up without you re-running anything.Typical attributes worth routing on
Typical attributes worth routing on
Teams commonly set
order_id, user_id, city, zone, or tier tags on the task. Any of these show up as flex_order_id, flex_user_id, etc., and can be used in an .Naming comes from your workflow
Naming comes from your workflow
OpenCX does not define which attributes exist — your Flex workflow does. The only guarantee is the
flex_ prefix. If you rename an attribute on the Flex side, update your Autopilot conditions to match.Closing Flex tasks
If you want tasks to close automatically on AI resolution:- Add a TaskRouter event callback on
task.wrapuporreservation.wrapupand close via your own automation. - Or configure a Flex workflow rule that closes tasks whose AI reservation was rejected without a successor assignment — depending on how your queues are structured.
Related Documentation
Connect Twilio Flex
Credentials, webhook registration, workflow filters.
Channels
Per-channel implementation on top of this shared setup.
Autopilot topics
Read
flex_* custom_data in topic conditions and actions.Troubleshooting
Handoff fires but the task stays in the AI queue, and other scenarios.