> ## Documentation Index
> Fetch the complete documentation index at: https://helpcenter.magure.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 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.

<Steps>
  <Step title="Workflow reaches Human Task">
    Execution arrives at the Human Task node. The workflow prepares to pause.
  </Step>

  <Step title="Execution pauses">
    The workflow execution pauses and its status becomes **waiting for input**. Temporal maintains the complete state durably, so no data is lost.
  </Step>

  <Step title="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
  </Step>

  <Step title="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.
  </Step>

  <Step title="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.
  </Step>

  <Step title="Workflow continues">
    Subsequent nodes can access the human's answers, and approval tasks can route the workflow based on the decision.
  </Step>
</Steps>

<Note>
  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.
</Note>

## 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 (id `approval`) that approval branches route on.
* **`clarification`** — an open-ended request for information. Its default question is a single free-text field (id `response`).

```json theme={null}
{
  "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 accuracy`
* `Approve 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.

<Tabs>
  <Tab title="Single assignee">
    Assign the task to one user.

    ```json theme={null}
    { "assignee_id": "{{system.user_id}}" }
    ```

    **Use when:** one specific person owns the decision.
  </Tab>

  <Tab title="Multiple assignees (first responder wins)">
    Assign the task to several people by passing a **comma-separated** list of user IDs. The task lands in every assignee's queue, and the **first** to respond completes it and unblocks the workflow; later responses are ignored. Up to 50 assignees per task.

    ```json theme={null}
    { "assignee_id": "user_id_a,user_id_b,user_id_c" }
    ```

    **Use when:** anyone on a team can handle the task and you want the fastest available approver.
  </Tab>

  <Tab title="Dynamic assignment">
    Resolve the assignee from earlier workflow data. The template must produce a user ID (or comma-separated user IDs).

    ```json theme={null}
    { "assignee_id": "{{input.assigned_manager_id}}" }
    ```

    **Use when:** the assignee depends on workflow context, such as the account manager for a specific customer.
  </Tab>
</Tabs>

<Note>
  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.
</Note>

### 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`).

```json theme={null}
{
  "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`** — when `true` (the default), the previous activity's full output is attached as context as well.

```json theme={null}
{
  "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.

```json theme={null}
{
  "task_type": "approval",
  "branches": [
    { "label": "Approve", "goto": "send_email" },
    { "label": "Reject", "goto": "notify_rejection" }
  ]
}
```

<Note>
  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.
</Note>

### 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](/workflows/triggers-and-execution) can catch. Omit `timeout_minutes` to wait indefinitely.

```json theme={null}
{ "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](/workflows/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:**

```json theme={null}
{
  "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:**

```json theme={null}
{
  "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:**

```json theme={null}
{
  "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:**

```json theme={null}
{
  "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

<AccordionGroup>
  <Accordion title="Provide rich context">
    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.
  </Accordion>

  <Accordion title="Set realistic timeouts">
    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`)
  </Accordion>

  <Accordion title="Use clear action labels">
    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.
  </Accordion>

  <Accordion title="Assign to several people when speed matters">
    List multiple `assignee_id`s (comma-separated) so any available approver can act. The first response wins, so a task isn't blocked waiting on one specific person.
  </Accordion>

  <Accordion title="Capture the reason with a follow-up question">
    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.
  </Accordion>

  <Accordion title="Keep the deciding question id as 'approval'">
    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.
  </Accordion>
</AccordionGroup>

<Tip>
  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.
</Tip>

## 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: Reject
```

### Conditional 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 processing
```

### Approval 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 decision
```

## In 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](/workflows/triggers-and-execution#api) 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:

<Steps>
  <Step title="Trigger the workflow">
    Call the workflow's webhook endpoint. The response includes a poll token and poll URL you use to follow execution.
  </Step>

  <Step title="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.
  </Step>

  <Step title="Read the task">
    Fetch the task to get its questions, options, and current status — the same content a Hub user would see.
  </Step>

  <Step title="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.
  </Step>

  <Step title="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.
  </Step>
</Steps>

<Note>
  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.
</Note>

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.

## Next steps

<CardGroup cols={2}>
  <Card title="Condition node" icon="code-branch" href="/workflows/condition-node">
    Route to human tasks based on conditions
  </Card>

  <Card title="Parallel node" icon="code-branch" href="/workflows/parallel-node">
    Require multiple parallel approvals
  </Card>

  <Card title="Agent node" icon="robot" href="/workflows/agent-node">
    Use agents to prepare context for human review
  </Card>

  <Card title="Memory system" icon="database" href="/workflows/memory">
    Access human task responses in subsequent nodes
  </Card>
</CardGroup>
