Skip to content

Human Task

"type" : "HUMAN"

The Human task (HUMAN) is used to pause the workflow and wait for an external signal. It acts as a gate that remains in IN_PROGRESS until marked as COMPLETED or FAILED by an external trigger.

The Human task can be used when the workflow needs to pause and wait for human intervention, such as manual approval. It can also be used with an event coming from external source such as Kafka, SQS, or Conductor's internal queueing mechanism.

Task parameters

No parameters are required to configure the Human task.

JSON configuration

Here is the task configuration for a Human task.

{
    "name": "human",
  "taskReferenceName": "human_ref",
    "inputParameters": {},
    "type": "HUMAN"
}

Completing the Human task

There are several ways to complete the Human task:

  • Using the Task Update API
  • Using an event handler

Task Update API

Use the Task Update API (POST api/tasks) to complete a Human task. Provide the taskId, the task status, and the desired task output.

Using the CLI:

conductor task update-execution --workflow-id {workflowId} --task-ref-name waiting_around_ref --status COMPLETED --output '{"data_key":"somedatatoWait1","data_key2":"somedatatoWAit2"}'

Event handler

If SQS integration is enabled, the Human task can also be resolved using the Update Queue APIs:

  1. POST api/queue/update/{workflowId}/{taskRefName}/{status}
  2. POST api/queue/update/{workflowId}/task/{taskId}/{status}

Any parameter that is sent in the body of the POST message will be repeated as the output of the task. For example, if we send a COMPLETED message as follows:

Using cURL
curl -X "POST" "{{ server_host }}{{ api_prefix }}/queue/update/{workflowId}/waiting_around_ref/COMPLETED" \
  -H 'Content-Type: application/json' \
  -d '{"data_key":"somedatatoWait1","data_key2":"somedatatoWAit2"}'

The output of the Human task will be:

{
  "data_key":"somedatatoWait1",
  "data_key2":"somedatatoWAit2"
}

Alternatively, an event handler using the complete_task action can also be configured.

Monitoring Human Tasks: Getting Callbacks and Notifications

When a workflow reaches a Human task, you may want to receive a notification or callback to trigger the next action (e.g., send an email, notify a Slack channel, or trigger an external system). Here are the recommended patterns:

Pattern 1: Polling the Workflow Status API

The simplest approach is to poll the workflow execution status and check for Human tasks in IN_PROGRESS state:

# Get workflow execution status
curl '{{ server_host }}/api/workflow/{workflowId}' \
  -H 'accept: application/json'

Parse the response to find tasks with taskType: "HUMAN" and status: "IN_PROGRESS".

Pros: Simple to implement, no additional configuration Cons: Requires polling, not real-time

Pattern 2: Event Handlers with Conductor Internal Events

Conductor can publish internal events when tasks change state. You can configure an event handler to listen for these events:

{
  "name": "human_task_notification_handler",
  "event": "conductor:TASK_STATUS_CHANGE",
  "condition": "$.taskType == 'HUMAN' && $.status == 'IN_PROGRESS'",
  "actions": [
    {
      "action": "start_workflow",
      "start_workflow": {
        "name": "notification_workflow",
        "input": {
          "workflowId": "${workflowId}",
          "taskRefName": "${taskRefName}",
          "taskStatus": "${status}"
        }
      }
    }
  ]
}

This triggers a notification workflow whenever a Human task enters IN_PROGRESS state.

Pattern 3: Webhook Integration via Event Task

Add an EVENT task immediately before the Human task to send a webhook notification:

{
  "name": "notify_human_task",
  "taskReferenceName": "notify_ref",
  "type": "EVENT",
  "sink": "kafka:human-task-notifications",
  "inputParameters": {
    "workflowId": "${workflow.input.workflowId}",
    "taskRefName": "human_ref",
    "eventType": "HUMAN_TASK_PENDING"
  }
},
{
  "name": "human_approval",
  "taskReferenceName": "human_ref",
  "type": "HUMAN"
}

Then configure an event handler or external consumer to process these notifications.

Pattern 4: Complete Task with Callback Output

When completing the Human task, include callback information in the output:

curl -X POST "{{ server_host }}/api/tasks" \
  -H 'Content-Type: application/json' \
  -d '{
    "taskId": "${taskId}",
    "status": "COMPLETED",
    "output": {
      "approvedBy": "user@example.com",
      "approvedAt": "2026-04-22T10:30:00Z",
      "comments": "Approved for production deployment"
    }
  }'

The output becomes available to downstream tasks and can be used for audit trails or further notifications.

Pattern 5: External System Integration

For real-time notifications, integrate with external systems:

  1. Slack/Teams: Use an event handler to trigger a notification workflow that posts to Slack/Teams webhooks
  2. Email: Send email notifications via SMTP or email service APIs
  3. SMS/Push: Integrate with Twilio, Pushover, or similar services
  4. Custom Webhooks: POST to your internal systems when human tasks are pending

Best Practices

  • Use correlation IDs: Include workflowId and taskRefName in all notifications for easy tracking
  • Set timeouts: Consider adding timeout logic to escalate unapproved human tasks
  • Audit trail: Log all human task completions with timestamps and user information
  • Idempotency: Ensure notification handlers are idempotent to handle duplicate events

Example: Complete Notification Flow

{
  "name": "approval_workflow",
  "version": 1,
  "tasks": [
    {
      "name": "send_approval_request",
      "taskReferenceName": "send_request_ref",
      "type": "HTTP",
      "inputParameters": {
        "http_request": {
          "method": "POST",
          "url": "https://hooks.slack.com/services/xxx",
          "body": {
            "text": "Approval needed for workflow ${workflow.input.requestId}"
          }
        }
      }
    },
    {
      "name": "wait_for_approval",
      "taskReferenceName": "approval_ref",
      "type": "HUMAN"
    },
    {
      "name": "send_approval_result",
      "taskReferenceName": "send_result_ref",
      "type": "HTTP",
      "inputParameters": {
        "http_request": {
          "method": "POST",
          "url": "https://hooks.slack.com/services/xxx",
          "body": {
            "text": "Approval ${approval_ref.output.status} by ${approval_ref.output.approvedBy}"
          }
        }
      }
    }
  ]
}

This workflow: 1. Sends a Slack notification when approval is needed 2. Waits for human approval 3. Sends a follow-up notification with the approval result