Input nodes
Input nodes pause a workflow and wait for a response before it continues. Use them to add human-in-the-loop steps such as approvals, manual gates, and decision points that require extra input.
When the workflow reaches an input node, the node stays in progress and notifies the responders you defined. Each responder opens the run, fills in a form, and clicks one of the node's buttons. Like condition nodes, an input node branches: it routes the workflow down a different path depending on which button responders press and how many of them respond.
How it works
The lifecycle of an input node is:
- The workflow reaches the input node, which enters an in progress state and pauses the run on that branch.
- Port notifies the configured responders (by email and/or webhook).
- A responder opens the run, clicks Provide inputs, fills in the form fields, and clicks one of the submit buttons.
- Port records the response and re-evaluates the node's outlets.
- When an outlet reaches its required number of responders, the node completes and the workflow continues down that outlet's path.
Example
The following input node asks responders to approve or decline, and continues on the approve path only after two approvals, or on the decline path after a single decline:
{
"identifier": "inputNode",
"title": "Approve/Decline",
"config": {
"type": "INPUT",
"description": "Approve or decline the production deployment.",
"userInputs": {
"properties": {
"reason": {
"type": "string",
"title": "Reason",
"description": "The reason for the approve/decline."
}
},
"buttons": [
{
"identifier": "approve",
"label": "Approve",
"variant": "PRIMARY"
},
{
"identifier": "decline",
"label": "Decline",
"variant": "DANGER"
}
]
},
"outlets": [
{
"evaluationMethod": "button",
"identifier": "approve",
"title": "Approve",
"numOfResponders": 2
},
{
"evaluationMethod": "button",
"identifier": "decline",
"title": "Decline",
"numOfResponders": 1
}
],
"responders": {
"users": ["alice@example.com", "bob@example.com"]
}
}
}
Configuration
An input node is defined by a config object with "type": "INPUT" and the following fields:
| Field | Required | Description |
|---|---|---|
type | Yes | Must be "INPUT". |
description | No | A short explanation shown to responders describing what they are responding to. |
userInputs | Yes | The form responders fill in, plus the submit buttons. See user inputs below. |
outlets | Yes | The branches the node can continue on, and how many responders each branch requires. See outlets below. |
responders | No | The users who are notified and allowed to respond. See responders below. |
notifications | No | Where Port sends notifications when the node is reached. See notifications below. |
User inputs
userInputs defines two things:
properties- the form fields shown to responders. These use the same schema as self-service user inputs, so you can collect text, numbers, entities, and any other supported input type.buttons- the submit buttons shown in the footer of the form. Each button records a different kind of response (for example, Approve or Decline).
Each button has the following fields:
| Field | Required | Description |
|---|---|---|
identifier | Yes | A unique identifier for the button. Outlets reference this value. |
label | Yes | The text shown on the button. |
variant | Yes | The button's visual style: PRIMARY, SECONDARY, or DANGER. |
icon | No | An optional icon to display on the button. |
Each button's identifier must be unique within the node, and every outlet must reference a valid button identifier.
Outlets
The node stays in progress until one of its outlets is satisfied. Each outlet maps to a button and defines how many responders must press that button before the workflow continues down its path.
In the example above, the node continues on the approve path after 2 approvals, or on the decline path after a single decline.
Each outlet has the following fields:
| Field | Required | Description |
|---|---|---|
evaluationMethod | Yes | How the outlet is evaluated. Currently "button" is supported. |
identifier | Yes | Must match the identifier of one of the node's buttons. |
title | No | A human-readable name for the outlet, shown in the graph. |
numOfResponders | Yes | The number of responses on this button required to continue down this path. Must be a positive integer. |
statusLabel | No | A label applied to the node run when this outlet is taken. Has a text field (supports JQ) and an optional variant of success or alert. |
workflowStatusLabel | No | Same as statusLabel, but applied to the entire workflow run. |
Port tallies responses per button. After each response, it checks the outlets in the order they are defined and continues on the first outlet whose numOfResponders threshold has been reached. Outlet identifiers must be unique within the node.
Responders
responders defines who is notified and allowed to respond to the node. Responders are specified by users, a list of user emails:
{
"responders": {
"users": ["alice@example.com", "bob@example.com"]
}
}
Each responder can submit a response only once. Attempting to respond again returns an error.
Notifications
notifications controls where Port sends a notification when the node is reached. It is an array of targets, each of which is one of:
- An email target, with a list of
fields(each alabelandvalue) to include in the notification. - A webhook target, used to notify an external system. It supports
url,method(defaults toPOST), and optionalheadersandbody.
{
"notifications": [
{
"target": "email",
"fields": [
{ "label": "Service", "value": ".outputs.trigger.serviceName" }
]
},
{
"target": "webhook",
"url": "https://example.com/notify",
"method": "POST",
"body": { "message": "An input node is awaiting your response" }
}
]
}
Responders specified under responders.users are automatically notified by email, in addition to any targets you define here.
Connections
Like condition nodes, connections from an input node must specify which outlet they belong to, using sourceOutletIdentifier:
{
"connections": [
{
"sourceIdentifier": "inputNode",
"targetIdentifier": "production-deploy",
"sourceOutletIdentifier": "approve"
},
{
"sourceIdentifier": "inputNode",
"targetIdentifier": "sendSlack",
"sourceOutletIdentifier": "decline"
}
]
}
Each sourceOutletIdentifier must reference a valid outlet identifier on the node.
Outputs
An input node produces the following outputs, which subsequent nodes can reference through data flow:
selectedOutlet.identifier- the identifier of the outlet the node continued on (for example,approve).responses- the list of submitted responses. Each response includes the button that was pressed (buttonIdentifier), the submitted form values (inputs), and submitter information (submitterInfowithsubmittedByandcreatedAt).
For example, to branch on the chosen outlet in a downstream node:
{{ .outputs["inputNode"].selectedOutlet.identifier }}
To reference a value a responder submitted in the form:
{{ .outputs["inputNode"].responses[0].inputs.reason }}
Related links
- Condition nodes - Branch a workflow based on JQ expressions.
- Data flow - Pass outputs between nodes.
- User inputs - Configure the form fields responders fill in.