---
title: "Update a workflow node"
method: POST
path: "/v1/workflows/{workflowId}/nodes/{nodeId}"
tags: ["Workflow nodes"]
---

# Update a workflow node

`POST /v1/workflows/{workflowId}/nodes/{nodeId}`

Update workflow-node-owned fields for a single node. Shared resources such as email messages and audience segments should be updated through their own APIs.

## Request body

- UpdateWorkflowNodeRequest
  - `expectedRevisionId` string, nullable, required — The workflow revision token returned by the latest workflow read or mutation. Older workflows may return `null` before their first revision-aware mutation; pass `null` back as `expectedRevisionId` in that case. If the token is stale, the API returns a `409 Conflict` error.
  - `payload` union, required — Node-type-specific fields to update. The allowed fields depend on the existing node type. Trigger node updates may include `typeName` when changing one trigger node type to another trigger node type.
    - WorkflowSignupTriggerPayload — Changes an existing trigger node to a signup trigger.
      - `typeName` 'SignupTrigger', required
    - WorkflowEventTriggerPayload — Updates an event trigger, or changes an existing trigger node to an event trigger. Assign the event pattern with either `eventPatternId` or `eventName`, not both. Set either field to `null` to clear the event-pattern relationship.
      - `typeName` 'EventTrigger'
      - `eventPatternId` string, nullable — The ID of the event pattern to trigger on. Use either `eventPatternId` or `eventName`, not both. Set to `null` to clear the event-pattern relationship.
      - `eventName` string, nullable — The name of the event pattern to trigger on. Use this when you know the event name but not the internal event pattern ID. Use either `eventName` or `eventPatternId`, not both. Set to `null` to clear the event-pattern relationship.
      - `reEligible` boolean — If `true`, the contacts will be able to enter this workflow every time the trigger is matched. If `false`, contacts will only ever enter this workflow once. Matches the "Trigger frequency" option in the UI.
    - WorkflowContactPropertyTriggerPayload — Updates a contact-property trigger, or changes an existing trigger node to a contact-property trigger.
      - `typeName` 'ContactPropertyTrigger'
      - `contactPropertyQuery` WorkflowContactPropertyQuery — Define the contact property change that triggers the workflow. In update requests, `key` must resolve to an existing contact property that is available for Contact Updated triggers. Hidden or unsupported fields, such as `createdAt`, `notes`, and computed contact properties, are rejected.
        - `key` string, required — The camel-cased `key` of the contact property to query. The property must exist for the team and must be available for Contact Updated triggers.
        - `is` WorkflowContactPropertyComparison, required — For Contact Updated triggers, the API validates `operator` against the selected contact property's type and the side of the comparison. The `was` comparison can use any operator supported by the selected property type. The `is` comparison uses the same operators, except number and boolean properties cannot use `empty`. String properties support `any`, `equal`, `not_equal`, `contains`, `not_contains`, `empty`, and `not_empty`. Number properties support `any`, `greater_than`, `less_than`, `numeric_equal`, `numeric_not_equal`, `empty`, and `not_empty`. Boolean properties support `any`, `true`, `false`, `empty`, and `not_empty`. Date properties support `any`, `empty`, `not_empty`, `after`, `before`, and `between`.
          - `value` union, required
            - string
            - number
            - boolean
          - `operator` 'any' | 'contains' | 'not_contains' | 'empty' | 'not_empty' | 'equal' | 'not_equal' | 'greater_than' | 'less_than' | 'true' | 'false' | 'numeric_equal' | 'numeric_not_equal' | 'after' | 'before' | 'between', required — The comparison operator. It must be valid for the selected contact property's type and for the `is` or `was` side of the comparison. Number and boolean properties allow `empty` on `was`, but not on `is`.
        - `was` WorkflowContactPropertyComparison, required — For Contact Updated triggers, the API validates `operator` against the selected contact property's type and the side of the comparison. The `was` comparison can use any operator supported by the selected property type. The `is` comparison uses the same operators, except number and boolean properties cannot use `empty`. String properties support `any`, `equal`, `not_equal`, `contains`, `not_contains`, `empty`, and `not_empty`. Number properties support `any`, `greater_than`, `less_than`, `numeric_equal`, `numeric_not_equal`, `empty`, and `not_empty`. Boolean properties support `any`, `true`, `false`, `empty`, and `not_empty`. Date properties support `any`, `empty`, `not_empty`, `after`, `before`, and `between`.
          - `value` union, required
            - string
            - number
            - boolean
          - `operator` 'any' | 'contains' | 'not_contains' | 'empty' | 'not_empty' | 'equal' | 'not_equal' | 'greater_than' | 'less_than' | 'true' | 'false' | 'numeric_equal' | 'numeric_not_equal' | 'after' | 'before' | 'between', required — The comparison operator. It must be valid for the selected contact property's type and for the `is` or `was` side of the comparison. Number and boolean properties allow `empty` on `was`, but not on `is`.
      - `reEligible` boolean — If `true`, the contacts will be able to enter this workflow every time the trigger is matched. If `false`, contacts will only ever enter this workflow once. Matches the "Trigger frequency" option in the UI.
    - WorkflowAddToListTriggerPayload — Updates an add-to-list trigger, or changes an existing trigger node to an add-to-list trigger.
      - `typeName` 'AddToListTrigger'
      - `reEligible` boolean — If `true`, the contacts will be able to enter this workflow every time the trigger is matched. If `false`, contacts will only ever enter this workflow once. Matches the "Trigger frequency" option in the UI.
    - WorkflowAudienceFilterPayload — Configuration for the audience filter node.
      - `audienceSegmentId` string, nullable — The ID of an audience segment. Setting this without also providing `audienceFilter` clears any existing `audienceFilter`. If both are provided, the filter is applied on top of the segment's filter.
      - `audienceFilter` AudienceFilterInRequest, nullable — A tree of audience conditions combined with `match`. Setting this without also providing `audienceSegmentId` clears any existing `audienceSegmentId`. When both are provided, this filter is applied on top of the segment's filter.
        - `match` 'all' | 'any', required
        - `conditions` AudienceFilterCondition[], required
          - union
            - PropertyCondition — Matches contacts by a property value.
              - …
            - OptInCondition — Matches contacts by mailing-list opt-in status.
              - …
            - ActivityCondition — Matches contacts by their activity on a campaign or workflow.
              - …
      - `appliesDownstream` boolean — If `true`, the audience filter will apply to all downstream nodes. If `false`, the audience filter will only apply to the current node. Matches the "Filter scope" option in the UI.
    - WorkflowTimerActionPayload — Configuration for the timer action node.
      - `amount` number — The amount of time to wait before triggering the next node. Set to `0` to move to the next node immediately.
      - `unit` 'm' | 'h' | 'd' — The unit of time for the timer action node. m = minutes, h = hours, d = days.
    - WorkflowExperimentBranchPayload — Configuration for the experiment branch node.
      - `samplingRate` number — The percentage of contacts that will be sent to variant branches, between `0` and `100`. The remaining percentage will be sent to the control branch. `100` sends all contacts to variant branches.
    - WorkflowVariantPayload — Configuration for the variant node.
      - `isControl` boolean — Use `true` to set this variant as the control of the experiment. This will set `false` on the existing control, if one exists. Experiments do not require a control variant.

