Human-in-the-Loop with USER_INPUT
Some processes require human approval, review, or sign-off. A USER_INPUT task suspends the running workflow, emits a Notification Service event, and holds the run in PAUSED state until a permitted user submits their input.
The Workflow
The Weather_Alert_Human_Approval workflow fetches and analyses weather information and then pauses to request user approval.
fetch_weather (SCRIPT_EXECUTION)
→ analyze_weather (SCRIPT_EXECUTION → severity)
→ request_approval (USER_INPUT) ← workflow PAUSES here
→ act_on_decision (SCRIPT_EXECUTION) ← reads the human's answer
The USER_INPUT Task
Here's the configuration for the USER_INPUT task in the Weather_Alert_Human_Approval workflow. It specifies the notification type as well as the requried _userInput needed to continue.
{
_type: "USER_INPUT",
_name: "request_approval",
_sequenceno: 3,
_inputParams: {
_sendNotification: true,
_notificationId: "weather_alert_approval",
_userInputPermissions: [
{ _userType: "user", _id: approverUserId }
],
_userInput: {
approve: { type: "string", enum: ["yes", "no"] },
note: { type: "string" }
}
}
}
Key fields:
_userInputdeclares the shape of the answer expected from the human: here anapproveenum and a free-textnote._userInputPermissionslists who may provide the reqruied input. You can provide multiple individual users and user groups to the_userInputPermissionsto allow users to provide the required input to the workflow. User groups are specified by configuring{ _userType: 'usergroup', _id: <_id of the user group> }while individual users are specifed by{ _userType: 'user', _id:<_id of a user> }. Your user _id was when you deployed the template package for the course. You can see it by right clickingWeather_Alert_Human_Approvaland selecting 'View Definition JSON'._sendNotification/_notificationIdcause the pause to emit a Notification Service event so a UI or subscriber can react. These live at the top of_inputParams, as siblings of_userInput.
Because the run may wait for a person, the definition sets a generous _timeoutSeconds: 3600.
Reading the Human's Input Downstream
USER_INPUT output is addressed differently from a script output — the submitted fields live under {{task name}}._output._userInput.<field>:
{
_type: "SCRIPT_EXECUTION",
_name: "act_on_decision",
_sequenceno: 4,
_inputParams: {
_userType: "weather_workflow_demo_static",
_scriptName: "actOnApprovalDecision",
approve: "${request_approval._output._userInput.approve}",
note: "${request_approval._output._userInput.note}",
severity: "${analyze_weather._output.scriptOutput}"
}
}
actOnApprovalDecision then dispatches on the answer. Sending the alert when approve === "yes" and suppressing it otherwise.
Running the Workflow
- Run
runWeatherWorkflowwith input copying and pasting this value into the input field:
{ "workflowUserType": "weather_workflow_transformer_static" }
- Monitor with
getLatestWorkflowRunByUserType.
The run advances to request_approval and then pauses (PAUSED).
-
Submit the human decision by running
updateWeatherUserInputRunwith the following input:{ "approve": "yes", "note": "Approved via the course" }With no
workflowRunId, theupdateWeatherUserInputRunscript targets the latest run of the user-input workflow. It resolves the paused run and itsUSER_INPUTtask, then calls the SDK:IafWorkflowSvc.updateUserInput(runId, userInputId, { _userInput: { approve, note } }, ctx) -
The run resumes,
act_on_decisionruns, and the workflow completes. Confirm withgetLatestWorkflowRunByUserTypeorpollWorkflowUntilComplete.
Inspecting the Pause / Notification
Two helpers exist to understand the paused state and its notification context:
resolveWeatherUserInputRun(internal helper) locates the run, itsUSER_INPUTtask, the runtimeuserInputId, and the_notificationId.sendWeatherUserInputNotificationsurfaces the notification context: it builds an event payload shaped like the liveworkflowsvc.UserInputevent and lists the current user's Notification Service history and any matching triggers.
There is no API to re-fire the UserInput event after the fact — the workflow emits workflowsvc.UserInput once, when the task starts (because _sendNotification: true). To actually reach an approver by email or webhook, a Notification Service trigger must be configured to filter on event = UserInput and notificationId = weather_alert_approval. This is the bridge between a paused workflow and the outside world; the helper lets you verify that bridge is in place.
Human Input is an API Call
Notice that completing a human task is an ordinary authenticated API call (updateUserInput). In a real application that call is made by a UI action, a chatbot, or another service. Anything that can present the decision to a permitted user and post their answer. The workflow does not care what the front end is; it only cares that a permitted user submitted an answer of the declared shape.