Human task node
Pause workflows for human approval or input to ensure oversight in critical decisions
Purpose
The Human Task node pauses the workflow and waits for a human to provide input or approval before continuing. Essential for human-in-the-loop patterns, Human Task nodes ensure that critical decisions have human oversight.
Human Task nodes bridge the gap between AI automation and human judgment. They enable workflows that leverage AI speed and consistency while retaining human oversight for high-stakes decisions.
How it works
When execution reaches a Human Task node, the workflow pauses durably while waiting for human input.
Workflow reaches Human Task
Execution arrives at the Human Task node. The workflow prepares to pause.
Execution pauses
The workflow execution pauses and its status becomes waiting for input. Temporal maintains the complete state durably, so no data is lost.
Task appears in MagOneAI Hub
A task record is created and surfaces in MagOneAI Hub for every assigned user. Each assignee sees:
- Task title and description
- Context data from previous nodes
- The questions to answer and available options
A human reviews and responds
An assignee reviews the context and submits their answers through MagOneAI Hub. When a task has several assignees, the first person to respond is the one who resolves it.
Workflow resumes
The response is validated against the task's questions, stored in the variable store, and signalled back to the workflow. Execution resumes from exactly where it paused.
Workflow continues
Subsequent nodes can access the human's answers, and approval tasks can route the workflow based on the decision.
Human Task nodes leverage Temporal's durable execution. The workflow can wait for hours, days, or up to a week for human input without losing state or consuming compute resources. When the human responds, execution resumes instantly.
Configuration
A Human Task node is configured with a task type, a title, one or more assignees, and the questions the human answers. Every text field supports template variables, so the task is built from data produced earlier in the workflow.
Task type
Choose how the task behaves:
approval— a decision task. If you don't supply your own questions, the node adds a default Approve / Reject choice question (idapproval) that approval branches route on.clarification— an open-ended request for information. Its default question is a single free-text field (idresponse).
{
"task_type": "approval",
"title": "Approve email before sending"
}Title and description
title (required, up to 255 characters) is the headline the assignee sees in MagOneAI Hub. description (optional, up to 2000 characters) adds detail. Both support templates.
Good titles:
Review extracted invoice data for accuracyApprove high-value purchase request: AED {{amount}}Authorize payment of {{amount}} to {{vendor}}
Poor titles:
- "Review" (too vague)
- "Check this" (no context)
Assignees
assignee_id is the user (or users) who can complete the task. Provide a MagOneAI user ID, or a template that resolves to one such as {{system.user_id}}. Every assignee must be a member of the execution's project — assignees outside the project are rejected.
Assign the task to one user.
{ "assignee_id": "{{system.user_id}}" }Use when: one specific person owns the decision.
Assignees are identified by user ID, not email address or role. To route to a specific person from workflow data, resolve their user ID into the template.
Questions
questions defines what the human answers. Each question has an id, question text, and a question_type:
question_type | Answer | Notes |
|---|---|---|
choice | one option | Requires an options list (at least one; provide two or more for a real choice) |
multi_select | one or more options | Requires an options list (at least one; provide two or more for a real choice) |
text | free text | No options |
Set required to false to make an answer optional (the default is true).
{
"questions": [
{
"id": "decision",
"question": "Do you approve sending this email?",
"question_type": "choice",
"options": ["Approve", "Reject", "Edit"]
},
{
"id": "notes",
"question": "Any notes for the record?",
"question_type": "text",
"required": false
}
]
}If you omit questions, the node uses a sensible default for the task type: an Approve / Reject choice for approval, or a single free-text field for clarification. Questions can also be supplied dynamically — an upstream agent that emits a questions list has each one validated and used automatically (capped at 20).
Context for the reviewer
Give the human the information they need to decide. Two mechanisms, which can be combined:
context_fields— a map of named fields, each pulling a value from an earlier activity's output by path. Each field is{ "source": "...", "label": "..." }.include_previous_output— whentrue(the default), the previous activity's full output is attached as context as well.
{
"context_fields": {
"email": { "source": "compose.draft", "label": "Email Draft" },
"recipient": { "source": "compose.to", "label": "Recipient" }
},
"include_previous_output": true
}The assignee sees this data in MagOneAI Hub alongside the questions.
Approval branches
For approval tasks, branches routes the workflow based on the answer to the approval question (the default Approve / Reject question, or your own question with id approval). Each branch has a label matched against the answer and a goto naming the next node.
{
"task_type": "approval",
"branches": [
{ "label": "Approve", "goto": "send_email" },
{ "label": "Reject", "goto": "notify_rejection" }
]
}Branch matching uses the approval answer key. If you write your own approval questions, keep the deciding question's id as approval so branches can route on it.
Timeout
timeout_minutes bounds how long the node waits, from 1 minute up to 10080 (7 days). If no one responds in time, the task is marked timed out and the node fails with a timeout error, which your workflow's error handling can catch. Omit timeout_minutes to wait indefinitely.
{ "timeout_minutes": 1440 }Timeout is a simple duration. There is no built-in escalation, reassignment, or auto-approve on expiry — model those with a Condition node on the timeout error, or a follow-up Human Task, if you need them.
Use cases
Human Task nodes enable sophisticated human-in-the-loop workflows.
Financial approvals
Scenario: Approve invoices above a threshold before payment.
Workflow:
1. Extract invoice data (Agent)
2. Validate against PO (Agent)
3. Check budget availability (Tool)
4. Condition: amount > 10000
├─ True: Human Task: "Finance manager approval"
└─ False: Auto-approve
5. Process payment (Tool)
6. Send confirmation (Tool)Human Task configuration:
{
"task_type": "approval",
"title": "Approve invoice payment: {{vendor}} - {{amount}} {{currency}}",
"assignee_id": "{{input.finance_manager_id}}",
"context_fields": {
"invoice_number": { "source": "extract_invoice.invoice_number", "label": "Invoice #" },
"vendor": { "source": "extract_invoice.vendor_name", "label": "Vendor" },
"amount": { "source": "extract_invoice.total_amount", "label": "Amount" },
"budget_remaining": { "source": "budget_check.remaining", "label": "Budget remaining" }
},
"questions": [
{
"id": "approval",
"question": "Approve this payment?",
"question_type": "choice",
"options": ["Approve", "Reject"]
}
],
"timeout_minutes": 2880,
"branches": [
{ "label": "Approve", "goto": "process_payment" },
{ "label": "Reject", "goto": "notify_rejection" }
]
}Content review before publication
Scenario: Review AI-generated content before publishing to customers.
Workflow:
1. Generate content (Agent with RAG)
2. Fact-check against knowledge base (Agent)
3. Check brand guidelines (Agent)
4. Human Task: "Content review and approval"
5. Route on the decision
├─ Approve: Publish content (Tool)
└─ Request Changes / Reject: Return to drafts
6. Send publication notification (Tool)Human Task configuration:
{
"task_type": "approval",
"title": "Review article before publication: {{article_title}}",
"assignee_id": "{{input.reviewer_id}}",
"context_fields": {
"content": { "source": "generate_content.draft", "label": "Draft" },
"fact_check": { "source": "fact_checker.result", "label": "Fact-check results" },
"brand_check": { "source": "brand_checker.result", "label": "Brand check" }
},
"questions": [
{
"id": "approval",
"question": "Approve this article for publication?",
"question_type": "choice",
"options": ["Approve", "Request Changes", "Reject"]
}
],
"timeout_minutes": 240,
"branches": [
{ "label": "Approve", "goto": "publish" },
{ "label": "Request Changes", "goto": "return_to_drafts" },
{ "label": "Reject", "goto": "archive" }
]
}Data validation
Scenario: Validate AI-extracted data before committing to a database.
Workflow:
1. Extract data from document (Agent with vision)
2. Validate format and completeness (Agent)
3. Condition: confidence < 0.9
├─ True: Human Task: "Validate extracted data"
└─ False: Auto-approve
4. Save to database (Tool)
5. Send confirmation (Tool)Human Task configuration:
{
"task_type": "clarification",
"title": "Validate extracted data: {{document_type}}",
"assignee_id": "{{input.reviewer_id}}",
"context_fields": {
"extracted": { "source": "extractor.output", "label": "Extracted data" },
"confidence": { "source": "extractor.confidence", "label": "Confidence score" },
"issues": { "source": "validator.issues", "label": "Validation issues" }
},
"questions": [
{
"id": "correct",
"question": "Is the extracted data correct?",
"question_type": "choice",
"options": ["Correct", "Needs correction"]
},
{
"id": "corrections",
"question": "If corrections are needed, describe them:",
"question_type": "text",
"required": false
}
],
"timeout_minutes": 60
}Compliance review
Scenario: Route high-risk compliance findings to the legal team for a decision.
Workflow:
1. Analyze document for compliance (Agent)
2. Assess risk level (Agent)
3. Condition: risk_level == "high"
├─ True: Human Task: "Legal review required"
└─ False: Auto-process
4. Generate compliance report (Agent)
5. Save report (Tool)Human Task configuration:
{
"task_type": "approval",
"title": "Legal review required: high-risk compliance finding",
"assignee_id": "{{input.legal_counsel_id}}",
"context_fields": {
"risk_level": { "source": "risk_agent.risk_level", "label": "Risk level" },
"findings": { "source": "compliance_agent.findings", "label": "Findings" },
"recommendations": { "source": "compliance_agent.recommendations", "label": "Recommendations" }
},
"questions": [
{
"id": "approval",
"question": "How should this finding be handled?",
"question_type": "choice",
"options": ["Approve with Conditions", "Reject", "Request More Information"]
}
],
"timeout_minutes": 240,
"branches": [
{ "label": "Approve with Conditions", "goto": "generate_report" },
{ "label": "Reject", "goto": "flag_noncompliant" },
{ "label": "Request More Information", "goto": "gather_more_info" }
]
}Best practices
Use context_fields to surface exactly what the reviewer needs — key data points, AI analysis results, and links to source data. Keep include_previous_output on when the full upstream output helps, or turn it off to keep the task focused.
Consider business hours and time zones. Don't set a 1-hour timeout if the approver might be asleep. Remember a timeout fails the node — handle that path deliberately rather than leaving it to error out.
Good timeout examples:
- Urgent approval: a few hours (
timeout_minutes: 240) - Standard approval: one day (
timeout_minutes: 1440) - Non-urgent review: a few days (up to
10080)
Instead of generic Yes / No, use specific option labels: "Approve Payment", "Reject Invoice", "Request Changes". The option label is also what approval branches match on.
List multiple assignee_ids (comma-separated) so any available approver can act. The first response wins, so a task isn't blocked waiting on one specific person.
There is no separate comments field. To record why a decision was made, add a text question (mark it required when you need a justification on rejection). The answer is stored with the task's other answers.
Approval branches route on the approval answer key. If you replace the default question, keep the id of the deciding question as approval so routing still works.
Use Human Task nodes strategically. Not every decision needs human approval. Reserve human oversight for high-stakes decisions, low-confidence AI outputs, and situations where human judgment is genuinely needed.
Advanced patterns
Multi-stage approvals
Require multiple approvals in sequence:
Workflow:
1. Process request (Agent)
2. Human Task: "Manager approval"
3. Condition: approved AND amount > 50000
├─ True: Human Task: "Director approval"
└─ False: Continue
4. Execute action (Tool)Parallel approvals
Require multiple approvals simultaneously:
Workflow:
1. Process request (Agent)
2. Parallel Node:
├─ Branch 1: Human Task: "Finance approval"
├─ Branch 2: Human Task: "Legal approval"
└─ Branch 3: Human Task: "Compliance approval"
3. Condition: All approved
├─ True: Execute
└─ False: RejectConditional approval
Only require approval under certain conditions:
Workflow:
1. Process document (Agent)
2. Assess risk (Agent)
3. Condition: risk_score > 0.7 OR amount > threshold
├─ True: Human Task: "Approval required"
└─ False: Auto-approve
4. Continue processingApproval with agent augmentation
Agent assists human decision-making:
Workflow:
1. Analyze request (Agent)
2. Research relevant precedents (Agent with RAG)
3. Generate recommendation (Agent)
4. Human Task: "Final decision" (with AI recommendation in context_fields)
5. Process based on the human decisionIn MagOneAI Hub
Assigned users find the task in their MagOneAI Hub task queue. Opening a task shows its title and description, the context data the workflow attached, and the questions to answer. Any assignee can respond; the first submitted response completes the task and resumes the workflow. Tasks that have already been answered, timed out, or cancelled are no longer actionable.
Responding programmatically (API & webhooks)
Human tasks don't have to be answered from the Hub UI. A workflow started through the API trigger can pause on a Human Task and be resumed by an external system — so you can build approval steps into integrations where the approver lives in another application.
The flow mirrors the in-app experience over signed (HMAC-authenticated) API calls:
Trigger the workflow
Call the workflow's webhook endpoint. The response includes a poll token and poll URL you use to follow execution.
Detect the pending task
When the workflow reaches a Human Task, its status becomes waiting for input and polling surfaces the pending human-task IDs.
Read the task
Fetch the task to get its questions, options, and current status — the same content a Hub user would see.
Submit the response
Post the answers back to the task. The platform validates them against the task's questions, marks the task complete, and signals the workflow to resume. Submitting twice is safe — a task that's already answered isn't re-signalled.
Get the result
By default the submit call returns immediately and you poll for completion (including any new human task the workflow pauses on next). Optionally you can ask the call to wait briefly for the workflow to settle and return the outcome inline.
A webhook caller may only read and answer tasks belonging to executions it started, within the same project and any allowed-use-case restrictions on its API key. Requests outside that scope return a not-found error so task existence is never leaked.
This works for top-level executions as well as tasks inside schedules, sub-workflows, and foreach branches. Ready-to-paste request snippets (curl, Python, Node) are available in the API-key credentials screen in Studio.