Human-in-the-Loop (HITL)
Human-in-the-loop lets you pause agent communication and require manual approval before a message is forwarded. This is critical for high-stakes operations where you need a human to verify what an agent is about to do.
How HITL Gets Triggered
There are two distinct ways a message can be held for human review:
| Source | How it happens | Typical use case |
|---|
| Policy escalation | A detection policy with action HUMAN_REVIEW_REQUIRED matches the message | Compliance rules, PII detection, restricted operations |
| Agent-initiated | The downstream agent returns task status INPUT_REQUIRED | Agent is uncertain, needs clarification, or is designed to ask for confirmation |
These are fundamentally different flows. Policy escalation is triggered by a detection policy (regex, Presidio, Comprehend) at the relay level — before or after the message reaches the agent, depending on which leg matched. Agent-initiated INPUT_REQUIRED happens when the agent has processed the message and decided it needs human input. Both are automatically intercepted by the relay’s built-in HITL middleware.
Setting Up Policy-Based HITL
To escalate messages for human review, set the action to HUMAN_REVIEW_REQUIRED on any detection policy (regex, Presidio, or Comprehend). There is no separate “HITL policy type” — human review is an action you configure on your existing detection policies.
curl -X POST https://api.swarmd.ai/relay/v1/policies \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SWARMD_TOKEN" \
-d '{
"name": "Review Messages with SSNs",
"description": "Escalate to human review when SSNs are detected",
"config": {
"type": "PRESIDIO_DETECTION",
"enabledLegs": {
"requestFromSource": true,
"requestToSink": true,
"responseFromSink": true,
"responseToSource": true
},
"entity": {
"type": "US_SSN",
"scoreThreshold": 0.7,
"action": "HUMAN_REVIEW_REQUIRED"
}
}
}'
Coming soon.
After creating your policy, remember to add it to a policy group and bind that group to a tenant, agent, or subscription. See the Policy Configuration tutorial for the full flow.
Reviewing Approvals
When a message is held for review, it appears as a pending approval.
List Pending Approvals
curl "https://api.swarmd.ai/relay/v1/approvals?status=PENDING" \
-H "Authorization: Bearer $SWARMD_TOKEN"
Response:[
{
"id": "a1b2c3d4-...",
"taskId": "task-5678",
"agentMessageRole": "user",
"agentMessageText": "Please process this SSN: 123-45-6789",
"detectionSource": "POLICY_ESCALATION",
"sourceAgentId": "...",
"sinkAgentId": "...",
"policyName": "Review Messages with SSNs",
"matchedContent": "123-45-6789",
"createdAt": "2025-03-10T14:30:00",
"resolution": null
}
]
To see all approvals (including resolved ones):curl "https://api.swarmd.ai/relay/v1/approvals?status=ALL" \
-H "Authorization: Bearer $SWARMD_TOKEN"
Coming soon.
Get a Specific Approval
curl https://api.swarmd.ai/relay/v1/approvals/APPROVAL_ID \
-H "Authorization: Bearer $SWARMD_TOKEN"
Coming soon.
Key Fields in an Approval
| Field | Description |
|---|
detectionSource | POLICY_ESCALATION (from a policy) or AGENT_INPUT_REQUIRED (from the agent) |
agentMessageText | The message content that triggered the review |
matchedContent | The specific content that matched the policy (if policy-triggered) |
policyName | The name of the policy that triggered escalation (if policy-triggered) |
sourceAgentId / sourceUserId | Who sent the message |
sinkAgentId | The target agent |
resolution | null if pending, otherwise contains the resolution details |
Resolving Approvals
Approve
Approving a request allows the message to continue through the relay to the target agent.
curl -X POST https://api.swarmd.ai/relay/v1/approvals/APPROVAL_ID/resolve \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SWARMD_TOKEN" \
-d '{
"action": "APPROVED",
"message": "Verified — this is a test SSN for the demo environment"
}'
Coming soon.
What happens next:
- The held message is forwarded to the target agent
- The task resumes from where it was paused
- The approval, resolution, and reviewer are recorded in the audit log
Reject
Rejecting a request stops the message from being forwarded. The task is cancelled.
curl -X POST https://api.swarmd.ai/relay/v1/approvals/APPROVAL_ID/resolve \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $SWARMD_TOKEN" \
-d '{
"action": "REJECTED",
"message": "Contains real PII — must not be sent to external agent"
}'
Coming soon.
What happens next:
- The message is not forwarded
- The associated task is cancelled
- The rejection reason is recorded in the audit log
It’s important to understand the difference between these two flows:
| Policy Escalation | Agent INPUT_REQUIRED |
|---|
| Triggered by | A detection policy with HUMAN_REVIEW_REQUIRED action | Downstream agent returning INPUT_REQUIRED task status |
| When | During relay policy evaluation (on the matching leg) | After the agent has processed the message |
| Detection source | POLICY_ESCALATION | AGENT_INPUT_REQUIRED |
| Approval fields | policyName and matchedContent populated | policyName and matchedContent are null |
| Use case | Compliance, safety guardrails | Agent needs clarification or confirmation |
| On approve | The held message is forwarded to the target agent | A follow-up message is sent to the agent |
When an agent returns INPUT_REQUIRED, the agent has already seen the message and is asking for more input. The relay’s built-in HITL middleware automatically intercepts this and creates an approval request — you don’t need to configure a policy for this path. It happens by default.
Auditing HITL Decisions
Every HITL event is recorded in the audit log with specific audit types:
| Audit Type | Description |
|---|
HITL | HITL detection occurred (policy escalation or agent input-required) |
HITL_GUARD | The message was held and the task is guarded pending review |
HITL_RESOLUTION | The approval was resolved (approved or rejected) |
Query HITL-related events:
curl "https://api.swarmd.ai/audit/v1/events?auditType=HITL_RESOLUTION&page=0&size=10" \
-H "Authorization: Bearer $SWARMD_TOKEN"
To see the complete flow — trigger, hold, and resolution — use the trace endpoint with the correlationId from the approval:curl https://api.swarmd.ai/audit/v1/traces/CORRELATION_ID \
-H "Authorization: Bearer $SWARMD_TOKEN"
Coming soon.
Required Permissions
To manage HITL approvals, users need the following permissions:
| Action | Required Permission |
|---|
| List / view approvals | AGENT_CONVERSATIONS:READ |
| Approve or reject | AGENT_CONVERSATIONS:WRITE |
See the User Management tutorial for how to assign permissions.
Next Steps