last updated: june 20, 2025
Merge tasks collect desired playbook data and combine them into a single array. This array—the merge result—is found in the Raw Data tab of the Playbook Task Details popover.
Merge is useful when consolidating data from upstream task nodes that arrive either as:
Example - Merging Parallel Nodes *
objective – Merge the return data of three parallel task nodes into a string array.
Build the following playbook:
Configure task A to return the string "A", task B to return "B", and task C to return "C".
Provide the following configuration as input for the Merge task:
{
"groupBy": "Playbook Instance",
"dataJsonPath": "$.*.returnData"
}
Test run the playbook.
Observe the execution results for each task.
Data Formatter tasks:
Merge task:
Example - Merging Data from Instances of the Same Task *
objective – Use an Unwind task to split a list of objects into individual objects, update each one using a Data Formatter task, and then recombine the modified objects with a Merge task.
Build the following playbook:
Provide the following JSON data as input for the JSON Data parameter of the Unwind task :
[
{ "key1": "value1", "key2": "value2" },
{ "key3": "value3", "key4": "value4" },
{ "key5": "value5", "key6": "value6" }
]
Provide the following Jinja logic as input for the Process Object (Data Formatter) task:
{
{% set k1 = PlaybookData | jsonpath('$.Unwind.contextData.data.key1') %}
{% set k2 = PlaybookData | jsonpath('$.Unwind.contextData.data.key2') %}
{% set k3 = PlaybookData | jsonpath('$.Unwind.contextData.data.key3') %}
{% set k4 = PlaybookData | jsonpath('$.Unwind.contextData.data.key4') %}
{% set k5 = PlaybookData | jsonpath('$.Unwind.contextData.data.key5') %}
{% set k6 = PlaybookData | jsonpath('$.Unwind.contextData.data.key6') %}
{% if k1 %}
"key1": "UPDATED VALUE 1"{% if k2 %},{% endif %}
{% endif %}
{% if k2 %}
"key2": "UPDATED VALUE 2"{% if k3 %},{% endif %}
{% endif %}
{% if k3 %}
"key3": "UPDATED VALUE 3"{% if k4 %},{% endif %}
{% endif %}
{% if k4 %}
"key4": "UPDATED VALUE 4"{% if k5 %},{% endif %}
{% endif %}
{% if k5 %}
"key5": "UPDATED VALUE 5"{% if k6 %},{% endif %}
{% endif %}
{% if k6 %}
"key6": "UPDATED VALUE 6"
{% endif %}
}
Provide the following configuration as input for the Merge task:
{
"groupBy": "Task",
"taskName": "Unwind",
"dataJsonPath": "$['Process Object'].returnData"
}
Test run the playbook.
Observe the execution results for each task.
Merge Condition
The merge condition is a JSON object that tells the system how to group data based on a shared lineage—such as by Playbook Instance, Task, Task Instance, or Path—(lineage grouping), which data to filter, and the required match count for producing the merge result.
Merge Condition Schema
{
"groupBy": "<Playbook Instance | Task | Task Instance | Path>",
"taskName": "<Display name of the task>",
"paths": [
"<JSON path 1>",
"<JSON path 2>",
"<JSON path 3>",
...
"<JSON path N>"
],
"dataJsonPath": "<JSON path>",
"count": <Number>
}
The following tables list the (case-sensitive) keys for the merge condition.
Grouping Fields
These key-value pairs define the criteria for grouping data that share a common lineage. This defines the lineage grouping behavior.
Key
Data Type
Description
groupBy
string
taskName
string
paths
array<string>
Post-Grouping Fields
These key-value pairs control how grouped data is handled after lineage grouping has been applied.
Key
Data Type
Description
dataJsonPath
string
count
integer
The number of matched execution-lineage objects required to trigger the merge and generate the array for downstream workflows.
By default, all matched execution-lineage objects are returned in the merge output.
See the example below.
Example - Using the dataJsonPath Key
Objective – Understand the functionality and benefit of using the dataJsonPath key.
Build the following playbook:
Configure the playbook tasks:
Configure task A to return the string "A".
Configure task B to return the string "B".
Configure task C to return the array:
[
{ "key1": "value1", "key2": "value2" },
{ "key3": "value3", "key4": "value4" },
{ "key5": "value5", "key6": "value6" }
]
Configure Unwind to target {{ $.PlaybookData.C.returnData }} (i.e., the JSON Data parameter).
Configure task ABC to return "Hypothetically processed data".
Configure Merge with the following condition:
{
"groupBy": "Playbook Instance"
}
Test run the playbook.
Open D 's task details, then select the Playbook Data tab.
Expand the Merge > rawData field, then inspect each object in the rawData array.
Each object represents an execution lineage that led to the Merge task. In a real vSOC operation, this array may be significant in length.
Update the merge condition to the following:
{
"groupBy": "Playbook Instance",
"dataJsonPath": "$['ABC'].returnData"
}
Repeat steps 3–5, then recheck the rawData field.
This time, the rawData array contains only the returnData from task ABC instances.
READER NOTE
In a real scenario, each entry in the rawData array would typically contain distinct data, rather than identical hardcoded values.
The reduction to targeted task results simplifies data handling, improves clarity, and better supports debugging and modification.
Example - Using the count Key
Objective – Understand the functionality and benefit of using the count key.
Build the following playbook:
Configure the playbook tasks:
Configure task A to return the string "A".
Configure task B to return the string "B".
Configure task C to return the array:
[
{ "key1": "value1", "key2": "value2" },
{ "key3": "value3", "key4": "value4" },
{ "key5": "value5", "key6": "value6" }
]
Configure Unwind to target {{ $.PlaybookData.C.returnData }}.
Configure task ABC to return "Hypothetically processed data".
Configure Merge with the following condition:
{
"groupBy": "Playbook Instance"
}
Test run the playbook.
Open the D 's task details, then select the Playbook Data tab.
Expand the Merge > rawData field, then count the number of objects in the rawData array.
Each object represents an execution lineage that led to the Merge task. There is a count of five objects.
Update the merge condition to the following:
{
"groupBy": "Playbook Instance",
"count": 2
}
Repeat steps 3–5, then recheck the rawData field.
This time, there is a count of two objects in the rawData array.
TAKEAWAY
The count key limits the number of execution-lineage objects returned in the rawData field.
FAQ
What are execution-lineage objects?
Execution-lineage object = A JSON object containing the full sequence of task metadata and outputs that lead to an active execution point.
example
Given the following playbook build configuration:
Provided that the Merge task serves as the reference active execution point, the following are the execution lineages and their corresponding object representations:
lineage 1
{
"DataSource": { ... },
"A1": { ... }
}
lineage 2
{
"DataSource": { ... },
"B1": { ... },
"B2.1": { ... }
}
lineage 3
{
"DataSource": { ... },
"B1": { ... },
"B2.2": { ... }
}
Assuming the default merge condition is applied, the resulting merged output will be as follows:
[
{
"DataSource": { ... },
"A1": { ... }
},
{
"DataSource": { ... },
"B1": { ... },
"B2.1": { ... }
},
{
"DataSource": { ... },
"B1": { ... },
"B2.2": { ... }
}
]
TAKEAWAYS
An execution-lineage object describes a complete ancestral chain of task executions.
The default merge condition —unlike other grouping modes —will not, on its own, cause the merge result to exclude execution-lineage objects of any:
Divergent lineages (e.g., as with lineage 1 and lineage 2/3)
Sibling lineages (e.g., as with lineage 2 and lineage 3)
How can one use the dataJsonPath key to extract deeply nested values?
example 1
Build the following playbook.
Configure task A1 to return the following output:
[
{ "key1": "value1", "key2": "value2" },
{ "key3": "value3", "key4": "value4" },
{ "key5": "value5", "key6": "value6" }
]
Configure Merge with the following condition:
{
"groupBy": "Path",
"paths": ["$.['A1'].returnData"],
"dataJsonPath": "$['A1'].returnData[?(@.key2=='value2')]"
}
Test run the playbook.
Check the merge results.
Merge result
[
{
"key1": "value1",
"key2": "value2"
}
]
example 2
Configure task A1 to return the following output:
[
{
"A": {
"B": {
"C": {
"D": {
"TARGET": {
"id": 1,
"value": "match"
}
}
}
}
}
},
{
"A": {
"B": {
"C": {
"D": {
"TARGET": {
"id": 2,
"value": "no-match"
}
}
}
}
}
}
]
Configure Merge with the following condition:
{
"groupBy": "Path",
"paths": ["$['A1'].returnData"],
"dataJsonPath": "$['A1'].returnData[?(@.A.B.C.D.TARGET.value=='match')].A.B.C.D.TARGET"
}
Test run the playbook.
Check the merge result.
merge result
[
{
"id": 1,
"value": "match"
}
]