> ## Documentation Index
> Fetch the complete documentation index at: https://chatbotx.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Update flow draft

> Overwrites the draft version's nodes/edges in place, without publishing. Accepts either the raw `{ nodes, edges }` graph the builder UI sends, or `{ spec }` compiled server-side into that same graph — draft nodes are not otherwise validated (see `flows.validate` to check a spec before writing it). Unlike `flows.create`, a raw node's `id` is persisted verbatim, not remapped, so it must already be a numeric string (the same format `flows.create`'s `nodeIds` response and `flows.get` return).



## OpenAPI

````yaml /api-reference/platform-api.json put /v1/flows/{id}/draft
openapi: 3.1.1
info:
  title: ChatbotX
  version: 0.0.1
servers:
  - url: https://app.chatbotx.io/api
security:
  - bearerAuth: []
  - developerAccessToken: []
  - tokenInSearchParams: []
paths:
  /v1/flows/{id}/draft:
    put:
      tags:
        - Flows
      summary: Update flow draft
      description: >-
        Overwrites the draft version's nodes/edges in place, without publishing.
        Accepts either the raw `{ nodes, edges }` graph the builder UI sends, or
        `{ spec }` compiled server-side into that same graph — draft nodes are
        not otherwise validated (see `flows.validate` to check a spec before
        writing it). Unlike `flows.create`, a raw node's `id` is persisted
        verbatim, not remapped, so it must already be a numeric string (the same
        format `flows.create`'s `nodeIds` response and `flows.get` return).
      operationId: flows.updateDraft
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            pattern: ^\d+$
            description: flow id (numeric string). Get it from `flows.list`.
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                spec:
                  type: object
                  properties:
                    formatVersion:
                      const: 1
                      description: DSL format version. Always 1.
                    name:
                      type: string
                      minLength: 1
                      maxLength: 255
                      description: Flow name (max 255 characters).
                    channel:
                      enum:
                        - omnichannel
                        - webchat
                        - messenger
                        - whatsapp
                        - zalo
                        - smtp
                        - telegram
                        - instagram
                        - threads
                        - tiktok
                        - api
                      type: string
                      description: >-
                        Channel this flow targets. Omit for any/omnichannel.
                        sendTemplate steps always send over WhatsApp regardless
                        of this value.
                    steps:
                      type: array
                      minItems: 1
                      items:
                        anyOf:
                          - type: object
                            properties:
                              type:
                                const: send
                                description: 'Step type: "send".'
                              id:
                                type: string
                                minLength: 1
                                description: >-
                                  Stable id for this step. Omit to auto-generate
                                  one. Set it explicitly when a `goto` elsewhere
                                  needs to jump to this exact step.
                              text:
                                type: string
                                minLength: 1
                                maxLength: 1000
                                description: >-
                                  Text message body (max 1000 characters).
                                  Exactly one of text/imageUrl/fileUrl is
                                  required.
                              imageUrl:
                                type: string
                                format: uri
                                description: >-
                                  Image URL to send. Exactly one of
                                  text/imageUrl/fileUrl is required.
                              fileUrl:
                                type: string
                                format: uri
                                description: >-
                                  File URL to send. Exactly one of
                                  text/imageUrl/fileUrl is required.
                              buttons:
                                type: array
                                maxItems: 3
                                items:
                                  type: object
                                  properties:
                                    text:
                                      type: string
                                      minLength: 1
                                      maxLength: 20
                                      description: >-
                                        Button label shown to the contact (max
                                        20 characters).
                                    then:
                                      type: array
                                      items:
                                        anyOf:
                                          - {}
                                          - {}
                                          - {}
                                          - {}
                                          - {}
                                          - {}
                                          - {}
                                          - {}
                                      description: >-
                                        Steps to run when the contact taps this
                                        button. Omitted or empty means the
                                        button has no follow-up.
                                  required:
                                    - text
                                  description: >-
                                    A quick-reply button attached to a send
                                    step.
                                description: >-
                                  Up to 3 quick-reply buttons attached to this
                                  message.
                            required:
                              - type
                            description: >-
                              Sends one message (text, image, or file),
                              optionally with quick-reply buttons.
                          - type: object
                            properties:
                              type:
                                const: sendTemplate
                                description: 'Step type: "sendTemplate".'
                              id:
                                type: string
                                minLength: 1
                                description: >-
                                  Stable id for this step. Omit to auto-generate
                                  one. Set it explicitly when a `goto` elsewhere
                                  needs to jump to this exact step.
                              templateName:
                                type: string
                                minLength: 1
                                description: >-
                                  Name of an existing WhatsApp message template
                                  whose status is `APPROVED` (see
                                  `capabilities.get`'s `templates` list). Sent
                                  as-is, without dynamic variables.
                            required:
                              - type
                              - templateName
                            description: Sends an existing WhatsApp message template.
                          - type: object
                            properties:
                              type:
                                const: wait
                                description: 'Step type: "wait".'
                              id:
                                type: string
                                minLength: 1
                                description: >-
                                  Stable id for this step. Omit to auto-generate
                                  one. Set it explicitly when a `goto` elsewhere
                                  needs to jump to this exact step.
                              duration:
                                type: integer
                                minimum: -9007199254740991
                                maximum: 9007199254740991
                                exclusiveMinimum: 0
                                description: How long to wait, in `unit`s.
                              unit:
                                enum:
                                  - seconds
                                  - minutes
                                  - hours
                                  - days
                                type: string
                                description: Unit for `duration`.
                            required:
                              - type
                              - duration
                              - unit
                            description: >-
                              Pauses the flow for a fixed duration before
                              continuing.
                          - type: object
                            properties:
                              type:
                                const: branch
                                description: 'Step type: "branch".'
                              id:
                                type: string
                                minLength: 1
                                description: >-
                                  Stable id for this step. Omit to auto-generate
                                  one. Set it explicitly when a `goto` elsewhere
                                  needs to jump to this exact step.
                              cases:
                                type: array
                                minItems: 1
                                items:
                                  type: object
                                  properties:
                                    match:
                                      enum:
                                        - and
                                        - or
                                      type: string
                                      default: and
                                      description: >-
                                        Whether every ('and') or any ('or')
                                        condition in `when` must match.
                                    when:
                                      type: array
                                      minItems: 1
                                      items:
                                        type: object
                                        properties:
                                          field: {}
                                          operator: {}
                                          value: {}
                                        description: >-
                                          One contact-filter-style condition for a
                                          branch case.
                                      description: >-
                                        Conditions evaluated to determine
                                        whether this case matches.
                                    then:
                                      type: array
                                      minItems: 1
                                      items:
                                        anyOf:
                                          - {}
                                          - {}
                                          - {}
                                          - {}
                                          - {}
                                          - {}
                                          - {}
                                          - {}
                                      description: Steps to run when this case matches.
                                  required:
                                    - when
                                    - then
                                  description: One ordered case in a branch step.
                                description: Ordered cases evaluated until one matches.
                              otherwise:
                                type: array
                                items:
                                  anyOf:
                                    - type: object
                                      properties:
                                        type:
                                          const: send
                                          description: 'Step type: "send".'
                                        id:
                                          type: string
                                          minLength: 1
                                          description: >-
                                            Stable id for this step. Omit to
                                            auto-generate one. Set it explicitly
                                            when a `goto` elsewhere needs to jump to
                                            this exact step.
                                        text:
                                          type: string
                                          minLength: 1
                                          maxLength: 1000
                                          description: >-
                                            Text message body (max 1000 characters).
                                            Exactly one of text/imageUrl/fileUrl is
                                            required.
                                        imageUrl:
                                          type: string
                                          format: uri
                                          description: >-
                                            Image URL to send. Exactly one of
                                            text/imageUrl/fileUrl is required.
                                        fileUrl:
                                          type: string
                                          format: uri
                                          description: >-
                                            File URL to send. Exactly one of
                                            text/imageUrl/fileUrl is required.
                                        buttons:
                                          type: array
                                          maxItems: 3
                                          items: {}
                                          description: >-
                                            Up to 3 quick-reply buttons attached to
                                            this message.
                                      required:
                                        - type
                                      description: >-
                                        Sends one message (text, image, or
                                        file), optionally with quick-reply
                                        buttons.
                                    - type: object
                                      properties:
                                        type:
                                          const: sendTemplate
                                          description: 'Step type: "sendTemplate".'
                                        id:
                                          type: string
                                          minLength: 1
                                          description: >-
                                            Stable id for this step. Omit to
                                            auto-generate one. Set it explicitly
                                            when a `goto` elsewhere needs to jump to
                                            this exact step.
                                        templateName:
                                          type: string
                                          minLength: 1
                                          description: >-
                                            Name of an existing WhatsApp message
                                            template whose status is `APPROVED` (see
                                            `capabilities.get`'s `templates` list).
                                            Sent as-is, without dynamic variables.
                                      required:
                                        - type
                                        - templateName
                                      description: >-
                                        Sends an existing WhatsApp message
                                        template.
                                    - type: object
                                      properties:
                                        type:
                                          const: wait
                                          description: 'Step type: "wait".'
                                        id:
                                          type: string
                                          minLength: 1
                                          description: >-
                                            Stable id for this step. Omit to
                                            auto-generate one. Set it explicitly
                                            when a `goto` elsewhere needs to jump to
                                            this exact step.
                                        duration:
                                          type: integer
                                          minimum: -9007199254740991
                                          maximum: 9007199254740991
                                          exclusiveMinimum: 0
                                          description: How long to wait, in `unit`s.
                                        unit:
                                          enum:
                                            - seconds
                                            - minutes
                                            - hours
                                            - days
                                          type: string
                                          description: Unit for `duration`.
                                      required:
                                        - type
                                        - duration
                                        - unit
                                      description: >-
                                        Pauses the flow for a fixed duration
                                        before continuing.
                                    - type: object
                                      properties:
                                        type:
                                          const: branch
                                          description: 'Step type: "branch".'
                                        id:
                                          type: string
                                          minLength: 1
                                          description: >-
                                            Stable id for this step. Omit to
                                            auto-generate one. Set it explicitly
                                            when a `goto` elsewhere needs to jump to
                                            this exact step.
                                        cases:
                                          type: array
                                          minItems: 1
                                          items: {}
                                          description: >-
                                            Ordered cases evaluated until one
                                            matches.
                                        otherwise:
                                          type: array
                                          items: {}
                                          description: Steps to run when no case matches.
                                      required:
                                        - type
                                        - cases
                                      description: >-
                                        Splits the flow by contact-filter-style
                                        conditions. Terminal within its step
                                        list — nothing may follow a `branch` at
                                        the same level; continue inside
                                        `cases[].then` / `otherwise` instead.
                                    - type: object
                                      properties:
                                        type:
                                          const: action
                                          description: 'Step type: "action".'
                                        id:
                                          type: string
                                          minLength: 1
                                          description: >-
                                            Stable id for this step. Omit to
                                            auto-generate one. Set it explicitly
                                            when a `goto` elsewhere needs to jump to
                                            this exact step.
                                        action:
                                          enum:
                                            - addTags
                                            - removeTags
                                            - setCustomField
                                            - assignConversation
                                            - archiveConversation
                                          type: string
                                          description: Which workspace action to perform.
                                        tagNames:
                                          type: array
                                          items: {}
                                          description: >-
                                            Tag names. Required for
                                            `addTags`/`removeTags`.
                                        customFieldName:
                                          type: string
                                          minLength: 1
                                          description: >-
                                            Custom field name. Required for
                                            `setCustomField`.
                                        value:
                                          type: string
                                          description: >-
                                            Value to set. Required for
                                            `setCustomField`.
                                        assigneeId:
                                          type: string
                                          description: >-
                                            Workspace member id to assign the
                                            conversation to. Optional for
                                            `assignConversation`; omit to unassign.
                                      required:
                                        - type
                                        - action
                                      description: >-
                                        Performs a workspace side-effect: tag,
                                        custom field, or conversation action.
                                    - type: object
                                      properties:
                                        type:
                                          const: startFlow
                                          description: 'Step type: "startFlow".'
                                        id:
                                          type: string
                                          minLength: 1
                                          description: >-
                                            Stable id for this step. Omit to
                                            auto-generate one. Set it explicitly
                                            when a `goto` elsewhere needs to jump to
                                            this exact step.
                                        flowName:
                                          type: string
                                          minLength: 1
                                          description: >-
                                            Name of another existing flow in this
                                            workspace (see `flows.list`).
                                      required:
                                        - type
                                        - flowName
                                      description: >-
                                        Starts another flow for the contact;
                                        this flow keeps running afterward (an
                                        ordinary step may follow).
                                    - type: object
                                      properties:
                                        type:
                                          const: addNote
                                          description: 'Step type: "addNote".'
                                        id:
                                          type: string
                                          minLength: 1
                                          description: >-
                                            Stable id for this step. Omit to
                                            auto-generate one. Set it explicitly
                                            when a `goto` elsewhere needs to jump to
                                            this exact step.
                                        note:
                                          type: string
                                          minLength: 1
                                          maxLength: 1000
                                          description: >-
                                            Internal note text (max 1000 characters)
                                            — never shown to the contact.
                                      required:
                                        - type
                                        - note
                                      description: >-
                                        Adds an internal note to the
                                        conversation.
                                    - type: object
                                      properties:
                                        type:
                                          const: goto
                                          description: 'Step type: "goto".'
                                        targetId:
                                          type: string
                                          minLength: 1
                                          description: >-
                                            The `id` of an earlier step in this flow
                                            spec to jump to, instead of continuing
                                            linearly.
                                      required:
                                        - type
                                        - targetId
                                      description: >-
                                        Terminal — routes to an already-defined
                                        step instead of continuing. Must be the
                                        last step in its list.
                                description: Steps to run when no case matches.
                            required:
                              - type
                              - cases
                            description: >-
                              Splits the flow by contact-filter-style
                              conditions. Terminal within its step list —
                              nothing may follow a `branch` at the same level;
                              continue inside `cases[].then` / `otherwise`
                              instead.
                          - type: object
                            properties:
                              type:
                                const: action
                                description: 'Step type: "action".'
                              id:
                                type: string
                                minLength: 1
                                description: >-
                                  Stable id for this step. Omit to auto-generate
                                  one. Set it explicitly when a `goto` elsewhere
                                  needs to jump to this exact step.
                              action:
                                enum:
                                  - addTags
                                  - removeTags
                                  - setCustomField
                                  - assignConversation
                                  - archiveConversation
                                type: string
                                description: Which workspace action to perform.
                              tagNames:
                                type: array
                                items:
                                  type: string
                                  minLength: 1
                                description: >-
                                  Tag names. Required for
                                  `addTags`/`removeTags`.
                              customFieldName:
                                type: string
                                minLength: 1
                                description: >-
                                  Custom field name. Required for
                                  `setCustomField`.
                              value:
                                type: string
                                description: Value to set. Required for `setCustomField`.
                              assigneeId:
                                type: string
                                description: >-
                                  Workspace member id to assign the conversation
                                  to. Optional for `assignConversation`; omit to
                                  unassign.
                            required:
                              - type
                              - action
                            description: >-
                              Performs a workspace side-effect: tag, custom
                              field, or conversation action.
                          - type: object
                            properties:
                              type:
                                const: startFlow
                                description: 'Step type: "startFlow".'
                              id:
                                type: string
                                minLength: 1
                                description: >-
                                  Stable id for this step. Omit to auto-generate
                                  one. Set it explicitly when a `goto` elsewhere
                                  needs to jump to this exact step.
                              flowName:
                                type: string
                                minLength: 1
                                description: >-
                                  Name of another existing flow in this
                                  workspace (see `flows.list`).
                            required:
                              - type
                              - flowName
                            description: >-
                              Starts another flow for the contact; this flow
                              keeps running afterward (an ordinary step may
                              follow).
                          - type: object
                            properties:
                              type:
                                const: addNote
                                description: 'Step type: "addNote".'
                              id:
                                type: string
                                minLength: 1
                                description: >-
                                  Stable id for this step. Omit to auto-generate
                                  one. Set it explicitly when a `goto` elsewhere
                                  needs to jump to this exact step.
                              note:
                                type: string
                                minLength: 1
                                maxLength: 1000
                                description: >-
                                  Internal note text (max 1000 characters) —
                                  never shown to the contact.
                            required:
                              - type
                              - note
                            description: Adds an internal note to the conversation.
                          - type: object
                            properties:
                              type:
                                const: goto
                                description: 'Step type: "goto".'
                              targetId:
                                type: string
                                minLength: 1
                                description: >-
                                  The `id` of an earlier step in this flow spec
                                  to jump to, instead of continuing linearly.
                            required:
                              - type
                              - targetId
                            description: >-
                              Terminal — routes to an already-defined step
                              instead of continuing. Must be the last step in
                              its list.
                      description: Ordered steps executed from the flow's start node.
                  required:
                    - formatVersion
                    - name
                    - steps
                  description: A complete agent-authored flow DSL document.
                nodes:
                  type: array
                  items: {}
                  description: Raw flow node graph, as sent by the builder UI.
                edges:
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        type: string
                      source:
                        type: string
                      sourceHandle:
                        type: string
                      target:
                        type: string
                      targetHandle:
                        type: string
                    required:
                      - id
                      - source
                      - sourceHandle
                      - target
                      - targetHandle
                  description: Raw flow edge graph, as sent by the builder UI.
      responses:
        '204':
          description: OK
          content:
            application/json:
              schema:
                anyOf:
                  - {}
                  - not: {}
        '400':
          description: '400'
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    properties:
                      defined:
                        const: true
                      code:
                        const: businessError
                      status:
                        const: 400
                      message:
                        type: string
                        default: An error occurred while processing your request
                      data: {}
                    required:
                      - defined
                      - code
                      - status
                      - message
                  - $ref: '#/components/schemas/UndefinedError'
        '401':
          description: '401'
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    properties:
                      defined:
                        const: true
                      code:
                        const: UNAUTHORIZED
                      status:
                        const: 401
                      message:
                        type: string
                        default: Authentication required
                      data: {}
                    required:
                      - defined
                      - code
                      - status
                      - message
                  - type: object
                    properties:
                      defined:
                        const: true
                      code:
                        const: INVALID_CHATBOT_TOKEN
                      status:
                        const: 401
                      message:
                        type: string
                        default: Invalid or missing workspace API token
                      data: {}
                    required:
                      - defined
                      - code
                      - status
                      - message
                  - $ref: '#/components/schemas/UndefinedError'
        '403':
          description: '403'
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    properties:
                      defined:
                        const: true
                      code:
                        const: FORBIDDEN
                      status:
                        const: 403
                      message:
                        type: string
                        default: You do not have permission to perform this action
                      data: {}
                    required:
                      - defined
                      - code
                      - status
                      - message
                  - type: object
                    properties:
                      defined:
                        const: true
                      code:
                        const: trialExpired
                      status:
                        const: 403
                      message:
                        type: string
                        default: Trial expired
                      data: {}
                    required:
                      - defined
                      - code
                      - status
                      - message
                  - type: object
                    properties:
                      defined:
                        const: true
                      code:
                        const: macLimitReached
                      status:
                        const: 403
                      message:
                        type: string
                        default: Monthly active contact limit reached
                      data: {}
                    required:
                      - defined
                      - code
                      - status
                      - message
                  - $ref: '#/components/schemas/UndefinedError'
        '404':
          description: '404'
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    properties:
                      defined:
                        const: true
                      code:
                        const: notFound
                      status:
                        const: 404
                      message:
                        type: string
                        default: Resource not found
                      data: {}
                    required:
                      - defined
                      - code
                      - status
                      - message
                  - $ref: '#/components/schemas/UndefinedError'
        '422':
          description: '422'
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    properties:
                      defined:
                        const: true
                      code:
                        const: invalidRequestData
                      status:
                        const: 422
                      message:
                        type: string
                        default: Input validation failed
                      data:
                        type: object
                        properties:
                          issues:
                            type: array
                            items:
                              type: object
                              properties:
                                message:
                                  type: string
                                path:
                                  type: array
                                  items:
                                    anyOf:
                                      - type: string
                                      - type: number
                                      - type: object
                                        properties:
                                          key:
                                            anyOf:
                                              - type: string
                                              - type: number
                                        required:
                                          - key
                                        additionalProperties: {}
                              required:
                                - message
                              additionalProperties: {}
                        required:
                          - issues
                        additionalProperties: {}
                    required:
                      - defined
                      - code
                      - status
                      - message
                      - data
                  - type: object
                    properties:
                      defined:
                        const: true
                      code:
                        const: validation
                      status:
                        const: 422
                      message:
                        type: string
                        default: Validation error
                      data: {}
                    required:
                      - defined
                      - code
                      - status
                      - message
                  - $ref: '#/components/schemas/UndefinedError'
        '429':
          description: '429'
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    properties:
                      defined:
                        const: true
                      code:
                        const: tooManyRequests
                      status:
                        const: 429
                      message:
                        type: string
                        default: Too many requests
                      data: {}
                    required:
                      - defined
                      - code
                      - status
                      - message
                  - $ref: '#/components/schemas/UndefinedError'
        '500':
          description: '500'
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    properties:
                      defined:
                        const: true
                      code:
                        const: INTERNAL_SERVER_ERROR
                      status:
                        const: 500
                      message:
                        type: string
                        default: An unexpected error occurred
                      data: {}
                    required:
                      - defined
                      - code
                      - status
                      - message
                  - $ref: '#/components/schemas/UndefinedError'
components:
  schemas:
    UndefinedError:
      type: object
      properties:
        defined:
          const: false
        code:
          type: string
        status:
          type: number
        message:
          type: string
        data: {}
      required:
        - defined
        - code
        - status
        - message
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
    developerAccessToken:
      type: http
      scheme: bearer
    tokenInSearchParams:
      type: apiKey
      in: query
      name: token

````