Merge Step
Rejoins values from multiple incoming workflow branches into a single set of output fields. Use this step after a Logic step (or other branching) so downstream steps can read one mapped value per field regardless of which branch ran. At runtime, each field takes the first non-empty source.
Merge cannot be the first step in a workflow. Create it with at least one incoming edge. Typical graphs place Merge after a Logic step so each Logic branch feeds one incoming edge.
Each merge field may map at most one source per incoming branch. Unattributable sources (session placeholders, UUID mapping ids) are allowed through; readable pills ({{Step.Field}}) that cannot be attributed to a single incoming branch are rejected.
Top-level properties
| name | type | required | constraints | description |
|---|---|---|---|---|
mergeableName | string | yes | Display name for the merge output (typically "Merge"). Used as the step label in mapping pills. | |
fields | array | yes | items: MergeField | Ordered output fields. Each field is published to session context under id when a source resolves. |
MergeField
| name | type | required | constraints | description |
|---|---|---|---|---|
id | string | yes | format: uuid | Stable field identifier. Downstream mappings reference this id. |
label | string | yes | Human-readable field name. | |
type | string | yes | enum: see MergeFieldType below | Output type. Incoming values are coerced to this type. |
sources | array | yes | items: string | Ordered source values, usually mapping pills ({{Step.Field}}). First non-empty source wins. |
Empty string, null, and empty collections are treated as empty. Scalar numbers/booleans/files count as present.
MergeFieldType enum
| Type | Description |
|---|---|
string | Single string. |
number | Single number. |
boolean | Single boolean. |
date | Single date (ISO 8601). |
file | Single file. |
array<string> | List of strings. |
array<number> | List of numbers. |
array<boolean> | List of booleans. |
array<date> | List of dates. |
array<file> | List of files. |
Supported inbound coercions depend on type. For example number accepts string/number/boolean; date accepts string or date; file accepts file or an array of files (collapsed to one). Invalid coercions fail the step.
Examples
Minimal example: One field, two branch sources
{
"mergeableName": "Merge",
"fields": [
{
"id": "3f1c9a2e-8b44-4d1a-9c7e-1a2b3c4d5e6f",
"label": "Customer name",
"type": "string",
"sources": [
"{{`Premium form`.`fullName`}}",
"{{`Standard form`.`fullName`}}"
]
}
]
}At runtime, if the premium branch ran and fullName is "Alice", the merge publishes Customer name = "Alice". If that source is empty, it uses the standard-form source instead.
Connect Merge to existing steps (POST /v1/steps)
POST /v1/steps)Create the Merge step with edges. Each incoming predecessor is a { "prev": ... } entry (prev is the step id or description). { "next": ... } is optional and inserts Merge in front of that step.
When prev is a Logic step, branch is required and must match that branch's label. Omit branch for every other step type.
Logic split → two forms → Merge → notification
Logic
├─ branch "High value" → Premium form ─┐
└─ branch "Fallback branch" → Standard form ─┴→ Merge → Notification
{
"workflowId": "11111111-1111-1111-1111-111111111111",
"description": "Merge",
"type": "merge",
"version": 1,
"edges": [
{ "prev": "Premium form" },
{ "prev": "Standard form" },
{ "next": "Notification" }
],
"config": {
"mergeableName": "Merge",
"fields": [
{
"id": "3f1c9a2e-8b44-4d1a-9c7e-1a2b3c4d5e6f",
"label": "Customer name",
"type": "string",
"sources": [
"{{`Premium form`.`fullName`}}",
"{{`Standard form`.`fullName`}}"
]
}
]
}
}Logic branches wired straight into Merge (no intermediate steps on those branches):
{
"workflowId": "11111111-1111-1111-1111-111111111111",
"description": "Merge",
"type": "merge",
"version": 1,
"edges": [
{ "prev": "Logic", "branch": "High value" },
{ "prev": "Logic", "branch": "Fallback branch" }
],
"config": {
"mergeableName": "Merge",
"fields": []
}
}prev may be a step UUID instead of description. Incoming prev-only edges are the merge branches used to validate “one source per incoming branch”.
Full example: Mixed types after a Logic split
JSON
{
"mergeableName": "Merge",
"fields": [
{
"id": "a11c9a2e-8b44-4d1a-9c7e-1a2b3c4d5e6f",
"label": "Amount",
"type": "number",
"sources": [
"{{`High-value path`.`credit`}}",
"{{`Standard path`.`credit`}}"
]
},
{
"id": "b22c9a2e-8b44-4d1a-9c7e-1a2b3c4d5e6f",
"label": "Signed file",
"type": "file",
"sources": [
"{{`High-value path`.`contract`}}",
"{{`Standard path`.`contract`}}"
]
},
{
"id": "c33c9a2e-8b44-4d1a-9c7e-1a2b3c4d5e6f",
"label": "Tags",
"type": "array<string>",
"sources": [
"{{`High-value path`.`tags`}}",
"{{`Standard path`.`tags`}}"
]
}
]
}Updated 6 days ago