## Response `200`

Workflow node updated.

- union
  - object — The updated workflow node, plus the latest simplified workflow.
    - `id` string, required
    - `typeName` 'SignupTrigger', required
    - `nextNodeIds` string[], required — The IDs of the nodes that are downstream of this node.
    - `workflowRevisionId` string, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation.
    - `workflow` SimplifiedWorkflow, required
      - `id` string, required — The ID of the workflow.
      - `workflowRevisionId` string, nullable, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation. Will be `null` for workflows without a revision token yet.
      - `status` 'Draft' | 'Sending' | 'Paused' | 'PausedAndQueueing', required
      - `name` string — The name of the workflow.
      - `description` string — The description of the workflow.
      - `mailingListId` string, nullable, required — The ID of the mailing list the workflow sends to.
      - `rootNodeId` string, required — The ID of the root node in the workflow graph.
      - `nodes` object, required — A map of node IDs to simplified node objects. Each node includes `typeName` and `nextNodeIds`, plus type-specific fields when present. To get the full node object, use the `GET /v1/workflows/{workflowId}/nodes/{nodeId}` endpoint.
  - object — The updated workflow node, plus the latest simplified workflow.
    - `id` string, required
    - `typeName` 'EventTrigger', required
    - `nextNodeIds` string[], required — The IDs of the nodes that are downstream of this node.
    - `eventName` string — The name of the event pattern that triggers this node.
    - `eventProperties` WorkflowEventProperty[] — The properties of the event pattern, which can be used in emails.
      - `name` string, required
      - `type` 'string' | 'number' | 'boolean' | 'date', required
    - `reEligible` boolean, required — If `true`, the contacts will be able to enter this workflow every time the trigger is matched. If `false`, contacts will only ever enter this workflow once. Matches the "Trigger frequency" option in the UI.
    - `workflowRevisionId` string, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation.
    - `workflow` SimplifiedWorkflow, required
      - `id` string, required — The ID of the workflow.
      - `workflowRevisionId` string, nullable, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation. Will be `null` for workflows without a revision token yet.
      - `status` 'Draft' | 'Sending' | 'Paused' | 'PausedAndQueueing', required
      - `name` string — The name of the workflow.
      - `description` string — The description of the workflow.
      - `mailingListId` string, nullable, required — The ID of the mailing list the workflow sends to.
      - `rootNodeId` string, required — The ID of the root node in the workflow graph.
      - `nodes` object, required — A map of node IDs to simplified node objects. Each node includes `typeName` and `nextNodeIds`, plus type-specific fields when present. To get the full node object, use the `GET /v1/workflows/{workflowId}/nodes/{nodeId}` endpoint.
  - object — The updated workflow node, plus the latest simplified workflow.
    - `id` string, required
    - `typeName` 'ContactPropertyTrigger', required
    - `nextNodeIds` string[], required — The IDs of the nodes that are downstream of this node.
    - `contactPropertyQuery` WorkflowContactPropertyQuery, required — Define the contact property change that triggers the workflow. In update requests, `key` must resolve to an existing contact property that is available for Contact Updated triggers. Hidden or unsupported fields, such as `createdAt`, `notes`, and computed contact properties, are rejected.
      - `key` string, required — The camel-cased `key` of the contact property to query. The property must exist for the team and must be available for Contact Updated triggers.
      - `is` WorkflowContactPropertyComparison, required — For Contact Updated triggers, the API validates `operator` against the selected contact property's type and the side of the comparison. The `was` comparison can use any operator supported by the selected property type. The `is` comparison uses the same operators, except number and boolean properties cannot use `empty`. String properties support `any`, `equal`, `not_equal`, `contains`, `not_contains`, `empty`, and `not_empty`. Number properties support `any`, `greater_than`, `less_than`, `numeric_equal`, `numeric_not_equal`, `empty`, and `not_empty`. Boolean properties support `any`, `true`, `false`, `empty`, and `not_empty`. Date properties support `any`, `empty`, `not_empty`, `after`, `before`, and `between`.
        - `value` union, required
          - string
          - number
          - boolean
        - `operator` 'any' | 'contains' | 'not_contains' | 'empty' | 'not_empty' | 'equal' | 'not_equal' | 'greater_than' | 'less_than' | 'true' | 'false' | 'numeric_equal' | 'numeric_not_equal' | 'after' | 'before' | 'between', required — The comparison operator. It must be valid for the selected contact property's type and for the `is` or `was` side of the comparison. Number and boolean properties allow `empty` on `was`, but not on `is`.
      - `was` WorkflowContactPropertyComparison, required — For Contact Updated triggers, the API validates `operator` against the selected contact property's type and the side of the comparison. The `was` comparison can use any operator supported by the selected property type. The `is` comparison uses the same operators, except number and boolean properties cannot use `empty`. String properties support `any`, `equal`, `not_equal`, `contains`, `not_contains`, `empty`, and `not_empty`. Number properties support `any`, `greater_than`, `less_than`, `numeric_equal`, `numeric_not_equal`, `empty`, and `not_empty`. Boolean properties support `any`, `true`, `false`, `empty`, and `not_empty`. Date properties support `any`, `empty`, `not_empty`, `after`, `before`, and `between`.
        - `value` union, required
          - string
          - number
          - boolean
        - `operator` 'any' | 'contains' | 'not_contains' | 'empty' | 'not_empty' | 'equal' | 'not_equal' | 'greater_than' | 'less_than' | 'true' | 'false' | 'numeric_equal' | 'numeric_not_equal' | 'after' | 'before' | 'between', required — The comparison operator. It must be valid for the selected contact property's type and for the `is` or `was` side of the comparison. Number and boolean properties allow `empty` on `was`, but not on `is`.
    - `reEligible` boolean, required — If `true`, the contacts will be able to enter this workflow every time the trigger is matched. If `false`, contacts will only ever enter this workflow once. Matches the "Trigger frequency" option in the UI.
    - `workflowRevisionId` string, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation.
    - `workflow` SimplifiedWorkflow, required
      - `id` string, required — The ID of the workflow.
      - `workflowRevisionId` string, nullable, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation. Will be `null` for workflows without a revision token yet.
      - `status` 'Draft' | 'Sending' | 'Paused' | 'PausedAndQueueing', required
      - `name` string — The name of the workflow.
      - `description` string — The description of the workflow.
      - `mailingListId` string, nullable, required — The ID of the mailing list the workflow sends to.
      - `rootNodeId` string, required — The ID of the root node in the workflow graph.
      - `nodes` object, required — A map of node IDs to simplified node objects. Each node includes `typeName` and `nextNodeIds`, plus type-specific fields when present. To get the full node object, use the `GET /v1/workflows/{workflowId}/nodes/{nodeId}` endpoint.
  - object — The updated workflow node, plus the latest simplified workflow.
    - `id` string, required
    - `typeName` 'AddToListTrigger', required
    - `nextNodeIds` string[], required — The IDs of the nodes that are downstream of this node.
    - `mailingListId` string, nullable, required — The ID of the mailing list this trigger sends to, if set.
    - `reEligible` boolean, required — If `true`, the contacts will be able to enter this workflow every time the trigger is matched. If `false`, contacts will only ever enter this workflow once. Matches the "Trigger frequency" option in the UI.
    - `workflowRevisionId` string, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation.
    - `workflow` SimplifiedWorkflow, required
      - `id` string, required — The ID of the workflow.
      - `workflowRevisionId` string, nullable, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation. Will be `null` for workflows without a revision token yet.
      - `status` 'Draft' | 'Sending' | 'Paused' | 'PausedAndQueueing', required
      - `name` string — The name of the workflow.
      - `description` string — The description of the workflow.
      - `mailingListId` string, nullable, required — The ID of the mailing list the workflow sends to.
      - `rootNodeId` string, required — The ID of the root node in the workflow graph.
      - `nodes` object, required — A map of node IDs to simplified node objects. Each node includes `typeName` and `nextNodeIds`, plus type-specific fields when present. To get the full node object, use the `GET /v1/workflows/{workflowId}/nodes/{nodeId}` endpoint.
  - object — The updated workflow node, plus the latest simplified workflow.
    - `id` string, required
    - `typeName` 'BlankTrigger', required
    - `nextNodeIds` string[], required — The IDs of the nodes that are downstream of this node.
    - `workflowRevisionId` string, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation.
    - `workflow` SimplifiedWorkflow, required
      - `id` string, required — The ID of the workflow.
      - `workflowRevisionId` string, nullable, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation. Will be `null` for workflows without a revision token yet.
      - `status` 'Draft' | 'Sending' | 'Paused' | 'PausedAndQueueing', required
      - `name` string — The name of the workflow.
      - `description` string — The description of the workflow.
      - `mailingListId` string, nullable, required — The ID of the mailing list the workflow sends to.
      - `rootNodeId` string, required — The ID of the root node in the workflow graph.
      - `nodes` object, required — A map of node IDs to simplified node objects. Each node includes `typeName` and `nextNodeIds`, plus type-specific fields when present. To get the full node object, use the `GET /v1/workflows/{workflowId}/nodes/{nodeId}` endpoint.
  - object — The updated workflow node, plus the latest simplified workflow.
    - `id` string, required
    - `typeName` 'AudienceFilter', required
    - `nextNodeIds` string[], required — The IDs of the nodes that are downstream of this node.
    - `audienceFilter` AudienceFilter, nullable — A tree of audience conditions combined with `match`.
      - `match` 'all' | 'any', required
      - `conditions` AudienceFilterCondition[], required
        - union
          - PropertyCondition — Matches contacts by a property value.
            - `type` 'property', required
            - `key` string, required — The contact property name.
            - `operator` 'any' | 'contains' | 'notContains' | 'equals' | 'notEquals' | 'greaterThan' | 'lessThan' | 'isTrue' | 'isFalse' | 'empty' | 'notEmpty' | 'dateEmpty' | 'dateNotEmpty' | 'after' | 'before' | 'between', required
            - `value` union — The comparison value. Omitted for value-less operators (e.g. `isTrue`, `empty`). A `{ from, to }` object for `between`.
              - …
          - OptInCondition — Matches contacts by mailing-list opt-in status.
            - `type` 'optIn', required
            - `status` 'accepted' | 'pending' | 'rejected' | 'null', nullable, required
          - ActivityCondition — Matches contacts by their activity on a campaign or workflow.
            - `type` 'activity', required
            - `action` 'sent' | 'opened' | 'clicked', required
            - `negate` boolean, required
            - `target` 'campaign' | 'workflow' | 'workflowEmail', required
            - `id` string, required — The ID of the campaign, workflow, or workflow email.
    - `audienceSegmentId` string — The ID of the audience segment this trigger targets.
    - `appliesDownstream` boolean, required — If `true`, the audience filter will apply to all downstream nodes. If `false`, the audience filter will only apply to the current node. Matches the "Filter scope" option in the UI.
    - `workflowRevisionId` string, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation.
    - `workflow` SimplifiedWorkflow, required
      - `id` string, required — The ID of the workflow.
      - `workflowRevisionId` string, nullable, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation. Will be `null` for workflows without a revision token yet.
      - `status` 'Draft' | 'Sending' | 'Paused' | 'PausedAndQueueing', required
      - `name` string — The name of the workflow.
      - `description` string — The description of the workflow.
      - `mailingListId` string, nullable, required — The ID of the mailing list the workflow sends to.
      - `rootNodeId` string, required — The ID of the root node in the workflow graph.
      - `nodes` object, required — A map of node IDs to simplified node objects. Each node includes `typeName` and `nextNodeIds`, plus type-specific fields when present. To get the full node object, use the `GET /v1/workflows/{workflowId}/nodes/{nodeId}` endpoint.
  - object — The updated workflow node, plus the latest simplified workflow.
    - `id` string, required
    - `typeName` 'TimerAction', required
    - `nextNodeIds` string[], required — The IDs of the nodes that are downstream of this node.
    - `amount` number, required — The amount of time to wait before triggering the next node. Set to `0` to move to the next node immediately.
    - `unit` 'm' | 'h' | 'd', required — The unit of time for the timer action node. m = minutes, h = hours, d = days.
    - `workflowRevisionId` string, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation.
    - `workflow` SimplifiedWorkflow, required
      - `id` string, required — The ID of the workflow.
      - `workflowRevisionId` string, nullable, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation. Will be `null` for workflows without a revision token yet.
      - `status` 'Draft' | 'Sending' | 'Paused' | 'PausedAndQueueing', required
      - `name` string — The name of the workflow.
      - `description` string — The description of the workflow.
      - `mailingListId` string, nullable, required — The ID of the mailing list the workflow sends to.
      - `rootNodeId` string, required — The ID of the root node in the workflow graph.
      - `nodes` object, required — A map of node IDs to simplified node objects. Each node includes `typeName` and `nextNodeIds`, plus type-specific fields when present. To get the full node object, use the `GET /v1/workflows/{workflowId}/nodes/{nodeId}` endpoint.
  - object — The updated workflow node, plus the latest simplified workflow.
    - `id` string, required
    - `typeName` 'SendEmailAction', required
    - `nextNodeIds` string[], required — The IDs of the nodes that are downstream of this node.
    - `emailMessageId` string, required — The ID of the email message to send. To edit this email, use the `POST /v1/email-messages/{emailMessageId}` endpoint.
    - `subject` string, required
    - `workflowRevisionId` string, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation.
    - `workflow` SimplifiedWorkflow, required
      - `id` string, required — The ID of the workflow.
      - `workflowRevisionId` string, nullable, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation. Will be `null` for workflows without a revision token yet.
      - `status` 'Draft' | 'Sending' | 'Paused' | 'PausedAndQueueing', required
      - `name` string — The name of the workflow.
      - `description` string — The description of the workflow.
      - `mailingListId` string, nullable, required — The ID of the mailing list the workflow sends to.
      - `rootNodeId` string, required — The ID of the root node in the workflow graph.
      - `nodes` object, required — A map of node IDs to simplified node objects. Each node includes `typeName` and `nextNodeIds`, plus type-specific fields when present. To get the full node object, use the `GET /v1/workflows/{workflowId}/nodes/{nodeId}` endpoint.
  - object — The updated workflow node, plus the latest simplified workflow.
    - `id` string, required
    - `typeName` 'ExitAction', required
    - `nextNodeIds` string[], required — The IDs of the nodes that are downstream of this node.
    - `workflowRevisionId` string, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation.
    - `workflow` SimplifiedWorkflow, required
      - `id` string, required — The ID of the workflow.
      - `workflowRevisionId` string, nullable, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation. Will be `null` for workflows without a revision token yet.
      - `status` 'Draft' | 'Sending' | 'Paused' | 'PausedAndQueueing', required
      - `name` string — The name of the workflow.
      - `description` string — The description of the workflow.
      - `mailingListId` string, nullable, required — The ID of the mailing list the workflow sends to.
      - `rootNodeId` string, required — The ID of the root node in the workflow graph.
      - `nodes` object, required — A map of node IDs to simplified node objects. Each node includes `typeName` and `nextNodeIds`, plus type-specific fields when present. To get the full node object, use the `GET /v1/workflows/{workflowId}/nodes/{nodeId}` endpoint.
  - object — The updated workflow node, plus the latest simplified workflow.
    - `id` string, required
    - `typeName` 'BranchNode', required
    - `nextNodeIds` string[], required — The IDs of the nodes that are downstream of this node.
    - `workflowRevisionId` string, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation.
    - `workflow` SimplifiedWorkflow, required
      - `id` string, required — The ID of the workflow.
      - `workflowRevisionId` string, nullable, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation. Will be `null` for workflows without a revision token yet.
      - `status` 'Draft' | 'Sending' | 'Paused' | 'PausedAndQueueing', required
      - `name` string — The name of the workflow.
      - `description` string — The description of the workflow.
      - `mailingListId` string, nullable, required — The ID of the mailing list the workflow sends to.
      - `rootNodeId` string, required — The ID of the root node in the workflow graph.
      - `nodes` object, required — A map of node IDs to simplified node objects. Each node includes `typeName` and `nextNodeIds`, plus type-specific fields when present. To get the full node object, use the `GET /v1/workflows/{workflowId}/nodes/{nodeId}` endpoint.
  - object — The updated workflow node, plus the latest simplified workflow.
    - `id` string, required
    - `typeName` 'ExperimentBranchNode', required
    - `nextNodeIds` string[], required — The IDs of the nodes that are downstream of this node.
    - `samplingRate` number, required — The percentage of contacts that will be sent to variant branches, between `0` and `100`. The remaining percentage will be sent to the control branch. `100` sends all contacts to variant branches.
    - `workflowRevisionId` string, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation.
    - `workflow` SimplifiedWorkflow, required
      - `id` string, required — The ID of the workflow.
      - `workflowRevisionId` string, nullable, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation. Will be `null` for workflows without a revision token yet.
      - `status` 'Draft' | 'Sending' | 'Paused' | 'PausedAndQueueing', required
      - `name` string — The name of the workflow.
      - `description` string — The description of the workflow.
      - `mailingListId` string, nullable, required — The ID of the mailing list the workflow sends to.
      - `rootNodeId` string, required — The ID of the root node in the workflow graph.
      - `nodes` object, required — A map of node IDs to simplified node objects. Each node includes `typeName` and `nextNodeIds`, plus type-specific fields when present. To get the full node object, use the `GET /v1/workflows/{workflowId}/nodes/{nodeId}` endpoint.
  - object — The updated workflow node, plus the latest simplified workflow.
    - `id` string, required
    - `typeName` 'VariantNode', required
    - `nextNodeIds` string[], required — The IDs of the nodes that are downstream of this node.
    - `isControl` boolean — Whether this is the control variant of an experiment.
    - `workflowRevisionId` string, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation.
    - `workflow` SimplifiedWorkflow, required
      - `id` string, required — The ID of the workflow.
      - `workflowRevisionId` string, nullable, required — The current workflow revision token. Pass the latest value as `expectedRevisionId` on the next workflow mutation. Will be `null` for workflows without a revision token yet.
      - `status` 'Draft' | 'Sending' | 'Paused' | 'PausedAndQueueing', required
      - `name` string — The name of the workflow.
      - `description` string — The description of the workflow.
      - `mailingListId` string, nullable, required — The ID of the mailing list the workflow sends to.
      - `rootNodeId` string, required — The ID of the root node in the workflow graph.
      - `nodes` object, required — A map of node IDs to simplified node objects. Each node includes `typeName` and `nextNodeIds`, plus type-specific fields when present. To get the full node object, use the `GET /v1/workflows/{workflowId}/nodes/{nodeId}` endpoint.

## Other responses

- `400` — Invalid `workflowId`, `nodeId`, request body, or node update.
- `401` — Invalid API key.
- `404` — Workflow or workflow node not found.
- `405` — Wrong HTTP request method.
- `409` — `expectedRevisionId` is stale.
- `501` — This node update is not implemented.

---

[API](https://skmtc.net/loops/apis/loops-openapi-spec.md) · [All operations](https://skmtc.net/loops/apis/loops-openapi-spec/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/loops/loops-openapi-spec/revisions/9cc087257f0d/schema)
