---
title: "Update workflow"
method: PATCH
path: "/workflows/{workflow_id}"
tags: ["Workflows"]
---

# Update workflow

`PATCH /workflows/{workflow_id}`

Update workflow metadata or replace workflow definition collections.

Common updates:
- Change workflow name or description
- Update workflow definition nodes and edges
- Activate workflow by setting status to 'active'
- Archive workflow by setting status to 'archived'

Definition update semantics:
- Omit `definition` to update metadata only.
- Omit `definition.nodes` to leave nodes unchanged.
- Include `definition.nodes` only when sending the complete desired node set. Nodes omitted from that array are removed.
- Omit `definition.edges` to leave edges unchanged.
- Include `definition.edges` only when sending the complete desired edge set. Edges omitted from that array are removed.
- Use snake_case config keys in API payloads.

Successful responses contain workflow metadata, including the new `lock_version`. They do not include the expanded graph. Call `GET /workflows/{workflow_id}/definition` after updating when you need the saved nodes and edges.

You can update the definition of an active workflow. Changes take effect immediately for new executions; running executions continue with the snapshot they started with.

## Request body

- WorkflowUpdateRequest
  - `workflow` object, required
    - `name` string — Workflow name (must be unique within project)
    - `slug` string — URL-safe identifier. Slug is decoupled from name — renaming the workflow does not change the slug, you must update it explicitly.
    - `description` string, nullable — Workflow description
    - `status` 'draft' | 'active' | 'archived' — Workflow lifecycle status
    - `message_debounce_seconds` integer, nullable — Debounce window for incoming messages in seconds (default: 1)
    - `inbound_message_read_mode` 'disabled' | 'read_only' | 'read_with_typing' — Controls how inbound WhatsApp messages are marked as read before the workflow responds. - `disabled`: Do nothing - `read_only`: Mark as read, no typing indicator - `read_with_typing`: Mark as read and show typing indicator (default)
    - `lock_version` integer — Current optimistic lock version. Required to prevent concurrent modification conflicts.
    - `definition` WorkflowDefinitionInput — Workflow graph write payload. Field names are snake_case. The expanded definition response includes persisted IDs such as edge IDs and condition IDs; those IDs are optional in write payloads.
      - `nodes` WorkflowDefinitionInputNode[] — Desired node set for the workflow. When `nodes` is present on create or update, it is treated as the complete node set: nodes omitted from the array are removed. Omit `nodes` to leave existing nodes unchanged on update.
        - `id` string, required — Stable step identifier used by edges. Use a readable identifier such as `send_intro`.
        - `type` string — Canvas renderer type. Use `flow-node`.
        - `position` WorkflowDefinitionNodePosition, required — Canvas position of the node.
          - `x` number, required — Horizontal canvas position.
          - `y` number, required — Vertical canvas position.
        - `data` WorkflowDefinitionInputNodeData, required — Node data write payload.
          - `node_type` 'start' | 'send_text' | 'send_template' | 'send_interactive' | 'wait_for_response' | 'decide' | 'function' | 'webhook' | 'agent' | 'call' | 'handoff' | 'set_variable' | 'emit_event', required — Canonical backend node type.
          - `config` union, required — Node configuration. Shape depends on `node_type`.
            - WorkflowNodeStartConfig — Empty config for the `start` node.
            - WorkflowNodeSendTextConfig — Config for `send_text` nodes.
              - …
            - WorkflowNodeSendTemplateConfig — Config for `send_template` nodes.
              - …
            - WorkflowNodeSendInteractiveConfig — Config for `send_interactive` nodes.
              - …
            - WorkflowNodeWaitForResponseConfig — Config returned for `wait_for_response` nodes.
              - …
            - WorkflowNodeDecideConfig — Config returned for `decide` nodes.
              - …
            - WorkflowNodeFunctionConfig — Config for `function` nodes.
              - …
            - WorkflowNodeWebhookConfig — Config for `webhook` nodes.
              - …
            - WorkflowNodeAgentConfig — Config returned for `agent` nodes.
              - …
            - WorkflowNodeCallConfig — Config returned for `call` nodes.
              - …
            - WorkflowNodeHandoffConfig — Config for `handoff` nodes.
              - …
            - WorkflowNodeSetVariableConfig — Config for `set_variable` nodes.
              - …
            - WorkflowNodeEmitEventConfig — Config for `emit_event` nodes.
              - …
          - `display_name` string — Optional human-friendly label shown in the visual editor.
      - `edges` WorkflowDefinitionInputEdge[] — Desired edge set for the workflow. When `edges` is present on create or update, it is treated as the complete edge set: edges omitted from the array are removed. Omit `edges` to leave existing edges unchanged on update.
        - `id` string, uuid — Optional existing edge ID. Usually omitted for new edges.
        - `source` string, required — Source node identifier.
        - `target` string, required — Target node identifier.
        - `label` string — Transition label. Use `next` for non-decision nodes. For decide nodes, this must match a condition label.
        - `type` string — Optional canvas edge renderer type. The API returns `default`.
        - `flow_condition_id` string, uuid, nullable — Optional persisted condition ID for decide-step edges. If omitted, the API resolves decide edges by `label`.

## Response `200`

Workflow updated successfully

- WorkflowResponse — Single workflow response
  - `data` Workflow, required
    - `id` string, uuid, required — Unique workflow identifier
    - `name` string, required — Workflow name (unique per project)
    - `slug` string, required — URL-safe workflow identifier (lowercase alphanumeric with hyphens). Stable across renames — useful as an external sync key. Auto-generated from `name` on create if not provided. Unique within the project.
    - `description` string, nullable — Optional workflow description
    - `status` 'draft' | 'active' | 'archived', required — Workflow lifecycle status: - `draft`: Under development, not executable - `active`: Published and executable - `archived`: Inactive, no longer in use
    - `lock_version` integer, nullable — Optimistic locking version. Increment on each update to prevent concurrent modification conflicts. Include this value when updating to ensure you're working with the latest version.
    - `message_debounce_seconds` integer, nullable — Debounce window for incoming messages in seconds (default: 1). When a user sends multiple messages rapidly, the workflow waits this duration before processing to batch messages together. Prevents workflow from reacting to every keystroke.
    - `agent_default_tools_version` integer, nullable — Version used to decide which built-in agent tools are required by default for this workflow.
    - `inbound_message_read_mode` 'disabled' | 'read_only' | 'read_with_typing' — Controls how inbound WhatsApp messages are marked as read before the workflow responds (default: read_with_typing). - `disabled`: Do nothing — messages are not marked as read - `read_only`: Mark messages as read without showing a typing indicator - `read_with_typing`: Mark as read and show a typing indicator before responding
    - `created_at` string, date-time, required — Workflow creation timestamp
    - `updated_at` string, date-time, required — Last modification timestamp
    - `project_id` string, uuid — Project this workflow belongs to
    - `execution_count` integer — Total number of times this workflow has been executed
    - `last_executed_at` string, date-time, nullable — Timestamp of most recent execution, null if never executed

## Other responses

- `401` — Missing or invalid API key
- `404` — Resource not found
- `409` — Conflict — the supplied `lock_version` is stale. Refetch the workflow to get the current version and retry.
- `422` — Request validation failed

---

[API](https://skmtc.net/kapso/apis/kapso-platform-api.md) · [All operations](https://skmtc.net/kapso/apis/kapso-platform-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/kapso/kapso-platform-api/revisions/18ff5548a33f/schema)
