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

# Add node

> Add one node to a draft journey. Positions are optional (auto-laid-out). Wire it up separately with journeys_connect_nodes.



## OpenAPI

````yaml /api-reference/openapi.json post /api/v1/journeys/{journeyId}/nodes
openapi: 3.1.0
info:
  title: Boom API
  version: 1.0.0
  description: >-
    Boom's public REST API — one uniform surface over every platform capability.
    CDP: upsert people and custom objects, define object and relationship types,
    link and unlink relationships, and record behavioral events — one record per
    request or up to 1000 per request via the `/batch` endpoints. Segments: read
    (list, read, membership) and full authoring — discover the filterable
    catalog, validate a filter, create and update segments, preview match
    counts, and trigger evaluation. Initiatives: create and configure outreach
    initiatives, link WhatsApp templates, drive the lifecycle (launch, cancel,
    archive), and read collected-data summaries. Participants: enroll people
    into an active initiative, track their status, read conversation
    transcripts, and stop outreach. Journeys: read-only access to always-on
    message flows and their metrics. WhatsApp templates: list your WhatsApp
    numbers and list, read, and create message templates. The same capabilities
    are exposed as MCP tools with identical schemas.
servers:
  - url: https://www.useboom.ai
    description: Production
  - url: https://dev.useboom.ai
    description: Development (sandbox — use a development organization API key)
security:
  - bearerAuth: []
