Two HITL modes
Approvals
The agent pauses mid-conversation before executing a tool call or workflow action. A human operator reviews the pending action, then approves or denies it. The agent automatically resumes with the decision and continues the conversation.
Handoffs
The agent transfers the entire conversation to a human operator. The operator sends messages that are relayed directly to the end user. When the issue is resolved, the operator closes the handoff and the session ends gracefully.
Handling approvals
When a conversation reaches an action that requires sign-off, the agent entersawaiting_approval status and waits — it will not proceed until a decision is recorded.
List pending approval requests
Poll this endpoint from your operator dashboard or webhook handler to surface requests that need attention.The response lists approval summaries including the
subject_ref, approver_role, and the suspend_message shown to the user.Fetch full approval detail
Retrieve the complete record for a specific approval — including the action payload the agent wants to execute.ApprovalRequestDetail fields:
| Field | Type | Description |
|---|---|---|
id | string | Unique approval request ID |
conversation_id | string | The conversation this approval belongs to |
subject_kind | enum | workflow_node or tool_call |
subject_ref | string | Identifier of the node or tool awaiting approval |
payload | object | The full action payload the agent intends to execute |
approver_role | string | The operator role required to approve this action |
suspend_message | string | Message currently displayed to the end user |
timeout_at | ISO 8601 | When the request auto-expires if no decision is made |
Submit your decision
Approve or deny the pending action. Include a Once the decision is submitted, the conversation automatically resumes. If approved, the agent executes the action. If denied, the agent receives the denial note and responds to the user accordingly.
note when denying so the agent can explain the outcome to the user.Handling handoffs
When an agent triggers a handoff, the conversation transitions towaiting_for_human status. The agent is no longer generating responses — a human operator takes over completely.
Review the handoff context
Fetch the full handoff record to understand why the agent escalated and what the customer’s situation is before you write your first message.The
packet field contains everything the agent prepared for the handoff:| Packet field | Description |
|---|---|
static_text | A short briefing sentence visible at the top of the handoff card. |
reason | Why the agent decided to escalate. |
summary | A longer AI-generated summary of the conversation so far. |
transcript_ptr | Watermark pointer {conversation_id, up_to_seq} indicating the conversation message seq up to which the transcript had been captured at handoff time. |
Relay a message to the user
Send messages as the human operator. They appear in the customer’s conversation thread immediately.You can send as many messages as needed. The customer replies are visible by polling
GET /v1/v2/conversations/{id}/messages.Poll
GET /v1/v2/conversations/{id}/messages?since_seq={n} to receive the end user’s replies in real time during an active handoff. Pass the sequence number of the last message you’ve read as since_seq to receive only new messages.Custom approval messages
While a conversation is paused waiting for approval, the end user sees a holding message. You can customize both the initial holding message and the follow-up patience message to match your brand voice.| Field | When it’s shown |
|---|---|
holding_line | Sent to the user immediately when the conversation enters awaiting_approval. |
waiting_reply | Sent if the user sends another message while still waiting (the “still here” acknowledgement). |
Configuring HITL in workflows
Approval and handoff behaviors are configured as nodes in your agent’s workflow graph. Here’s how both node types look in a workflow definition:condition is a deterministic expression: when it evaluates to false the node is a pass-through and no approval is requested. When it’s true, the runtime suspends and emits an approval request. On resume, on_approve and on_deny each name the next node to route to for that decision — a timeout is recorded as a deny, so it follows the on_deny path.