1. Decide when to hand over
There are two ways to get the decision from the model. Use either or both. Triage after each customer message. The console ships a “Customer care triage” agent template. In the console, open Agents, choose New agent, pick Customer care triage, select Use template, then Create agent. The agent returns one JSON object per run withcategory, priority, sentiment, language, summary, suggested_reply, needs_human_handoff and handoff_reason.
The template’s instructions say when needs_human_handoff is true: the customer asks for a person, reports fraud or a security issue, threatens legal action or cancellation, is very upset, or needs a refund, account change or decision the model cannot make.
Edit the categories in the instructions to match your support teams before you route on them.
Copy the agent id; the sample below reads it from TRIAGE_AGENT_ID.
Let the assistant ask for a person mid-conversation. Declare a function tool on the agent or Responses request that handles the chat.
When the model calls it, the response contains a function_call item with the arguments. Your application builds the same handover package as below and answers with a function_call_output so the model can tell the customer what happens next.
See Function calling for the loop.
Tool definition
2. Pause for a human decision
If the agent uses MCP tools that mutate external systems, setrequire_approval: "always" on the tool.
The response then stops at an mcp_approval_request item instead of calling the tool. Your application shows the human the server, tool name and arguments, and continues the response with an mcp_approval_response item that approves or denies the call.
This is the same approval flow as Require end-user approval, with a support agent making the decision instead of the end user.
3. Collect the full history
Keep each support chat in a conversation so the history is stored on the platform. When the handover fires, list the conversation’s items and attach them to the package. Items come back in the order they were added when you passorder: "asc".
TypeScript SDK
after with the last item id when a conversation is longer than one page.
4. Route with rules you control
Routing is a lookup your application owns. Keep it as data so support leads can change it without a deploy. The sample uses a list of rules, first match wins. A rule withoutpriority matches every priority, and anything unmatched goes to a default queue.
Routing rules
category and priority come from the triage JSON. With the function tool, map queue_hint the same way.
5. Deliver to the queue
The handover package is plain JSON: the queue, the reason, the triage result, the conversation id and the history. Post it to the system that holds your human queues, such as a help desk webhook or a ticketing API. The sample posts toHANDOVER_WEBHOOK_URL when it is set and prints the package otherwise, so you can run it without a third-party account.
Handover package
Run the sample
The sample seeds a conversation so it runs on its own. In your application the conversation already exists and only steps 2 to 5 run. It needsMKA1_API_KEY and the TRIAGE_AGENT_ID from step 1.
handover.ts
Example output
This is what the sample printed against production, trimmed to the first history item.Next steps
- Create and run agents for run status, history and versions
- Conversations for storing and continuing the chat after the handover
- Use MCP tools for the approval flow in step 2
- Chat connectors when the conversation arrives from a messaging channel