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

nametyperequiredconstraintsdescription
mergeableNamestringyesDisplay name for the merge output (typically "Merge"). Used as the step label in mapping pills.
fieldsarrayyesitems: MergeFieldOrdered output fields. Each field is published to session context under id when a source resolves.

MergeField

nametyperequiredconstraintsdescription
idstringyesformat: uuidStable field identifier. Downstream mappings reference this id.
labelstringyesHuman-readable field name.
typestringyesenum: see MergeFieldType belowOutput type. Incoming values are coerced to this type.
sourcesarrayyesitems: stringOrdered 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

TypeDescription
stringSingle string.
numberSingle number.
booleanSingle boolean.
dateSingle date (ISO 8601).
fileSingle 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)

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`}}"
      ]
    }
  ]
}

Did this page help you?