paths:
  /api/v1/journeys/{journeyId}/nodes:
    post:
      tags:
        - Journeys
      summary: Add node
      description: >-
        Add one node to a draft journey. Positions are optional (auto-laid-out).
        Wire it up separately with journeys_connect_nodes.
      operationId: journeys_add_node
      parameters:
        - name: journeyId
          in: path
          required: true
          schema:
            $schema: https://json-schema.org/draft/2020-12/schema
            type: string
            minLength: 1
            description: >-
              A draft journey id, or the initiative id (resolves to its current
              draft).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $schema: https://json-schema.org/draft/2020-12/schema
              type: object
              properties:
                node:
                  description: >-
                    The whole node object ({"kind": …, "id": …, …}), nested
                    under this key — never its fields at the top level.
                  oneOf:
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: ENTRY
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            description:
                              type: string
                            triggerType:
                              description: >-
                                How people enter: manual (added by an operator
                                or API call), segment (on entering a segment),
                                cdp_event (when an event is received), or
                                inbound (when a message arrives on one of the
                                org's channels). Defaults to manual.
                              type: string
                              enum:
                                - manual
                                - segment
                                - cdp_event
                                - inbound
                            segmentId:
                              description: >-
                                Segment id — required when triggerType is
                                segment.
                              type: string
                            segmentName:
                              description: Cached segment display name (optional).
                              type: string
                            eventName:
                              description: >-
                                CDP event name — required when triggerType is
                                cdp_event.
                              type: string
                            inboundAction:
                              description: >-
                                Which arrival fires the trigger — required when
                                triggerType is inbound. INSTAGRAM_COMMENT /
                                FACEBOOK_COMMENT listen to public comments on
                                the account's posts instead of DMs; they require
                                Instagram or Messenger channels whose connection
                                was granted comment permission, and enroll the
                                commenter without opening a conversation.
                              type: string
                              enum:
                                - WHATSAPP_MESSAGE
                                - SMS_MESSAGE
                                - INSTAGRAM_MESSAGE
                                - MESSENGER_MESSAGE
                                - INSTAGRAM_COMMENT
                                - FACEBOOK_COMMENT
                            inboundChannelIds:
                              description: >-
                                Channel ids to listen on — at least one required
                                when triggerType is inbound. Must be NATIVE
                                WhatsApp, SMS, Instagram or Messenger channels
                                that are not deleted — WhatsApp and SMS
                                additionally need an ONLINE sender, Instagram
                                and Messenger have no sender row and need none
                                (a Messenger Page still on the V1 bridge is
                                withheld as NOT_NATIVE); journeys_set_trigger
                                names the eligible ids if you pass an ineligible
                                one. For a comment action, only Instagram and
                                Messenger channels are valid. Several published
                                journeys may share one channel as long as their
                                keywords differ: publishing a rule whose keyword
                                (or blank catch-all) is already taken on that
                                channel is refused with INBOUND_CHANNEL_TAKEN.
                                Each arriving message enrols exactly one of
                                them, the most specific matching rule, ties
                                going to the older initiative.
                              type: array
                              items:
                                type: string
                            inboundKeyword:
                              description: >-
                                The word the inbound message must match for this
                                journey to enrol — e.g. 'PRECIO'. Blank or
                                absent means the trigger is the catch-all and
                                fires on ANY message arriving on the channel,
                                which is almost never what you want beside other
                                journeys on the same number. Several journeys
                                may share one channel as long as their keywords
                                differ — two rules with the same keyword on one
                                channel, or two blank ones, are refused at
                                publish with INBOUND_CHANNEL_TAKEN. The keyword
                                is matched accent-, case- and
                                punctuation-insensitively, and stored
                                normalized.
                              type: string
                            inboundMatchMode:
                              description: >-
                                How inboundKeyword is matched: EXACT (the
                                message is only-the-word), ALL_WORDS (the
                                message contains all-the-words, in any order),
                                or CONTAINS (the message contains-the-word,
                                adjacent and in order). All three are
                                word-based, so no mode ever matches inside a
                                longer word ('precioso' does not match
                                'precio'). Defaults to EXACT. Ignored when
                                inboundKeyword is blank.
                              type: string
                              enum:
                                - EXACT
                                - CONTAINS
                                - ALL_WORDS
                            maxEnrollments:
                              description: >-
                                Frequency cap: max enrollments per person within
                                enrollmentWindow. Both-or-neither with
                                enrollmentWindow.
                              type: integer
                              minimum: 1
                              maximum: 9007199254740991
                            enrollmentWindow:
                              description: Rolling window for the frequency cap.
                              type: string
                            parallelRunsBy:
                              description: >-
                                Let one person have several runs of this journey
                                at the same time, one per distinct value of this
                                event property (e.g. "paymentLinkId"). Use it
                                when a person can have several of the same thing
                                in flight, two payment links or two orders, and
                                each needs its own sequence. Three things to
                                know. It works on cdp_event triggers only,
                                because the run is identified by a property of
                                the triggering event; an event that does not
                                carry the property is refused rather than
                                enrolled. The journey becomes SEND ONLY: no
                                wait-for-reply, conversation or AI nodes,
                                because an inbound message belongs to the person
                                and not to one run, so a single reply would wake
                                every run at once. And every stop event listed
                                in cancelOnEvents matches on this same property,
                                so a completed one stops only its own run and
                                leaves the person's other runs alive. Publish is
                                refused if any of that is violated.
                              type: string
                              minLength: 1
                          description: >-
                            Trigger node config. Exactly one ENTRY node per
                            journey.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: SEND_MESSAGE
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            mode:
                              description: >-
                                What this send carries: 'template' (an approved
                                WhatsApp template, the default when omitted) or
                                'free_text' (prose you write, needing `body`
                                instead of `templateId`). free_text emits SENT
                                and WINDOW_CLOSED, both of which must be wired —
                                Meta accepts free-form content only within 24
                                hours of the customer's last message, checked
                                before sending. Prefer this over the deprecated
                                SEND_WHATSAPP_TEXT node, which is the same send
                                under an older name.
                              type: string
                              enum:
                                - template
                                - free_text
                            templateId:
                              description: >-
                                Approved WhatsApp template id. Resolve ids from
                                the catalog.
                              type: string
                            templateName:
                              type: string
                            body:
                              description: >-
                                The message text, for mode 'free_text' only.
                                Placeholders are named, like {{customer.name}},
                                and EVERY one must have a matching entry in
                                `bindings` or publish is refused: an unbound
                                placeholder is sent literally, braces and all.
                                Bind an upstream HTTP response with
                                engagement.nodeOutputs.<nodeId>.body.<field>.
                              type: string
                            bindings:
                              description: >-
                                Map of {{placeholder}} name → variable
                                reference, for `body`. Template mode uses
                                `templateBindings` instead.
                              type: object
                              propertyNames:
                                type: string
                              additionalProperties:
                                type: string
                            channel:
                              description: >-
                                Always whatsapp. Other channels have their own
                                node kind — SEND_SMS for a text, SEND_INSTAGRAM
                                for Instagram, SEND_MESSENGER for Facebook
                                Messenger.
                              type: string
                              const: whatsapp
                            templateBindings:
                              description: >-
                                Map of template placeholder → variable
                                reference, or fixed text prefixed `literal:`
                                (e.g. `{ "2": "literal:BIENVENIDA20" }`) for a
                                value that is the same for every recipient.
                                EVERY placeholder the template declares (body,
                                header, footer, button URL) needs an entry or
                                publish is refused, since an unbound one is sent
                                literally. The only exception: a template whose
                                sole placeholder is {{1}}, with no map at all,
                                falls back to the customer name (not on a
                                Transactional).
                              type: object
                              propertyNames:
                                type: string
                              additionalProperties:
                                type: string
                            channelId:
                              description: >-
                                Sending WhatsApp channel (WABA) id. Required
                                before publishing.
                              type: string
                            sendImmediately:
                              description: >-
                                Deprecated business-hours gate; prefer a
                                preceding DELAY.
                              type: boolean
                            delivery:
                              description: >-
                                'draft' holds the rendered send in the Drafts
                                queue until an org member approves or rejects
                                it; the run waits at this node. Approve sends it
                                and continues on SENT; reject emits REJECTED
                                (optional edge — unwired, the run ends). Omit
                                for 'immediate'. Refused on a Transactional
                                initiative's journey
                                (`transactional_draft_delivery`): a notification
                                must go out. Refused (`drafts_disabled`) while
                                drafts are turned off for the organization; a
                                published drafted send reached while they're off
                                is skipped (SKIPPED), never sent unreviewed.
                              type: string
                              enum:
                                - immediate
                                - draft
                          description: >-
                            Sends WhatsApp: an approved template (default), or
                            free-text prose with mode 'free_text'.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: SEND_SMS
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            body:
                              description: >-
                                The message text. Free text — SMS has no
                                approved-template concept. Placeholders are
                                named, like {{customer.name}}, and EVERY one
                                must have a matching entry in `bindings` or
                                publish is refused: an unbound placeholder is
                                sent literally, braces and all. The opt-out
                                footer and the brand are added by the system; do
                                not write them into the body.
                              type: string
                            channelId:
                              description: >-
                                Sending SMS channel id. Required before
                                publishing.
                              type: string
                            bindings:
                              description: >-
                                Map of {{placeholder}} name → variable
                                reference. The builder writes the path as its
                                own name ({"customer.name": "customer.name"});
                                an alias is allowed as long as the body uses the
                                alias.
                              type: object
                              propertyNames:
                                type: string
                              additionalProperties:
                                type: string
                            optOutText:
                              description: >-
                                Opt-out line for this node, overriding the
                                organization's. Must contain the STOP keyword.
                                Omit to use the organization's.
                              type: string
                            allowEmoji:
                              description: >-
                                Keep emoji instead of stripping them. Defaults
                                to false, because emoji force UCS-2 encoding,
                                which cuts a message part from 160 characters to
                                70 and roughly doubles the cost.
                              type: boolean
                          description: Sends a plain-text SMS.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: SEND_WHATSAPP_TEXT
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            body:
                              description: >-
                                The message text. Free text — no Meta template
                                approval needed, which is the point of this
                                node. Placeholders are named, like
                                {{customer.name}}, and EVERY one must have a
                                matching entry in `bindings` or publish is
                                refused: an unbound placeholder is sent
                                literally, braces and all. Bind an upstream HTTP
                                response with
                                engagement.nodeOutputs.<nodeId>.body.<field>.
                              type: string
                            channelId:
                              description: >-
                                Sending WhatsApp channel (WABA) id. Required
                                before publishing; it is also the per-number
                                send throttle key.
                              type: string
                            bindings:
                              description: >-
                                Map of {{placeholder}} name → variable
                                reference. The builder writes the path as its
                                own name ({"customer.name": "customer.name"});
                                an alias is allowed as long as the body uses the
                                alias.
                              type: object
                              propertyNames:
                                type: string
                              additionalProperties:
                                type: string
                          description: >-
                            Sends free-text WhatsApp — author-written prose
                            instead of an approved template. Emits SENT or
                            WINDOW_CLOSED, and BOTH must be wired. Meta accepts
                            free-form content only within 24 hours of the
                            customer's last message; the node checks that BEFORE
                            sending (Twilio would accept an out-of-window
                            message and fail it asynchronously with 63016), so
                            WINDOW_CLOSED means nothing was sent and is where
                            you put an approved template. A node with no
                            upstream WAIT_FOR_REPLY / MANAGE_CONVERSATION will
                            usually take WINDOW_CLOSED — publish warns but does
                            not block, because a customer who wrote recently on
                            this number in ANY journey still has an open window.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: SEND_INSTAGRAM
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            body:
                              description: >-
                                The message text. Free text — Instagram has no
                                approved-template concept. Placeholders are
                                named, like {{customer.name}}, and EVERY one
                                must have a matching entry in `bindings` or
                                publish is refused: an unbound placeholder is
                                sent literally, braces and all.
                              type: string
                            channelId:
                              description: >-
                                Sending native Instagram channel id. Required
                                before publishing, with no org-primary fallback.
                              type: string
                            bindings:
                              description: >-
                                Map of {{placeholder}} name → variable
                                reference. The builder writes the path as its
                                own name ({"customer.name": "customer.name"});
                                an alias is allowed as long as the body uses the
                                alias.
                              type: object
                              propertyNames:
                                type: string
                              additionalProperties:
                                type: string
                          description: >-
                            Sends free-text Instagram from a chosen native
                            account — no template concept, so every message is
                            author-written prose. Emits SENT or WINDOW_CLOSED,
                            and BOTH must be wired. Meta accepts free-form
                            content only within 24 hours of the customer's last
                            message; the node checks that BEFORE sending, so
                            WINDOW_CLOSED means nothing was sent. Instagram has
                            no template fallback, so WINDOW_CLOSED usually leads
                            to EXIT — say so explicitly rather than leaving it
                            dangling. Exception: in a run an INSTAGRAM_COMMENT
                            trigger started, a shut window sends one private
                            reply to that comment instead (same account, comment
                            under 7 days old and not yet replied to); Meta
                            decides whether it lands.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: SEND_EMAIL
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            templateId:
                              description: >-
                                A PUBLISHED email template id from
                                journeys_email_templates. Required before
                                publishing; a draft or archived template is
                                refused at publish.
                              type: string
                            templateName:
                              description: >-
                                The template's name, cached so the canvas can
                                label the node without a lookup. Copy it from
                                journeys_email_templates.
                              type: string
                            bindings:
                              description: >-
                                Map of the template's variable key (its
                                `variables[].key` in journeys_email_templates) →
                                variable reference such as customer.name, or
                                engagement.chatLink for the link that opens this
                                run's web chat. Bind only what you want to
                                reroute: a variable left out resolves its own
                                `path`, as the template was authored.
                              type: object
                              propertyNames:
                                type: string
                              additionalProperties:
                                type: string
                            fromSenderIdOverride:
                              description: >-
                                Sender id to send From for this node only,
                                overriding the template's pick and the org
                                default. Must be a sender with usableAsFrom:
                                true in journeys_email_templates. Omit to
                                inherit.
                              type: string
                            replyToSenderIdOverride:
                              description: >-
                                Sender id to use as Reply-To for this node only.
                                Omit to inherit the template, then the org
                                default.
                              type: string
                            delivery:
                              description: >-
                                'draft' holds the rendered send in the Drafts
                                queue until an org member approves or rejects
                                it; the run waits at this node. Approve sends it
                                and continues on SENT; reject emits REJECTED
                                (optional edge — unwired, the run ends). Omit
                                for 'immediate'. Refused on a Transactional
                                initiative's journey
                                (`transactional_draft_delivery`): a notification
                                must go out. Refused (`drafts_disabled`) while
                                drafts are turned off for the organization; a
                                published drafted send reached while they're off
                                is skipped (SKIPPED), never sent unreviewed.
                              type: string
                              enum:
                                - immediate
                                - draft
                          description: Sends a PUBLISHED email template to the customer.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: SEND_MESSENGER
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            body:
                              description: >-
                                The message text, at most 2000 characters. Free
                                text — no approved-template concept.
                                Placeholders are named, like {{customer.name}},
                                and EVERY one must have a matching entry in
                                `bindings` or publish is refused: an unbound
                                placeholder is sent literally, braces and all.
                              type: string
                            channelId:
                              description: >-
                                Sending native Messenger channel (Facebook Page)
                                id, from journeys_message_channels (sendNodeKind
                                SEND_MESSENGER). Required before publishing,
                                with no org-primary fallback.
                              type: string
                            bindings:
                              description: >-
                                Map of {{placeholder}} name → variable
                                reference. The builder writes the path as its
                                own name ({"customer.name": "customer.name"});
                                an alias is allowed as long as the body uses the
                                alias.
                              type: object
                              propertyNames:
                                type: string
                              additionalProperties:
                                type: string
                          description: >-
                            Sends free-text Facebook Messenger from a chosen
                            Page — every message is author-written prose. Emits
                            SENT or WINDOW_CLOSED, and BOTH must be wired. Meta
                            accepts it only within 24 hours of the customer's
                            last message; the node checks that BEFORE sending,
                            so WINDOW_CLOSED means nothing was sent. There is no
                            template fallback, so WINDOW_CLOSED usually leads to
                            EXIT — say so explicitly rather than leaving it
                            dangling. Exception: in a run an FACEBOOK_COMMENT
                            trigger started, a shut window sends one private
                            reply to that comment instead (same Page, comment
                            under 7 days old and not yet replied to); Meta
                            decides whether it lands.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: CONVERSATION_BLOCK
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            goal:
                              type: string
                            maxTimeout:
                              description: How long to wait for a reply before timing out.
                              type: string
                            mode:
                              type: string
                              enum:
                                - AGENT
                                - ESCALATE
                            outputs:
                              type: array
                              items:
                                type: object
                                properties:
                                  id:
                                    type: string
                                  label:
                                    type: string
                                  type:
                                    type: string
                                    enum:
                                      - string
                                      - number
                                      - date
                                      - boolean
                                      - json
                                  description:
                                    type: string
                                  builtin:
                                    type: boolean
                                required:
                                  - id
                                  - label
                                  - type
                                  - builtin
                          description: Legacy combined wait + AI conversation block.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: WAIT_FOR_REPLY
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            maxTimeout:
                              description: >-
                                How long to wait for the first reply before
                                timing out.
                              type: string
                          description: Waits for the person to reply.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: MANAGE_CONVERSATION
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            mode:
                              description: >-
                                AGENT (AI-led) or ESCALATE (human handoff).
                                Defaults to AGENT.
                              type: string
                              enum:
                                - AGENT
                                - ESCALATE
                            goal:
                              description: >-
                                Instructions for this conversation step only, on
                                top of the initiative objective (e.g. 'Confirm
                                the delivery address before anything else').
                                AGENT mode only; ignored in ESCALATE.
                              type: string
                            inactivityTimeout:
                              description: >-
                                Optional custom idle window (e.g. '2h', '30m')
                                that overrides the global inactive-conversation
                                close. Resets on each inbound message; after
                                this much silence the node closes the
                                conversation (routes CLOSED), unless the AI has
                                escalated it to a human, in which case it stays
                                open. Hard cap 24h; under 30m is allowed but
                                flagged 'not recommended'. Requires the
                                journey-inactivity-timeout flag.
                              type: string
                          description: Runs the AI-led conversation.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: DISPATCH_EVENT
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            eventName:
                              type: string
                              minLength: 1
                              description: >-
                                CDP event name to record. Must match the CDP
                                name pattern.
                            properties:
                              description: >-
                                Literal string values, or { var: path } bindings
                                resolved to typed values at dispatch time.
                              type: object
                              propertyNames:
                                type: string
                              additionalProperties:
                                anyOf:
                                  - type: string
                                  - type: object
                                    properties:
                                      var:
                                        type: string
                                    required:
                                      - var
                            description:
                              type: string
                          required:
                            - eventName
                          description: Records a CDP event for the person.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: DELAY
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            mode:
                              description: How the wait is measured. Defaults to duration.
                              type: string
                              enum:
                                - duration
                                - until_date
                                - until_weekday
                            duration:
                              description: For mode duration.
                              type: string
                            targetAt:
                              description: ISO 8601 instant, for mode until_date.
                              type: string
                            weekdays:
                              description: >-
                                ISO weekdays 1=Mon..7=Sun, for mode
                                until_weekday.
                              type: array
                              items:
                                type: integer
                                minimum: 1
                                maximum: 7
                            windowStartMinutes:
                              type: integer
                              minimum: 0
                              maximum: 1439
                            windowEndMinutes:
                              type: integer
                              minimum: 0
                              maximum: 1439
                            timezone:
                              description: IANA timezone. Load-bearing for until_weekday.
                              type: string
                            description:
                              type: string
                          description: Pauses the run.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: DECISION
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            logic:
                              type: string
                              enum:
                                - AND
                                - OR
                            conditions:
                              type: array
                              items:
                                oneOf:
                                  - type: object
                                    properties:
                                      kind:
                                        type: string
                                        const: value
                                      selectionPath:
                                        type: string
                                        description: >-
                                          Dot-path into the run; must start with
                                          one of "engagement.workflowState.",
                                          "engagement.extracted.",
                                          "engagement.nodeOutputs.",
                                          "engagement.conversation." (e.g.
                                          engagement.workflowState.totalPrice).
                                          customer.*, person.*, attributes.* and
                                          engagement.context.* are NOT resolvable
                                          here. Unlike the other roots,
                                          "engagement.conversation." takes ONE OF
                                          a closed set of keys —
                                          hoursSinceLastInbound, lastInboundText,
                                          lastInboundKind, documentCount,
                                          newDocumentCount — and any other key is
                                          refused at publish rather than resolving
                                          blank. A single formatting helper may
                                          follow the path ("| currency:MXN", "|
                                          count"), including on
                                          engagement.conversation.*, whose key is
                                          checked with the helper stripped off.
                                      operator:
                                        type: string
                                        enum:
                                          - eq
                                          - neq
                                          - gt
                                          - lt
                                          - contains
                                          - matchesKeyword
                                          - isSet
                                        description: >-
                                          How to compare. `contains` is a plain
                                          substring test, so "precio" also matches
                                          "precioso". `matchesKeyword` is the
                                          ENTRY inbound-trigger matcher instead —
                                          accent- and case-folded, matched on word
                                          boundaries — so an author who writes the
                                          same word on a trigger and mid-journey
                                          gets the same answer. Use
                                          `matchesKeyword` to route by what the
                                          customer said; a value that folds to no
                                          letters or digits is refused at publish,
                                          because it would match every message.
                                          Must also suit the selected field: text
                                          tests (`contains`, `matchesKeyword`) are
                                          refused on a number, and ordering (`gt`,
                                          `lt`) on text — see
                                          DECISION_OPERATOR_TYPE_MISMATCH.
                                      value:
                                        type: string
                                    required:
                                      - kind
                                      - selectionPath
                                      - operator
                                      - value
                                  - type: object
                                    properties:
                                      kind:
                                        type: string
                                        const: event
                                      eventName:
                                        type: string
                                      subjectSelectionPath:
                                        type: string
                                        description: >-
                                          Dot-path into the run; must start with
                                          one of "engagement.workflowState.",
                                          "engagement.extracted.",
                                          "engagement.nodeOutputs.",
                                          "engagement.conversation." (e.g.
                                          engagement.workflowState.totalPrice).
                                          customer.*, person.*, attributes.* and
                                          engagement.context.* are NOT resolvable
                                          here. Unlike the other roots,
                                          "engagement.conversation." takes ONE OF
                                          a closed set of keys —
                                          hoursSinceLastInbound, lastInboundText,
                                          lastInboundKind, documentCount,
                                          newDocumentCount — and any other key is
                                          refused at publish rather than resolving
                                          blank. A single formatting helper may
                                          follow the path ("| currency:MXN", "|
                                          count"), including on
                                          engagement.conversation.*, whose key is
                                          checked with the helper stripped off.
                                      occurred:
                                        type: boolean
                                    required:
                                      - kind
                                      - eventName
                                      - subjectSelectionPath
                                      - occurred
                                  - type: object
                                    properties:
                                      kind:
                                        type: string
                                        const: cdp_predicate
                                      term:
                                        type: object
                                        properties:
                                          attr:
                                            type: string
                                            minLength: 1
                                            description: >-
                                              Typed person column, `attributes.<key>`,
                                              or `computed.<key>`. See
                                              journeys_condition_catalog for the
                                              available attributes.
                                          type:
                                            type: string
                                            enum:
                                              - STRING
                                              - NUMBER
                                              - BOOLEAN
                                              - DATE
                                              - JSON
                                              - ARRAY
                                            description: >-
                                              CDP attribute type. Determines which
                                              `op` values are legal — see
                                              journeys_condition_catalog.
                                          op:
                                            type: string
                                            minLength: 1
                                            description: >-
                                              Segments OperatorEnum value (eq | neq |
                                              gt | lt | in_last_n | ...). Must be
                                              legal for `type` — see
                                              journeys_condition_catalog.
                                          value:
                                            description: >-
                                              Shape depends on `op`: a plain scalar
                                              for eq/neq/gt/lt/starts_with/…, an array
                                              for in/not_in/contains/not_contains,
                                              {from, to} for between, {amount, unit}
                                              for
                                              in_last_n/in_next_n/more_than_n_ago/more_than_n_from_now,
                                              {minAmount, maxAmount, unit} for
                                              between_n_and_m_ago, {daysOffset} for
                                              exactly_n_from_today. Omit entirely for
                                              is_null/is_not_null.
                                            anyOf:
                                              - type: string
                                              - type: number
                                              - type: boolean
                                              - type: array
                                                items:
                                                  anyOf:
                                                    - type: string
                                                    - type: number
                                              - type: object
                                                properties:
                                                  from:
                                                    type: string
                                                  to:
                                                    type: string
                                                required:
                                                  - from
                                                  - to
                                              - type: object
                                                properties:
                                                  amount:
                                                    type: integer
                                                    minimum: 1
                                                    maximum: 9999
                                                  unit:
                                                    type: string
                                                    enum:
                                                      - days
                                                      - weeks
                                                      - months
                                                required:
                                                  - amount
                                                  - unit
                                              - type: object
                                                properties:
                                                  minAmount:
                                                    type: integer
                                                    minimum: 0
                                                    maximum: 9999
                                                  maxAmount:
                                                    type: integer
                                                    minimum: 1
                                                    maximum: 9999
                                                  unit:
                                                    type: string
                                                    enum:
                                                      - days
                                                      - weeks
                                                      - months
                                                required:
                                                  - minAmount
                                                  - maxAmount
                                                  - unit
                                              - type: object
                                                properties:
                                                  daysOffset:
                                                    type: integer
                                                    minimum: -9007199254740991
                                                    maximum: 9007199254740991
                                                  rollForward:
                                                    type: object
                                                    properties:
                                                      fromDow:
                                                        type: integer
                                                        minimum: 0
                                                        maximum: 6
                                                      includeDows:
                                                        minItems: 1
                                                        type: array
                                                        items:
                                                          type: integer
                                                          minimum: 0
                                                          maximum: 6
                                                    required:
                                                      - fromDow
                                                      - includeDows
                                                required:
                                                  - daysOffset
                                        required:
                                          - attr
                                          - type
                                          - op
                                        description: >-
                                          A single live person/computed predicate
                                          term. See journeys_condition_catalog for
                                          its shape and the legal operator/value
                                          pairing.
                                    required:
                                      - kind
                                      - term
                                  - type: object
                                    properties:
                                      kind:
                                        type: string
                                        const: cdp_object
                                      objectType:
                                        type: string
                                      matchAttr:
                                        type: string
                                      matchSelectionPath:
                                        type: string
                                        description: >-
                                          Dot-path into the run; must start with
                                          one of "engagement.workflowState.",
                                          "engagement.extracted.",
                                          "engagement.nodeOutputs.",
                                          "engagement.conversation." (e.g.
                                          engagement.workflowState.totalPrice).
                                          customer.*, person.*, attributes.* and
                                          engagement.context.* are NOT resolvable
                                          here. Unlike the other roots,
                                          "engagement.conversation." takes ONE OF
                                          a closed set of keys —
                                          hoursSinceLastInbound, lastInboundText,
                                          lastInboundKind, documentCount,
                                          newDocumentCount — and any other key is
                                          refused at publish rather than resolving
                                          blank. A single formatting helper may
                                          follow the path ("| currency:MXN", "|
                                          count"), including on
                                          engagement.conversation.*, whose key is
                                          checked with the helper stripped off.
                                      exists:
                                        type: boolean
                                    required:
                                      - kind
                                      - objectType
                                      - matchAttr
                                      - matchSelectionPath
                                      - exists
                                  - type: object
                                    properties:
                                      kind:
                                        type: string
                                        const: matched_object
                                      objectType:
                                        type: string
                                        minLength: 1
                                        description: >-
                                          Custom-object type whose matched rows
                                          (the rows that put this person in the
                                          entry segment,
                                          `workflowState.__matched.<type>`) are
                                          re-read LIVE. Segment-triggered journeys
                                          only; must be one of the segment's
                                          matched types.
                                      term:
                                        type: object
                                        properties:
                                          attr:
                                            type: string
                                            minLength: 1
                                            description: >-
                                              The BARE attribute key of the matched
                                              object type, exactly as in its attribute
                                              catalog (e.g. `order_status`). No
                                              `attributes.`, `object.` or `computed.`
                                              prefix. `type` must equal the catalogued
                                              type.
                                          type:
                                            type: string
                                            enum:
                                              - STRING
                                              - NUMBER
                                              - BOOLEAN
                                              - DATE
                                              - JSON
                                              - ARRAY
                                            description: >-
                                              CDP attribute type. Determines which
                                              `op` values are legal — see
                                              journeys_condition_catalog.
                                          op:
                                            type: string
                                            minLength: 1
                                            description: >-
                                              Segments OperatorEnum value (eq | neq |
                                              gt | lt | in_last_n | ...). Must be
                                              legal for `type` — see
                                              journeys_condition_catalog.
                                          value:
                                            description: >-
                                              Shape depends on `op`: a plain scalar
                                              for eq/neq/gt/lt/starts_with/…, an array
                                              for in/not_in/contains/not_contains,
                                              {from, to} for between, {amount, unit}
                                              for
                                              in_last_n/in_next_n/more_than_n_ago/more_than_n_from_now,
                                              {minAmount, maxAmount, unit} for
                                              between_n_and_m_ago, {daysOffset} for
                                              exactly_n_from_today. Omit entirely for
                                              is_null/is_not_null.
                                            anyOf:
                                              - type: string
                                              - type: number
                                              - type: boolean
                                              - type: array
                                                items:
                                                  anyOf:
                                                    - type: string
                                                    - type: number
                                              - type: object
                                                properties:
                                                  from:
                                                    type: string
                                                  to:
                                                    type: string
                                                required:
                                                  - from
                                                  - to
                                              - type: object
                                                properties:
                                                  amount:
                                                    type: integer
                                                    minimum: 1
                                                    maximum: 9999
                                                  unit:
                                                    type: string
                                                    enum:
                                                      - days
                                                      - weeks
                                                      - months
                                                required:
                                                  - amount
                                                  - unit
                                              - type: object
                                                properties:
                                                  minAmount:
                                                    type: integer
                                                    minimum: 0
                                                    maximum: 9999
                                                  maxAmount:
                                                    type: integer
                                                    minimum: 1
                                                    maximum: 9999
                                                  unit:
                                                    type: string
                                                    enum:
                                                      - days
                                                      - weeks
                                                      - months
                                                required:
                                                  - minAmount
                                                  - maxAmount
                                                  - unit
                                              - type: object
                                                properties:
                                                  daysOffset:
                                                    type: integer
                                                    minimum: -9007199254740991
                                                    maximum: 9007199254740991
                                                  rollForward:
                                                    type: object
                                                    properties:
                                                      fromDow:
                                                        type: integer
                                                        minimum: 0
                                                        maximum: 6
                                                      includeDows:
                                                        minItems: 1
                                                        type: array
                                                        items:
                                                          type: integer
                                                          minimum: 0
                                                          maximum: 6
                                                    required:
                                                      - fromDow
                                                      - includeDows
                                                required:
                                                  - daysOffset
                                        required:
                                          - attr
                                          - type
                                          - op
                                        description: >-
                                          Condition on the row's CURRENT
                                          attributes. `attr` is the bare object
                                          attribute key (e.g. `order_status`, not
                                          `object.attributes.order_status`);
                                          `type`/`op`/`value` follow the same
                                          rules as a cdp_predicate term.
                                      quantifier:
                                        type: string
                                        enum:
                                          - any
                                          - all
                                        description: >-
                                          `any`: YES when at least one matched row
                                          passes. `all`: YES only when every
                                          matched row still exists and passes. No
                                          matched rows on the run → false.
                                    required:
                                      - kind
                                      - objectType
                                      - term
                                      - quantifier
                                description: One decision condition.
                            description:
                              type: string
                          required:
                            - logic
                            - conditions
                          description: Two-way branch. Emits YES / NO.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: CASE
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            selectionPath:
                              type: string
                              description: >-
                                Value to switch on; must start with one of
                                "attributes.", "engagement.extracted.",
                                "engagement.nodeOutputs.", "matched." (e.g.
                                attributes.plan_tier). "matched.<type>.<attr>"
                                (e.g. matched.order.order_status) switches on
                                the CURRENT value of an attribute of the row
                                that put the person in the entry segment — the
                                first matched row of that type, read live;
                                segment-triggered journeys only, and the type
                                must be in the segment's matched types. A
                                formatting helper ("| currency:MXN", "| count")
                                is REFUSED here, unlike on a DECISION condition:
                                CASE reads this path raw, so a helper would
                                resolve blank and route case:default on every
                                run.
                            branches:
                              type: array
                              items:
                                type: object
                                properties:
                                  id:
                                    type: string
                                    description: >-
                                      Stable branch id; edge handle is
                                      case:<id>.
                                  value:
                                    type: string
                                    description: Value matched. Unique within the node.
                                  label:
                                    type: string
                                    minLength: 1
                                    description: >-
                                      Required. Names the variant in analytics
                                      and on canvas.
                                required:
                                  - id
                                  - value
                                  - label
                              description: >-
                                Up to 10 branches. A case:default handle is
                                always required.
                            description:
                              type: string
                          required:
                            - selectionPath
                            - branches
                          description: N-way switch on a person attribute.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: RANDOM_SPLIT
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            arms:
                              type: array
                              items:
                                type: object
                                properties:
                                  id:
                                    type: string
                                    description: Stable arm id; edge handle is split:<id>.
                                  weight:
                                    type: integer
                                    minimum: 1
                                    maximum: 100
                                    description: >-
                                      Integer percentage. A node's arms must
                                      total 100.
                                  label:
                                    type: string
                                required:
                                  - id
                                  - weight
                              description: >-
                                At least 2 and at most 10 arms whose weights
                                total exactly 100. There is no default handle —
                                every roll lands on a declared arm.
                            description:
                              type: string
                          required:
                            - arms
                          description: >-
                            Randomly routes each run down one of N weighted
                            arms.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: HTTP_REQUEST
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            method:
                              type: string
                              enum:
                                - GET
                                - POST
                                - PUT
                                - PATCH
                                - DELETE
                              description: HTTP method.
                            url:
                              type: string
                              minLength: 1
                              description: >-
                                Target URL. Supports {{variable}} placeholders.
                                Resolvable roots here: customer.<field> (a
                                single flat field of the customer record),
                                person.<attribute> (CDP), env.<key> (journey
                                environment), engagement.context.*,
                                engagement.workflowState.*,
                                engagement.extracted.*,
                                engagement.nodeOutputs.<nodeId>.*,
                                engagement.documents (json body, whole quoted
                                token, flag-gated), and
                                engagement.conversation.id /
                                engagement.conversation.inboxUrl — the
                                conversation this run is talking to and its
                                Shared Inbox deep link. Anything else
                                substitutes as an empty string and is reported
                                at publish as UNRESOLVABLE_HTTP_TOKEN. Note
                                engagement.chatLink is SEND_EMAIL-only and does
                                NOT resolve here.
                            headers:
                              description: >-
                                Request headers as key/value pairs. Values
                                support the same {{variable}} placeholders as
                                the url. Resolvable roots here: customer.<field>
                                (a single flat field of the customer record),
                                person.<attribute> (CDP), env.<key> (journey
                                environment), engagement.context.*,
                                engagement.workflowState.*,
                                engagement.extracted.*,
                                engagement.nodeOutputs.<nodeId>.*,
                                engagement.documents (json body, whole quoted
                                token, flag-gated), and
                                engagement.conversation.id /
                                engagement.conversation.inboxUrl — the
                                conversation this run is talking to and its
                                Shared Inbox deep link. Anything else
                                substitutes as an empty string and is reported
                                at publish as UNRESOLVABLE_HTTP_TOKEN. Note
                                engagement.chatLink is SEND_EMAIL-only and does
                                NOT resolve here.
                              type: array
                              items:
                                type: object
                                properties:
                                  key:
                                    type: string
                                  value:
                                    type: string
                                required:
                                  - key
                                  - value
                            body:
                              description: >-
                                Request body. mode none sends no body. Supports
                                the same {{variable}} placeholders as the url;
                                in json mode a whole quoted token
                                ("{{engagement.documents}}") substitutes as a
                                JSON array. Resolvable roots here:
                                customer.<field> (a single flat field of the
                                customer record), person.<attribute> (CDP),
                                env.<key> (journey environment),
                                engagement.context.*,
                                engagement.workflowState.*,
                                engagement.extracted.*,
                                engagement.nodeOutputs.<nodeId>.*,
                                engagement.documents (json body, whole quoted
                                token, flag-gated), and
                                engagement.conversation.id /
                                engagement.conversation.inboxUrl — the
                                conversation this run is talking to and its
                                Shared Inbox deep link. Anything else
                                substitutes as an empty string and is reported
                                at publish as UNRESOLVABLE_HTTP_TOKEN. Note
                                engagement.chatLink is SEND_EMAIL-only and does
                                NOT resolve here.
                              type: object
                              properties:
                                mode:
                                  type: string
                                  enum:
                                    - none
                                    - json
                                    - raw
                                content:
                                  type: string
                                contentType:
                                  type: string
                              required:
                                - mode
                            credentialId:
                              description: >-
                                Deprecated/legacy: HttpCredential row id used to
                                authenticate the request. Prefer credentialKey.
                              type: string
                            credentialKey:
                              description: >-
                                Logical credential key; the pinned environment
                                selects the secret.
                              type: string
                            timeoutMs:
                              description: >-
                                Request timeout in milliseconds. Max 30000
                                (30s).
                              type: integer
                              exclusiveMinimum: 0
                              maximum: 30000
                            maxAttempts:
                              description: Max attempts including the first. Max 5.
                              type: integer
                              exclusiveMinimum: 0
                              maximum: 5
                            documentUrlTtlSeconds:
                              description: >-
                                TTL (seconds, ≤86400) for presigned
                                engagement.documents URLs this node emits.
                                Default 86400.
                              type: integer
                              exclusiveMinimum: 0
                              maximum: 86400
                            documentMimeTypes:
                              description: >-
                                Allowlist of MIME types this node may egress in
                                engagement.documents, e.g. ['application/pdf']
                                for an endpoint that only accepts PDFs. Omit (or
                                pass an empty list) to send every document type
                                — the default. A document whose type is not
                                listed is withheld and counted in the step's
                                documents.filteredCount, never silently dropped.
                                Match is exact, trimmed and case-insensitive; a
                                document with no recorded type is withheld
                                whenever a list is set. Each entry must be a
                                MIME type an inbound document can actually have,
                                because a well-formed typo would match nothing
                                and withhold everything: image/jpeg, image/png,
                                image/webp, image/gif, application/pdf,
                                video/mp4, text/vcard, text/html,
                                application/msword, application/vnd.ms-excel,
                                application/vnd.openxmlformats-officedocument.wordprocessingml.document,
                                application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,
                                application/octet-stream.
                              type: array
                              items:
                                type: string
                                minLength: 1
                          required:
                            - method
                            - url
                          description: >-
                            Calls an external HTTP endpoint. Emits SUCCESS or
                            FAILED.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: ROUTE_TO_INITIATIVE
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            initiativeId:
                              type: string
                              minLength: 1
                              description: >-
                                Target initiative id to enroll this customer
                                into.
                            context:
                              description: >-
                                Values stamped onto the new engagement, readable
                                by its agent. A literal string, or { var:
                                'engagement.extracted.<slug>' } resolved at
                                route time.
                              type: object
                              propertyNames:
                                type: string
                              additionalProperties:
                                anyOf:
                                  - type: string
                                  - type: object
                                    properties:
                                      var:
                                        type: string
                                    required:
                                      - var
                            description:
                              type: string
                          required:
                            - initiativeId
                          description: >-
                            Terminal. Ends this engagement and enrolls the
                            customer into another initiative, moving the live
                            conversation onto a new session. Emits no signals —
                            it has no outgoing edges.
                      required:
                        - id
                        - kind
                    - type: object
                      properties:
                        id:
                          type: string
                          minLength: 1
                          description: Node id, unique within the journey.
                        kind:
                          type: string
                          const: EXIT
                        name:
                          type: string
                          minLength: 1
                          description: >-
                            The label shown on the canvas. Required before
                            publishing.
                        position:
                          type: object
                          properties:
                            x:
                              type: number
                            'y':
                              type: number
                          required:
                            - x
                            - 'y'
                          description: >-
                            Explicit canvas position. Omit it and the server
                            auto-lays-out the graph top-down; only set it to
                            preserve a hand-arranged layout.
                        inputs:
                          type: object
                          properties:
                            outcome:
                              type: string
                          description: Terminal node.
                      required:
                        - id
                        - kind
              required:
                - node
      responses:
        '201':
          description: Success
          content:
            application/json:
              schema:
                $schema: https://json-schema.org/draft/2020-12/schema
                type: object
                properties:
                  id:
                    type: string
                    description: Journey (workflow version) id.
                  initiativeId:
                    type: string
                    description: The initiative this journey belongs to.
                  status:
                    type: string
                    enum:
                      - DRAFT
                      - PUBLISHED
                      - STOPPED
                    description: >-
                      DRAFT (editable), PUBLISHED (live, frozen), or STOPPED
                      (retired).
                  version:
                    type: integer
                    minimum: -9007199254740991
                    maximum: 9007199254740991
                    description: Version number within the initiative.
                  definition:
                    type: object
                    properties:
                      id:
                        description: >-
                          Journey id; carried for round-trip ergonomics.
                          Optional on create.
                        type: string
                      name:
                        type: string
                        minLength: 1
                        description: Journey name.
                      metadata:
                        type: object
                        properties:
                          initiativeType:
                            type: string
                          version:
                            type: integer
                            minimum: -9007199254740991
                            maximum: 9007199254740991
                          cancelOnEvents:
                            description: >-
                              Cancel an in-flight run when any of these events
                              arrive.
                            type: object
                            properties:
                              eventNames:
                                type: array
                                items:
                                  type: string
                              matchRunKey:
                                description: >-
                                  Cancel only the run whose key equals this
                                  event's `parallelRunsBy` property, instead of
                                  every run the person has. Leave it unset on a
                                  journey with several runs at once: that
                                  already matches on the key, and setting it to
                                  false there is refused at publish, because one
                                  completed payment would stop the person's
                                  other payments too.
                                type: boolean
                            required:
                              - eventNames
                            additionalProperties: false
                          environmentId:
                            description: >-
                              Pinned environment whose non-secret {{env.*}}
                              values HTTP nodes resolve against. Frozen at
                              publish. The server preserves the stored value
                              when a whole-graph update omits it.
                            type: string
                        additionalProperties: false
                        description: Optional journey-level metadata.
                      actions:
                        minItems: 1
                        type: array
                        items:
                          oneOf:
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: ENTRY
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    description:
                                      type: string
                                    triggerType:
                                      description: >-
                                        How people enter: manual (added by an
                                        operator or API call), segment (on
                                        entering a segment), cdp_event (when an
                                        event is received), or inbound (when a
                                        message arrives on one of the org's
                                        channels). Defaults to manual.
                                      type: string
                                      enum:
                                        - manual
                                        - segment
                                        - cdp_event
                                        - inbound
                                    segmentId:
                                      description: >-
                                        Segment id — required when triggerType
                                        is segment.
                                      type: string
                                    segmentName:
                                      description: Cached segment display name (optional).
                                      type: string
                                    eventName:
                                      description: >-
                                        CDP event name — required when
                                        triggerType is cdp_event.
                                      type: string
                                    inboundAction:
                                      description: >-
                                        Which arrival fires the trigger —
                                        required when triggerType is inbound.
                                        INSTAGRAM_COMMENT / FACEBOOK_COMMENT
                                        listen to public comments on the
                                        account's posts instead of DMs; they
                                        require Instagram or Messenger channels
                                        whose connection was granted comment
                                        permission, and enroll the commenter
                                        without opening a conversation.
                                      type: string
                                      enum:
                                        - WHATSAPP_MESSAGE
                                        - SMS_MESSAGE
                                        - INSTAGRAM_MESSAGE
                                        - MESSENGER_MESSAGE
                                        - INSTAGRAM_COMMENT
                                        - FACEBOOK_COMMENT
                                    inboundChannelIds:
                                      description: >-
                                        Channel ids to listen on — at least one
                                        required when triggerType is inbound.
                                        Must be NATIVE WhatsApp, SMS, Instagram
                                        or Messenger channels that are not
                                        deleted — WhatsApp and SMS additionally
                                        need an ONLINE sender, Instagram and
                                        Messenger have no sender row and need
                                        none (a Messenger Page still on the V1
                                        bridge is withheld as NOT_NATIVE);
                                        journeys_set_trigger names the eligible
                                        ids if you pass an ineligible one. For a
                                        comment action, only Instagram and
                                        Messenger channels are valid. Several
                                        published journeys may share one channel
                                        as long as their keywords differ:
                                        publishing a rule whose keyword (or
                                        blank catch-all) is already taken on
                                        that channel is refused with
                                        INBOUND_CHANNEL_TAKEN. Each arriving
                                        message enrols exactly one of them, the
                                        most specific matching rule, ties going
                                        to the older initiative.
                                      type: array
                                      items:
                                        type: string
                                    inboundKeyword:
                                      description: >-
                                        The word the inbound message must match
                                        for this journey to enrol — e.g.
                                        'PRECIO'. Blank or absent means the
                                        trigger is the catch-all and fires on
                                        ANY message arriving on the channel,
                                        which is almost never what you want
                                        beside other journeys on the same
                                        number. Several journeys may share one
                                        channel as long as their keywords differ
                                        — two rules with the same keyword on one
                                        channel, or two blank ones, are refused
                                        at publish with INBOUND_CHANNEL_TAKEN.
                                        The keyword is matched accent-, case-
                                        and punctuation-insensitively, and
                                        stored normalized.
                                      type: string
                                    inboundMatchMode:
                                      description: >-
                                        How inboundKeyword is matched: EXACT
                                        (the message is only-the-word),
                                        ALL_WORDS (the message contains
                                        all-the-words, in any order), or
                                        CONTAINS (the message contains-the-word,
                                        adjacent and in order). All three are
                                        word-based, so no mode ever matches
                                        inside a longer word ('precioso' does
                                        not match 'precio'). Defaults to EXACT.
                                        Ignored when inboundKeyword is blank.
                                      type: string
                                      enum:
                                        - EXACT
                                        - CONTAINS
                                        - ALL_WORDS
                                    maxEnrollments:
                                      description: >-
                                        Frequency cap: max enrollments per
                                        person within enrollmentWindow.
                                        Both-or-neither with enrollmentWindow.
                                      type: integer
                                      minimum: 1
                                      maximum: 9007199254740991
                                    enrollmentWindow:
                                      description: Rolling window for the frequency cap.
                                      type: string
                                    parallelRunsBy:
                                      description: >-
                                        Let one person have several runs of this
                                        journey at the same time, one per
                                        distinct value of this event property
                                        (e.g. "paymentLinkId"). Use it when a
                                        person can have several of the same
                                        thing in flight, two payment links or
                                        two orders, and each needs its own
                                        sequence. Three things to know. It works
                                        on cdp_event triggers only, because the
                                        run is identified by a property of the
                                        triggering event; an event that does not
                                        carry the property is refused rather
                                        than enrolled. The journey becomes SEND
                                        ONLY: no wait-for-reply, conversation or
                                        AI nodes, because an inbound message
                                        belongs to the person and not to one
                                        run, so a single reply would wake every
                                        run at once. And every stop event listed
                                        in cancelOnEvents matches on this same
                                        property, so a completed one stops only
                                        its own run and leaves the person's
                                        other runs alive. Publish is refused if
                                        any of that is violated.
                                      type: string
                                      minLength: 1
                                  additionalProperties: false
                                  description: >-
                                    Trigger node config. Exactly one ENTRY node
                                    per journey.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: SEND_MESSAGE
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    mode:
                                      description: >-
                                        What this send carries: 'template' (an
                                        approved WhatsApp template, the default
                                        when omitted) or 'free_text' (prose you
                                        write, needing `body` instead of
                                        `templateId`). free_text emits SENT and
                                        WINDOW_CLOSED, both of which must be
                                        wired — Meta accepts free-form content
                                        only within 24 hours of the customer's
                                        last message, checked before sending.
                                        Prefer this over the deprecated
                                        SEND_WHATSAPP_TEXT node, which is the
                                        same send under an older name.
                                      type: string
                                      enum:
                                        - template
                                        - free_text
                                    templateId:
                                      description: >-
                                        Approved WhatsApp template id. Resolve
                                        ids from the catalog.
                                      type: string
                                    templateName:
                                      type: string
                                    body:
                                      description: >-
                                        The message text, for mode 'free_text'
                                        only. Placeholders are named, like
                                        {{customer.name}}, and EVERY one must
                                        have a matching entry in `bindings` or
                                        publish is refused: an unbound
                                        placeholder is sent literally, braces
                                        and all. Bind an upstream HTTP response
                                        with
                                        engagement.nodeOutputs.<nodeId>.body.<field>.
                                      type: string
                                    bindings:
                                      description: >-
                                        Map of {{placeholder}} name → variable
                                        reference, for `body`. Template mode
                                        uses `templateBindings` instead.
                                      type: object
                                      propertyNames:
                                        type: string
                                      additionalProperties:
                                        type: string
                                    channel:
                                      description: >-
                                        Always whatsapp. Other channels have
                                        their own node kind — SEND_SMS for a
                                        text, SEND_INSTAGRAM for Instagram,
                                        SEND_MESSENGER for Facebook Messenger.
                                      type: string
                                      const: whatsapp
                                    templateBindings:
                                      description: >-
                                        Map of template placeholder → variable
                                        reference, or fixed text prefixed
                                        `literal:` (e.g. `{ "2":
                                        "literal:BIENVENIDA20" }`) for a value
                                        that is the same for every recipient.
                                        EVERY placeholder the template declares
                                        (body, header, footer, button URL) needs
                                        an entry or publish is refused, since an
                                        unbound one is sent literally. The only
                                        exception: a template whose sole
                                        placeholder is {{1}}, with no map at
                                        all, falls back to the customer name
                                        (not on a Transactional).
                                      type: object
                                      propertyNames:
                                        type: string
                                      additionalProperties:
                                        type: string
                                    channelId:
                                      description: >-
                                        Sending WhatsApp channel (WABA) id.
                                        Required before publishing.
                                      type: string
                                    sendImmediately:
                                      description: >-
                                        Deprecated business-hours gate; prefer a
                                        preceding DELAY.
                                      type: boolean
                                    delivery:
                                      description: >-
                                        'draft' holds the rendered send in the
                                        Drafts queue until an org member
                                        approves or rejects it; the run waits at
                                        this node. Approve sends it and
                                        continues on SENT; reject emits REJECTED
                                        (optional edge — unwired, the run ends).
                                        Omit for 'immediate'. Refused on a
                                        Transactional initiative's journey
                                        (`transactional_draft_delivery`): a
                                        notification must go out. Refused
                                        (`drafts_disabled`) while drafts are
                                        turned off for the organization; a
                                        published drafted send reached while
                                        they're off is skipped (SKIPPED), never
                                        sent unreviewed.
                                      type: string
                                      enum:
                                        - immediate
                                        - draft
                                  additionalProperties: false
                                  description: >-
                                    Sends WhatsApp: an approved template
                                    (default), or free-text prose with mode
                                    'free_text'.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: SEND_SMS
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    body:
                                      description: >-
                                        The message text. Free text — SMS has no
                                        approved-template concept. Placeholders
                                        are named, like {{customer.name}}, and
                                        EVERY one must have a matching entry in
                                        `bindings` or publish is refused: an
                                        unbound placeholder is sent literally,
                                        braces and all. The opt-out footer and
                                        the brand are added by the system; do
                                        not write them into the body.
                                      type: string
                                    channelId:
                                      description: >-
                                        Sending SMS channel id. Required before
                                        publishing.
                                      type: string
                                    bindings:
                                      description: >-
                                        Map of {{placeholder}} name → variable
                                        reference. The builder writes the path
                                        as its own name ({"customer.name":
                                        "customer.name"}); an alias is allowed
                                        as long as the body uses the alias.
                                      type: object
                                      propertyNames:
                                        type: string
                                      additionalProperties:
                                        type: string
                                    optOutText:
                                      description: >-
                                        Opt-out line for this node, overriding
                                        the organization's. Must contain the
                                        STOP keyword. Omit to use the
                                        organization's.
                                      type: string
                                    allowEmoji:
                                      description: >-
                                        Keep emoji instead of stripping them.
                                        Defaults to false, because emoji force
                                        UCS-2 encoding, which cuts a message
                                        part from 160 characters to 70 and
                                        roughly doubles the cost.
                                      type: boolean
                                  additionalProperties: false
                                  description: Sends a plain-text SMS.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: SEND_WHATSAPP_TEXT
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    body:
                                      description: >-
                                        The message text. Free text — no Meta
                                        template approval needed, which is the
                                        point of this node. Placeholders are
                                        named, like {{customer.name}}, and EVERY
                                        one must have a matching entry in
                                        `bindings` or publish is refused: an
                                        unbound placeholder is sent literally,
                                        braces and all. Bind an upstream HTTP
                                        response with
                                        engagement.nodeOutputs.<nodeId>.body.<field>.
                                      type: string
                                    channelId:
                                      description: >-
                                        Sending WhatsApp channel (WABA) id.
                                        Required before publishing; it is also
                                        the per-number send throttle key.
                                      type: string
                                    bindings:
                                      description: >-
                                        Map of {{placeholder}} name → variable
                                        reference. The builder writes the path
                                        as its own name ({"customer.name":
                                        "customer.name"}); an alias is allowed
                                        as long as the body uses the alias.
                                      type: object
                                      propertyNames:
                                        type: string
                                      additionalProperties:
                                        type: string
                                  additionalProperties: false
                                  description: >-
                                    Sends free-text WhatsApp — author-written
                                    prose instead of an approved template. Emits
                                    SENT or WINDOW_CLOSED, and BOTH must be
                                    wired. Meta accepts free-form content only
                                    within 24 hours of the customer's last
                                    message; the node checks that BEFORE sending
                                    (Twilio would accept an out-of-window
                                    message and fail it asynchronously with
                                    63016), so WINDOW_CLOSED means nothing was
                                    sent and is where you put an approved
                                    template. A node with no upstream
                                    WAIT_FOR_REPLY / MANAGE_CONVERSATION will
                                    usually take WINDOW_CLOSED — publish warns
                                    but does not block, because a customer who
                                    wrote recently on this number in ANY journey
                                    still has an open window.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: SEND_INSTAGRAM
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    body:
                                      description: >-
                                        The message text. Free text — Instagram
                                        has no approved-template concept.
                                        Placeholders are named, like
                                        {{customer.name}}, and EVERY one must
                                        have a matching entry in `bindings` or
                                        publish is refused: an unbound
                                        placeholder is sent literally, braces
                                        and all.
                                      type: string
                                    channelId:
                                      description: >-
                                        Sending native Instagram channel id.
                                        Required before publishing, with no
                                        org-primary fallback.
                                      type: string
                                    bindings:
                                      description: >-
                                        Map of {{placeholder}} name → variable
                                        reference. The builder writes the path
                                        as its own name ({"customer.name":
                                        "customer.name"}); an alias is allowed
                                        as long as the body uses the alias.
                                      type: object
                                      propertyNames:
                                        type: string
                                      additionalProperties:
                                        type: string
                                  additionalProperties: false
                                  description: >-
                                    Sends free-text Instagram from a chosen
                                    native account — no template concept, so
                                    every message is author-written prose. Emits
                                    SENT or WINDOW_CLOSED, and BOTH must be
                                    wired. Meta accepts free-form content only
                                    within 24 hours of the customer's last
                                    message; the node checks that BEFORE
                                    sending, so WINDOW_CLOSED means nothing was
                                    sent. Instagram has no template fallback, so
                                    WINDOW_CLOSED usually leads to EXIT — say so
                                    explicitly rather than leaving it dangling.
                                    Exception: in a run an INSTAGRAM_COMMENT
                                    trigger started, a shut window sends one
                                    private reply to that comment instead (same
                                    account, comment under 7 days old and not
                                    yet replied to); Meta decides whether it
                                    lands.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: SEND_EMAIL
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    templateId:
                                      description: >-
                                        A PUBLISHED email template id from
                                        journeys_email_templates. Required
                                        before publishing; a draft or archived
                                        template is refused at publish.
                                      type: string
                                    templateName:
                                      description: >-
                                        The template's name, cached so the
                                        canvas can label the node without a
                                        lookup. Copy it from
                                        journeys_email_templates.
                                      type: string
                                    bindings:
                                      description: >-
                                        Map of the template's variable key (its
                                        `variables[].key` in
                                        journeys_email_templates) → variable
                                        reference such as customer.name, or
                                        engagement.chatLink for the link that
                                        opens this run's web chat. Bind only
                                        what you want to reroute: a variable
                                        left out resolves its own `path`, as the
                                        template was authored.
                                      type: object
                                      propertyNames:
                                        type: string
                                      additionalProperties:
                                        type: string
                                    fromSenderIdOverride:
                                      description: >-
                                        Sender id to send From for this node
                                        only, overriding the template's pick and
                                        the org default. Must be a sender with
                                        usableAsFrom: true in
                                        journeys_email_templates. Omit to
                                        inherit.
                                      type: string
                                    replyToSenderIdOverride:
                                      description: >-
                                        Sender id to use as Reply-To for this
                                        node only. Omit to inherit the template,
                                        then the org default.
                                      type: string
                                    delivery:
                                      description: >-
                                        'draft' holds the rendered send in the
                                        Drafts queue until an org member
                                        approves or rejects it; the run waits at
                                        this node. Approve sends it and
                                        continues on SENT; reject emits REJECTED
                                        (optional edge — unwired, the run ends).
                                        Omit for 'immediate'. Refused on a
                                        Transactional initiative's journey
                                        (`transactional_draft_delivery`): a
                                        notification must go out. Refused
                                        (`drafts_disabled`) while drafts are
                                        turned off for the organization; a
                                        published drafted send reached while
                                        they're off is skipped (SKIPPED), never
                                        sent unreviewed.
                                      type: string
                                      enum:
                                        - immediate
                                        - draft
                                  additionalProperties: false
                                  description: >-
                                    Sends a PUBLISHED email template to the
                                    customer.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: SEND_MESSENGER
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    body:
                                      description: >-
                                        The message text, at most 2000
                                        characters. Free text — no
                                        approved-template concept. Placeholders
                                        are named, like {{customer.name}}, and
                                        EVERY one must have a matching entry in
                                        `bindings` or publish is refused: an
                                        unbound placeholder is sent literally,
                                        braces and all.
                                      type: string
                                    channelId:
                                      description: >-
                                        Sending native Messenger channel
                                        (Facebook Page) id, from
                                        journeys_message_channels (sendNodeKind
                                        SEND_MESSENGER). Required before
                                        publishing, with no org-primary
                                        fallback.
                                      type: string
                                    bindings:
                                      description: >-
                                        Map of {{placeholder}} name → variable
                                        reference. The builder writes the path
                                        as its own name ({"customer.name":
                                        "customer.name"}); an alias is allowed
                                        as long as the body uses the alias.
                                      type: object
                                      propertyNames:
                                        type: string
                                      additionalProperties:
                                        type: string
                                  additionalProperties: false
                                  description: >-
                                    Sends free-text Facebook Messenger from a
                                    chosen Page — every message is
                                    author-written prose. Emits SENT or
                                    WINDOW_CLOSED, and BOTH must be wired. Meta
                                    accepts it only within 24 hours of the
                                    customer's last message; the node checks
                                    that BEFORE sending, so WINDOW_CLOSED means
                                    nothing was sent. There is no template
                                    fallback, so WINDOW_CLOSED usually leads to
                                    EXIT — say so explicitly rather than leaving
                                    it dangling. Exception: in a run an
                                    FACEBOOK_COMMENT trigger started, a shut
                                    window sends one private reply to that
                                    comment instead (same Page, comment under 7
                                    days old and not yet replied to); Meta
                                    decides whether it lands.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: CONVERSATION_BLOCK
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    goal:
                                      type: string
                                    maxTimeout:
                                      description: >-
                                        How long to wait for a reply before
                                        timing out.
                                      type: string
                                    mode:
                                      type: string
                                      enum:
                                        - AGENT
                                        - ESCALATE
                                    outputs:
                                      type: array
                                      items:
                                        type: object
                                        properties:
                                          id:
                                            type: string
                                          label:
                                            type: string
                                          type:
                                            type: string
                                            enum:
                                              - string
                                              - number
                                              - date
                                              - boolean
                                              - json
                                          description:
                                            type: string
                                          builtin:
                                            type: boolean
                                        required:
                                          - id
                                          - label
                                          - type
                                          - builtin
                                        additionalProperties: false
                                  additionalProperties: false
                                  description: >-
                                    Legacy combined wait + AI conversation
                                    block.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: WAIT_FOR_REPLY
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    maxTimeout:
                                      description: >-
                                        How long to wait for the first reply
                                        before timing out.
                                      type: string
                                  additionalProperties: false
                                  description: Waits for the person to reply.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: MANAGE_CONVERSATION
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    mode:
                                      description: >-
                                        AGENT (AI-led) or ESCALATE (human
                                        handoff). Defaults to AGENT.
                                      type: string
                                      enum:
                                        - AGENT
                                        - ESCALATE
                                    goal:
                                      description: >-
                                        Instructions for this conversation step
                                        only, on top of the initiative objective
                                        (e.g. 'Confirm the delivery address
                                        before anything else'). AGENT mode only;
                                        ignored in ESCALATE.
                                      type: string
                                    inactivityTimeout:
                                      description: >-
                                        Optional custom idle window (e.g. '2h',
                                        '30m') that overrides the global
                                        inactive-conversation close. Resets on
                                        each inbound message; after this much
                                        silence the node closes the conversation
                                        (routes CLOSED), unless the AI has
                                        escalated it to a human, in which case
                                        it stays open. Hard cap 24h; under 30m
                                        is allowed but flagged 'not
                                        recommended'. Requires the
                                        journey-inactivity-timeout flag.
                                      type: string
                                  additionalProperties: false
                                  description: Runs the AI-led conversation.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: DISPATCH_EVENT
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    eventName:
                                      type: string
                                      minLength: 1
                                      description: >-
                                        CDP event name to record. Must match the
                                        CDP name pattern.
                                    properties:
                                      description: >-
                                        Literal string values, or { var: path }
                                        bindings resolved to typed values at
                                        dispatch time.
                                      type: object
                                      propertyNames:
                                        type: string
                                      additionalProperties:
                                        anyOf:
                                          - type: string
                                          - type: object
                                            properties:
                                              var:
                                                type: string
                                            required:
                                              - var
                                            additionalProperties: false
                                    description:
                                      type: string
                                  required:
                                    - eventName
                                  additionalProperties: false
                                  description: Records a CDP event for the person.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: DELAY
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    mode:
                                      description: >-
                                        How the wait is measured. Defaults to
                                        duration.
                                      type: string
                                      enum:
                                        - duration
                                        - until_date
                                        - until_weekday
                                    duration:
                                      description: For mode duration.
                                      type: string
                                    targetAt:
                                      description: ISO 8601 instant, for mode until_date.
                                      type: string
                                    weekdays:
                                      description: >-
                                        ISO weekdays 1=Mon..7=Sun, for mode
                                        until_weekday.
                                      type: array
                                      items:
                                        type: integer
                                        minimum: 1
                                        maximum: 7
                                    windowStartMinutes:
                                      type: integer
                                      minimum: 0
                                      maximum: 1439
                                    windowEndMinutes:
                                      type: integer
                                      minimum: 0
                                      maximum: 1439
                                    timezone:
                                      description: >-
                                        IANA timezone. Load-bearing for
                                        until_weekday.
                                      type: string
                                    description:
                                      type: string
                                  additionalProperties: false
                                  description: Pauses the run.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: DECISION
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    logic:
                                      type: string
                                      enum:
                                        - AND
                                        - OR
                                    conditions:
                                      type: array
                                      items:
                                        oneOf:
                                          - type: object
                                            properties:
                                              kind:
                                                type: string
                                                const: value
                                              selectionPath:
                                                type: string
                                                description: >-
                                                  Dot-path into the run; must start with
                                                  one of "engagement.workflowState.",
                                                  "engagement.extracted.",
                                                  "engagement.nodeOutputs.",
                                                  "engagement.conversation." (e.g.
                                                  engagement.workflowState.totalPrice).
                                                  customer.*, person.*, attributes.* and
                                                  engagement.context.* are NOT resolvable
                                                  here. Unlike the other roots,
                                                  "engagement.conversation." takes ONE OF
                                                  a closed set of keys —
                                                  hoursSinceLastInbound, lastInboundText,
                                                  lastInboundKind, documentCount,
                                                  newDocumentCount — and any other key is
                                                  refused at publish rather than resolving
                                                  blank. A single formatting helper may
                                                  follow the path ("| currency:MXN", "|
                                                  count"), including on
                                                  engagement.conversation.*, whose key is
                                                  checked with the helper stripped off.
                                              operator:
                                                type: string
                                                enum:
                                                  - eq
                                                  - neq
                                                  - gt
                                                  - lt
                                                  - contains
                                                  - matchesKeyword
                                                  - isSet
                                                description: >-
                                                  How to compare. `contains` is a plain
                                                  substring test, so "precio" also matches
                                                  "precioso". `matchesKeyword` is the
                                                  ENTRY inbound-trigger matcher instead —
                                                  accent- and case-folded, matched on word
                                                  boundaries — so an author who writes the
                                                  same word on a trigger and mid-journey
                                                  gets the same answer. Use
                                                  `matchesKeyword` to route by what the
                                                  customer said; a value that folds to no
                                                  letters or digits is refused at publish,
                                                  because it would match every message.
                                                  Must also suit the selected field: text
                                                  tests (`contains`, `matchesKeyword`) are
                                                  refused on a number, and ordering (`gt`,
                                                  `lt`) on text — see
                                                  DECISION_OPERATOR_TYPE_MISMATCH.
                                              value:
                                                type: string
                                            required:
                                              - kind
                                              - selectionPath
                                              - operator
                                              - value
                                            additionalProperties: false
                                          - type: object
                                            properties:
                                              kind:
                                                type: string
                                                const: event
                                              eventName:
                                                type: string
                                              subjectSelectionPath:
                                                type: string
                                                description: >-
                                                  Dot-path into the run; must start with
                                                  one of "engagement.workflowState.",
                                                  "engagement.extracted.",
                                                  "engagement.nodeOutputs.",
                                                  "engagement.conversation." (e.g.
                                                  engagement.workflowState.totalPrice).
                                                  customer.*, person.*, attributes.* and
                                                  engagement.context.* are NOT resolvable
                                                  here. Unlike the other roots,
                                                  "engagement.conversation." takes ONE OF
                                                  a closed set of keys —
                                                  hoursSinceLastInbound, lastInboundText,
                                                  lastInboundKind, documentCount,
                                                  newDocumentCount — and any other key is
                                                  refused at publish rather than resolving
                                                  blank. A single formatting helper may
                                                  follow the path ("| currency:MXN", "|
                                                  count"), including on
                                                  engagement.conversation.*, whose key is
                                                  checked with the helper stripped off.
                                              occurred:
                                                type: boolean
                                            required:
                                              - kind
                                              - eventName
                                              - subjectSelectionPath
                                              - occurred
                                            additionalProperties: false
                                          - type: object
                                            properties:
                                              kind:
                                                type: string
                                                const: cdp_predicate
                                              term:
                                                type: object
                                                properties:
                                                  attr:
                                                    type: string
                                                    minLength: 1
                                                    description: >-
                                                      Typed person column, `attributes.<key>`,
                                                      or `computed.<key>`. See
                                                      journeys_condition_catalog for the
                                                      available attributes.
                                                  type:
                                                    type: string
                                                    enum:
                                                      - STRING
                                                      - NUMBER
                                                      - BOOLEAN
                                                      - DATE
                                                      - JSON
                                                      - ARRAY
                                                    description: >-
                                                      CDP attribute type. Determines which
                                                      `op` values are legal — see
                                                      journeys_condition_catalog.
                                                  op:
                                                    type: string
                                                    minLength: 1
                                                    description: >-
                                                      Segments OperatorEnum value (eq | neq |
                                                      gt | lt | in_last_n | ...). Must be
                                                      legal for `type` — see
                                                      journeys_condition_catalog.
                                                  value:
                                                    description: >-
                                                      Shape depends on `op`: a plain scalar
                                                      for eq/neq/gt/lt/starts_with/…, an array
                                                      for in/not_in/contains/not_contains,
                                                      {from, to} for between, {amount, unit}
                                                      for
                                                      in_last_n/in_next_n/more_than_n_ago/more_than_n_from_now,
                                                      {minAmount, maxAmount, unit} for
                                                      between_n_and_m_ago, {daysOffset} for
                                                      exactly_n_from_today. Omit entirely for
                                                      is_null/is_not_null.
                                                    anyOf:
                                                      - type: string
                                                      - type: number
                                                      - type: boolean
                                                      - type: array
                                                        items:
                                                          anyOf:
                                                            - type: string
                                                            - type: number
                                                      - type: object
                                                        properties:
                                                          from:
                                                            type: string
                                                          to:
                                                            type: string
                                                        required:
                                                          - from
                                                          - to
                                                        additionalProperties: false
                                                      - type: object
                                                        properties:
                                                          amount:
                                                            type: integer
                                                            minimum: 1
                                                            maximum: 9999
                                                          unit:
                                                            type: string
                                                            enum:
                                                              - days
                                                              - weeks
                                                              - months
                                                        required:
                                                          - amount
                                                          - unit
                                                        additionalProperties: false
                                                      - type: object
                                                        properties:
                                                          minAmount:
                                                            type: integer
                                                            minimum: 0
                                                            maximum: 9999
                                                          maxAmount:
                                                            type: integer
                                                            minimum: 1
                                                            maximum: 9999
                                                          unit:
                                                            type: string
                                                            enum:
                                                              - days
                                                              - weeks
                                                              - months
                                                        required:
                                                          - minAmount
                                                          - maxAmount
                                                          - unit
                                                        additionalProperties: false
                                                      - type: object
                                                        properties:
                                                          daysOffset:
                                                            type: integer
                                                            minimum: -9007199254740991
                                                            maximum: 9007199254740991
                                                          rollForward:
                                                            type: object
                                                            properties:
                                                              fromDow:
                                                                type: integer
                                                                minimum: 0
                                                                maximum: 6
                                                              includeDows:
                                                                minItems: 1
                                                                type: array
                                                                items:
                                                                  type: integer
                                                                  minimum: 0
                                                                  maximum: 6
                                                            required:
                                                              - fromDow
                                                              - includeDows
                                                            additionalProperties: false
                                                        required:
                                                          - daysOffset
                                                        additionalProperties: false
                                                required:
                                                  - attr
                                                  - type
                                                  - op
                                                additionalProperties: false
                                                description: >-
                                                  A single live person/computed predicate
                                                  term. See journeys_condition_catalog for
                                                  its shape and the legal operator/value
                                                  pairing.
                                            required:
                                              - kind
                                              - term
                                            additionalProperties: false
                                          - type: object
                                            properties:
                                              kind:
                                                type: string
                                                const: cdp_object
                                              objectType:
                                                type: string
                                              matchAttr:
                                                type: string
                                              matchSelectionPath:
                                                type: string
                                                description: >-
                                                  Dot-path into the run; must start with
                                                  one of "engagement.workflowState.",
                                                  "engagement.extracted.",
                                                  "engagement.nodeOutputs.",
                                                  "engagement.conversation." (e.g.
                                                  engagement.workflowState.totalPrice).
                                                  customer.*, person.*, attributes.* and
                                                  engagement.context.* are NOT resolvable
                                                  here. Unlike the other roots,
                                                  "engagement.conversation." takes ONE OF
                                                  a closed set of keys —
                                                  hoursSinceLastInbound, lastInboundText,
                                                  lastInboundKind, documentCount,
                                                  newDocumentCount — and any other key is
                                                  refused at publish rather than resolving
                                                  blank. A single formatting helper may
                                                  follow the path ("| currency:MXN", "|
                                                  count"), including on
                                                  engagement.conversation.*, whose key is
                                                  checked with the helper stripped off.
                                              exists:
                                                type: boolean
                                            required:
                                              - kind
                                              - objectType
                                              - matchAttr
                                              - matchSelectionPath
                                              - exists
                                            additionalProperties: false
                                          - type: object
                                            properties:
                                              kind:
                                                type: string
                                                const: matched_object
                                              objectType:
                                                type: string
                                                minLength: 1
                                                description: >-
                                                  Custom-object type whose matched rows
                                                  (the rows that put this person in the
                                                  entry segment,
                                                  `workflowState.__matched.<type>`) are
                                                  re-read LIVE. Segment-triggered journeys
                                                  only; must be one of the segment's
                                                  matched types.
                                              term:
                                                type: object
                                                properties:
                                                  attr:
                                                    type: string
                                                    minLength: 1
                                                    description: >-
                                                      The BARE attribute key of the matched
                                                      object type, exactly as in its attribute
                                                      catalog (e.g. `order_status`). No
                                                      `attributes.`, `object.` or `computed.`
                                                      prefix. `type` must equal the catalogued
                                                      type.
                                                  type:
                                                    type: string
                                                    enum:
                                                      - STRING
                                                      - NUMBER
                                                      - BOOLEAN
                                                      - DATE
                                                      - JSON
                                                      - ARRAY
                                                    description: >-
                                                      CDP attribute type. Determines which
                                                      `op` values are legal — see
                                                      journeys_condition_catalog.
                                                  op:
                                                    type: string
                                                    minLength: 1
                                                    description: >-
                                                      Segments OperatorEnum value (eq | neq |
                                                      gt | lt | in_last_n | ...). Must be
                                                      legal for `type` — see
                                                      journeys_condition_catalog.
                                                  value:
                                                    description: >-
                                                      Shape depends on `op`: a plain scalar
                                                      for eq/neq/gt/lt/starts_with/…, an array
                                                      for in/not_in/contains/not_contains,
                                                      {from, to} for between, {amount, unit}
                                                      for
                                                      in_last_n/in_next_n/more_than_n_ago/more_than_n_from_now,
                                                      {minAmount, maxAmount, unit} for
                                                      between_n_and_m_ago, {daysOffset} for
                                                      exactly_n_from_today. Omit entirely for
                                                      is_null/is_not_null.
                                                    anyOf:
                                                      - type: string
                                                      - type: number
                                                      - type: boolean
                                                      - type: array
                                                        items:
                                                          anyOf:
                                                            - type: string
                                                            - type: number
                                                      - type: object
                                                        properties:
                                                          from:
                                                            type: string
                                                          to:
                                                            type: string
                                                        required:
                                                          - from
                                                          - to
                                                        additionalProperties: false
                                                      - type: object
                                                        properties:
                                                          amount:
                                                            type: integer
                                                            minimum: 1
                                                            maximum: 9999
                                                          unit:
                                                            type: string
                                                            enum:
                                                              - days
                                                              - weeks
                                                              - months
                                                        required:
                                                          - amount
                                                          - unit
                                                        additionalProperties: false
                                                      - type: object
                                                        properties:
                                                          minAmount:
                                                            type: integer
                                                            minimum: 0
                                                            maximum: 9999
                                                          maxAmount:
                                                            type: integer
                                                            minimum: 1
                                                            maximum: 9999
                                                          unit:
                                                            type: string
                                                            enum:
                                                              - days
                                                              - weeks
                                                              - months
                                                        required:
                                                          - minAmount
                                                          - maxAmount
                                                          - unit
                                                        additionalProperties: false
                                                      - type: object
                                                        properties:
                                                          daysOffset:
                                                            type: integer
                                                            minimum: -9007199254740991
                                                            maximum: 9007199254740991
                                                          rollForward:
                                                            type: object
                                                            properties:
                                                              fromDow:
                                                                type: integer
                                                                minimum: 0
                                                                maximum: 6
                                                              includeDows:
                                                                minItems: 1
                                                                type: array
                                                                items:
                                                                  type: integer
                                                                  minimum: 0
                                                                  maximum: 6
                                                            required:
                                                              - fromDow
                                                              - includeDows
                                                            additionalProperties: false
                                                        required:
                                                          - daysOffset
                                                        additionalProperties: false
                                                required:
                                                  - attr
                                                  - type
                                                  - op
                                                additionalProperties: false
                                                description: >-
                                                  Condition on the row's CURRENT
                                                  attributes. `attr` is the bare object
                                                  attribute key (e.g. `order_status`, not
                                                  `object.attributes.order_status`);
                                                  `type`/`op`/`value` follow the same
                                                  rules as a cdp_predicate term.
                                              quantifier:
                                                type: string
                                                enum:
                                                  - any
                                                  - all
                                                description: >-
                                                  `any`: YES when at least one matched row
                                                  passes. `all`: YES only when every
                                                  matched row still exists and passes. No
                                                  matched rows on the run → false.
                                            required:
                                              - kind
                                              - objectType
                                              - term
                                              - quantifier
                                            additionalProperties: false
                                        description: One decision condition.
                                    description:
                                      type: string
                                  required:
                                    - logic
                                    - conditions
                                  additionalProperties: false
                                  description: Two-way branch. Emits YES / NO.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: CASE
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    selectionPath:
                                      type: string
                                      description: >-
                                        Value to switch on; must start with one
                                        of "attributes.",
                                        "engagement.extracted.",
                                        "engagement.nodeOutputs.", "matched."
                                        (e.g. attributes.plan_tier).
                                        "matched.<type>.<attr>" (e.g.
                                        matched.order.order_status) switches on
                                        the CURRENT value of an attribute of the
                                        row that put the person in the entry
                                        segment — the first matched row of that
                                        type, read live; segment-triggered
                                        journeys only, and the type must be in
                                        the segment's matched types. A
                                        formatting helper ("| currency:MXN", "|
                                        count") is REFUSED here, unlike on a
                                        DECISION condition: CASE reads this path
                                        raw, so a helper would resolve blank and
                                        route case:default on every run.
                                    branches:
                                      type: array
                                      items:
                                        type: object
                                        properties:
                                          id:
                                            type: string
                                            description: >-
                                              Stable branch id; edge handle is
                                              case:<id>.
                                          value:
                                            type: string
                                            description: Value matched. Unique within the node.
                                          label:
                                            type: string
                                            minLength: 1
                                            description: >-
                                              Required. Names the variant in analytics
                                              and on canvas.
                                        required:
                                          - id
                                          - value
                                          - label
                                        additionalProperties: false
                                      description: >-
                                        Up to 10 branches. A case:default handle
                                        is always required.
                                    description:
                                      type: string
                                  required:
                                    - selectionPath
                                    - branches
                                  additionalProperties: false
                                  description: N-way switch on a person attribute.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: RANDOM_SPLIT
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    arms:
                                      type: array
                                      items:
                                        type: object
                                        properties:
                                          id:
                                            type: string
                                            description: >-
                                              Stable arm id; edge handle is
                                              split:<id>.
                                          weight:
                                            type: integer
                                            minimum: 1
                                            maximum: 100
                                            description: >-
                                              Integer percentage. A node's arms must
                                              total 100.
                                          label:
                                            type: string
                                        required:
                                          - id
                                          - weight
                                        additionalProperties: false
                                      description: >-
                                        At least 2 and at most 10 arms whose
                                        weights total exactly 100. There is no
                                        default handle — every roll lands on a
                                        declared arm.
                                    description:
                                      type: string
                                  required:
                                    - arms
                                  additionalProperties: false
                                  description: >-
                                    Randomly routes each run down one of N
                                    weighted arms.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: HTTP_REQUEST
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    method:
                                      type: string
                                      enum:
                                        - GET
                                        - POST
                                        - PUT
                                        - PATCH
                                        - DELETE
                                      description: HTTP method.
                                    url:
                                      type: string
                                      minLength: 1
                                      description: >-
                                        Target URL. Supports {{variable}}
                                        placeholders. Resolvable roots here:
                                        customer.<field> (a single flat field of
                                        the customer record), person.<attribute>
                                        (CDP), env.<key> (journey environment),
                                        engagement.context.*,
                                        engagement.workflowState.*,
                                        engagement.extracted.*,
                                        engagement.nodeOutputs.<nodeId>.*,
                                        engagement.documents (json body, whole
                                        quoted token, flag-gated), and
                                        engagement.conversation.id /
                                        engagement.conversation.inboxUrl — the
                                        conversation this run is talking to and
                                        its Shared Inbox deep link. Anything
                                        else substitutes as an empty string and
                                        is reported at publish as
                                        UNRESOLVABLE_HTTP_TOKEN. Note
                                        engagement.chatLink is SEND_EMAIL-only
                                        and does NOT resolve here.
                                    headers:
                                      description: >-
                                        Request headers as key/value pairs.
                                        Values support the same {{variable}}
                                        placeholders as the url. Resolvable
                                        roots here: customer.<field> (a single
                                        flat field of the customer record),
                                        person.<attribute> (CDP), env.<key>
                                        (journey environment),
                                        engagement.context.*,
                                        engagement.workflowState.*,
                                        engagement.extracted.*,
                                        engagement.nodeOutputs.<nodeId>.*,
                                        engagement.documents (json body, whole
                                        quoted token, flag-gated), and
                                        engagement.conversation.id /
                                        engagement.conversation.inboxUrl — the
                                        conversation this run is talking to and
                                        its Shared Inbox deep link. Anything
                                        else substitutes as an empty string and
                                        is reported at publish as
                                        UNRESOLVABLE_HTTP_TOKEN. Note
                                        engagement.chatLink is SEND_EMAIL-only
                                        and does NOT resolve here.
                                      type: array
                                      items:
                                        type: object
                                        properties:
                                          key:
                                            type: string
                                          value:
                                            type: string
                                        required:
                                          - key
                                          - value
                                        additionalProperties: false
                                    body:
                                      description: >-
                                        Request body. mode none sends no body.
                                        Supports the same {{variable}}
                                        placeholders as the url; in json mode a
                                        whole quoted token
                                        ("{{engagement.documents}}") substitutes
                                        as a JSON array. Resolvable roots here:
                                        customer.<field> (a single flat field of
                                        the customer record), person.<attribute>
                                        (CDP), env.<key> (journey environment),
                                        engagement.context.*,
                                        engagement.workflowState.*,
                                        engagement.extracted.*,
                                        engagement.nodeOutputs.<nodeId>.*,
                                        engagement.documents (json body, whole
                                        quoted token, flag-gated), and
                                        engagement.conversation.id /
                                        engagement.conversation.inboxUrl — the
                                        conversation this run is talking to and
                                        its Shared Inbox deep link. Anything
                                        else substitutes as an empty string and
                                        is reported at publish as
                                        UNRESOLVABLE_HTTP_TOKEN. Note
                                        engagement.chatLink is SEND_EMAIL-only
                                        and does NOT resolve here.
                                      type: object
                                      properties:
                                        mode:
                                          type: string
                                          enum:
                                            - none
                                            - json
                                            - raw
                                        content:
                                          type: string
                                        contentType:
                                          type: string
                                      required:
                                        - mode
                                      additionalProperties: false
                                    credentialId:
                                      description: >-
                                        Deprecated/legacy: HttpCredential row id
                                        used to authenticate the request. Prefer
                                        credentialKey.
                                      type: string
                                    credentialKey:
                                      description: >-
                                        Logical credential key; the pinned
                                        environment selects the secret.
                                      type: string
                                    timeoutMs:
                                      description: >-
                                        Request timeout in milliseconds. Max
                                        30000 (30s).
                                      type: integer
                                      exclusiveMinimum: 0
                                      maximum: 30000
                                    maxAttempts:
                                      description: Max attempts including the first. Max 5.
                                      type: integer
                                      exclusiveMinimum: 0
                                      maximum: 5
                                    documentUrlTtlSeconds:
                                      description: >-
                                        TTL (seconds, ≤86400) for presigned
                                        engagement.documents URLs this node
                                        emits. Default 86400.
                                      type: integer
                                      exclusiveMinimum: 0
                                      maximum: 86400
                                    documentMimeTypes:
                                      description: >-
                                        Allowlist of MIME types this node may
                                        egress in engagement.documents, e.g.
                                        ['application/pdf'] for an endpoint that
                                        only accepts PDFs. Omit (or pass an
                                        empty list) to send every document type
                                        — the default. A document whose type is
                                        not listed is withheld and counted in
                                        the step's documents.filteredCount,
                                        never silently dropped. Match is exact,
                                        trimmed and case-insensitive; a document
                                        with no recorded type is withheld
                                        whenever a list is set. Each entry must
                                        be a MIME type an inbound document can
                                        actually have, because a well-formed
                                        typo would match nothing and withhold
                                        everything: image/jpeg, image/png,
                                        image/webp, image/gif, application/pdf,
                                        video/mp4, text/vcard, text/html,
                                        application/msword,
                                        application/vnd.ms-excel,
                                        application/vnd.openxmlformats-officedocument.wordprocessingml.document,
                                        application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,
                                        application/octet-stream.
                                      type: array
                                      items:
                                        type: string
                                        minLength: 1
                                  required:
                                    - method
                                    - url
                                  additionalProperties: false
                                  description: >-
                                    Calls an external HTTP endpoint. Emits
                                    SUCCESS or FAILED.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: ROUTE_TO_INITIATIVE
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    initiativeId:
                                      type: string
                                      minLength: 1
                                      description: >-
                                        Target initiative id to enroll this
                                        customer into.
                                    context:
                                      description: >-
                                        Values stamped onto the new engagement,
                                        readable by its agent. A literal string,
                                        or { var: 'engagement.extracted.<slug>'
                                        } resolved at route time.
                                      type: object
                                      propertyNames:
                                        type: string
                                      additionalProperties:
                                        anyOf:
                                          - type: string
                                          - type: object
                                            properties:
                                              var:
                                                type: string
                                            required:
                                              - var
                                            additionalProperties: false
                                    description:
                                      type: string
                                  required:
                                    - initiativeId
                                  additionalProperties: false
                                  description: >-
                                    Terminal. Ends this engagement and enrolls
                                    the customer into another initiative, moving
                                    the live conversation onto a new session.
                                    Emits no signals — it has no outgoing edges.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                            - type: object
                              properties:
                                id:
                                  type: string
                                  minLength: 1
                                  description: Node id, unique within the journey.
                                kind:
                                  type: string
                                  const: EXIT
                                name:
                                  type: string
                                  minLength: 1
                                  description: >-
                                    The label shown on the canvas. Required
                                    before publishing.
                                position:
                                  type: object
                                  properties:
                                    x:
                                      type: number
                                    'y':
                                      type: number
                                  required:
                                    - x
                                    - 'y'
                                  additionalProperties: false
                                  description: >-
                                    Explicit canvas position. Omit it and the
                                    server auto-lays-out the graph top-down;
                                    only set it to preserve a hand-arranged
                                    layout.
                                inputs:
                                  type: object
                                  properties:
                                    outcome:
                                      type: string
                                  additionalProperties: false
                                  description: Terminal node.
                              required:
                                - id
                                - kind
                              additionalProperties: false
                        description: >-
                          The nodes. Exactly one ENTRY, and at least one end
                          point (EXIT or ROUTE_TO_INITIATIVE), are required to
                          publish.
                      edges:
                        type: array
                        items:
                          type: object
                          properties:
                            from:
                              type: string
                              description: Source node id.
                            to:
                              type: string
                              description: Target node id.
                            sourceHandle:
                              type: string
                              description: >-
                                The emitted signal that activates this edge
                                (e.g. SENT, REPLIED, YES, case:<id>). A handle
                                may wire to at most one node.
                            metadata:
                              type: object
                              properties:
                                signalCategory:
                                  type: string
                                  enum:
                                    - lifecycle
                                    - system
                                signalDescription:
                                  type: string
                              additionalProperties: false
                          required:
                            - from
                            - to
                            - sourceHandle
                          additionalProperties: false
                          description: >-
                            A connection: node `from` routes to `to` when it
                            emits `sourceHandle`.
                        description: The connections between node handles.
                    required:
                      - name
                      - actions
                      - edges
                    additionalProperties: false
                    description: The full journey graph.
                required:
                  - id
                  - initiativeId
                  - status
                  - version
                  - definition
                additionalProperties: false
        '400':
          description: Validation failed or the request cannot proceed.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: Stable machine-readable error code (snake_case).
                      message:
                        type: string
                    required:
                      - code
                      - message
                required:
                  - error
        '401':
          description: Missing, malformed, or revoked API key.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: Stable machine-readable error code (snake_case).
                      message:
                        type: string
                    required:
                      - code
                      - message
                required:
                  - error
        '404':
          description: The resource does not exist in this organization.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: Stable machine-readable error code (snake_case).
                      message:
                        type: string
                    required:
                      - code
                      - message
                required:
                  - error
        '409':
          description: >-
            Conflicts with the current state (duplicates, wrong lifecycle
            state).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: Stable machine-readable error code (snake_case).
                      message:
                        type: string
                    required:
                      - code
                      - message
                required:
                  - error
        '422':
          description: The request is well-formed but semantically invalid.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: Stable machine-readable error code (snake_case).
                      message:
                        type: string
                    required:
                      - code
                      - message
                required:
                  - error
        '429':
          description: Rate limit exceeded — retry after `Retry-After`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: Stable machine-readable error code (snake_case).
                      message:
                        type: string
                    required:
                      - code
                      - message
                required:
                  - error
        '500':
          description: Internal server error.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: Stable machine-readable error code (snake_case).
                      message:
                        type: string
                    required:
                      - code
                      - message
                required:
                  - error
        '503':
          description: Transient error — retry with a narrower request.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: Stable machine-readable error code (snake_case).
                      message:
                        type: string
                    required:
                      - code
                      - message
                required:
                  - error
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Organization API key, sent as `Authorization: Bearer boom_org_...`.'

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.