Configuration and outputs
Action nodes perform operations in your workflow. They execute after trigger nodes and can be chained together to create complex automation flows.
Common configuration
All action nodes share these common fields:
| Field | Description |
|---|---|
identifier | Unique identifier for the node within the workflow |
title | Display name for the node |
icon | Optional icon for the node |
description | Optional description of what the node does |
config | The action configuration (type-specific) |
variables | Optional key-value pairs for reusable expressions |
links | Optional array of URL templates (max 3) evaluated when the node run completes. See Attaching links to node runs. |
verbose | When true, enables verbose logging for the node. Default: false |
Attaching links to node runs
The links field lets you attach up to 3 URLs to a node run. The URLs are evaluated when the node run completes and are shown in the node details panel of the workflow run page.
Each entry in links is a URL string that can include template expressions using the {{ }} syntax. The available context variables are:
| Variable | Description |
|---|---|
.result | The node's output object |
.outputs | Outputs from all previous nodes, keyed by node identifier |
.workflow | Workflow-level variables |
.workflowRun | Workflow run metadata |
.workflowNodeRun | Current node run metadata (e.g. identifier, createdAt) |
If a template expression fails to evaluate or produces an invalid URL, that link is skipped and a warning is written to the node's logs.
Example - link to the resource created by a node:
{
"identifier": "create_service",
"title": "Create Service",
"links": [
"https://app.example.com/services/{{ .result.serviceId }}",
"https://ci.example.com/pipelines/{{ .result.pipelineId }}"
],
"config": {
"type": "WEBHOOK",
"url": "https://api.example.com/services",
"method": "POST",
"body": {
"name": "{{ .outputs.trigger.serviceName }}"
}
}
}
When the node run completes, the expressions are evaluated against the node's output. The resulting URLs appear in the node details panel for that run.
Links can also be attached dynamically when reporting a node run result via the API - see Updating node runs.
On failure
Action nodes that execute operations (WEBHOOK, KAFKA, UPSERT_ENTITY, INTEGRATION_ACTION) support an onFailure configuration option:
| Field | Type | Default | Description |
|---|---|---|---|
onFailure | 'continue' | 'terminate' | 'terminate' | When set to 'continue', the workflow continues to the next nodes even if this node fails. When set to 'terminate', the workflow run is marked as failed and no subsequent nodes are executed. |
By default, when an action node fails, the entire workflow run is marked as failed and no subsequent nodes are executed. Setting onFailure: 'continue' allows the workflow to proceed despite the failure.
The failed node is still marked with a FAILED result. The onFailure option only affects whether subsequent nodes are executed.
Example:
{
"identifier": "optional-notification",
"title": "Send Optional Notification",
"config": {
"type": "WEBHOOK",
"url": "https://hooks.slack.com/services/xxx",
"method": "POST",
"onFailure": "continue",
"body": {
"text": "Deployment started for {{ .outputs.trigger.service }}"
}
}
}
In this example, even if the Slack notification fails, the workflow will continue to execute subsequent nodes.
When a node fails, its output includes an error object with a message field describing the failure. Downstream nodes can reference it (for example when using onFailure: 'continue') to handle or log the error:
| Field | Description |
|---|---|
output.error.message | Human-readable error message describing why the node failed |
Example output from a failed node:
{
"error": {
"message": "Request failed: connection refused"
}
}
Referencing outputs
Action nodes can reference outputs from previous nodes using bracket notation .outputs["<node_identifier>"].<field>:
| Context | Description |
|---|---|
.outputs["<node_identifier>"].<field> | Output from any previous node (including trigger) |
.secrets["<name>"] | Organization secrets |
For self-service triggers, the user inputs are stored directly at .outputs["<trigger-node-identifier>"].<input_key>.
For event triggers, the event data is stored at .outputs["<trigger-node-identifier>"].diff.after, .outputs["<trigger-node-identifier>"].action, etc.
Example
Chaining node outputs
This example demonstrates how to pass data between nodes. A self-service trigger collects a resource name from the user, passes it to a webhook that creates the resource, and then sends a Slack notification with the newly created resource ID.
Chaining node outputs (click to expand)
{
"nodes": [
{
"identifier": "trigger",
"title": "Start",
"config": {
"type": "SELF_SERVE_TRIGGER",
"userInputs": {
"properties": {
"resourceName": { "type": "string" }
}
}
}
},
{
"identifier": "create_resource",
"title": "Create Resource",
"config": {
"type": "WEBHOOK",
"url": "https://api.example.com/resources",
"method": "POST",
"body": {
"name": "{{ .outputs.trigger.resourceName }}"
}
}
},
{
"identifier": "notify",
"title": "Send Notification",
"config": {
"type": "WEBHOOK",
"url": "https://hooks.slack.com/xxx",
"method": "POST",
"body": {
"text": "Created resource with ID: {{ .outputs.create_resource.response.data.resourceId }}"
}
}
}
],
"connections": [
{
"sourceIdentifier": "trigger",
"targetIdentifier": "create_resource"
},
{
"sourceIdentifier": "create_resource",
"targetIdentifier": "notify"
}
]
}
Condition nodes
In addition to action nodes, workflows support condition nodes for branching logic:
{
"identifier": "check-environment",
"title": "Check Environment",
"config": {
"type": "CONDITION",
"options": [
{
"identifier": "production",
"title": "Production",
"expression": ".outputs.trigger.environment == \"production\""
},
{
"identifier": "staging",
"title": "Staging",
"expression": ".outputs.trigger.environment == \"staging\""
}
]
}
}
Connections from condition nodes must specify which option they're connected to:
{
"connections": [
{
"sourceIdentifier": "check-environment",
"targetIdentifier": "production-deploy",
"sourceOptionIdentifier": "production"
},
{
"sourceIdentifier": "check-environment",
"targetIdentifier": "staging-deploy",
"sourceOptionIdentifier": "staging"
},
{
"sourceIdentifier": "check-environment",
"targetIdentifier": "default-deploy",
"fallback": true
}
]
}