> ## 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.

# Validate journey

> Dry-run the publish checks against a journey graph without saving. Pass a `journeyId` to validate the stored draft, or a `definition` to validate a graph as sent (exactly one of the two). Returns whether it is valid and the list of issues (errors block publishing; warnings are advisory). Use it to iterate a draft to valid before publishing in the app.



## OpenAPI

````yaml /api-reference/openapi.json post /api/v1/journeys/validate
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/validate:
    post:
      tags:
        - Journeys
      summary: Validate journey
      description: >-
        Dry-run the publish checks against a journey graph without saving. Pass
        a `journeyId` to validate the stored draft, or a `definition` to
        validate a graph as sent (exactly one of the two). Returns whether it is
        valid and the list of issues (errors block publishing; warnings are
        advisory). Use it to iterate a draft to valid before publishing in the
        app.
      operationId: journeys_validate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $schema: https://json-schema.org/draft/2020-12/schema
              type: object
              properties:
                journeyId:
                  description: >-
                    Validate the stored draft: a draft journey id, or the
                    initiative id (resolves to its current draft). Exactly one
                    of journeyId or definition.
                  type: string
                  minLength: 1
                definition:
                  description: >-
                    Validate this graph as sent, without loading anything.
                    Exactly one of journeyId or 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
                        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
                      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'
                                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
                      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
                        required:
                          - from
                          - to
                          - sourceHandle
                        description: >-
                          A connection: node `from` routes to `to` when it emits
                          `sourceHandle`.
                      description: The connections between node handles.
                  required:
                    - name
                    - actions
                    - edges
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $schema: https://json-schema.org/draft/2020-12/schema
                type: object
                properties:
                  valid:
                    type: boolean
                    description: True when there are no error-severity issues.
                  issues:
                    type: array
                    items:
                      type: object
                      properties:
                        code:
                          type: string
                          description: Stable issue code.
                        severity:
                          type: string
                          enum:
                            - error
                            - warning
                          description: error blocks publishing; warning is advisory.
                        nodeId:
                          description: The node this issue is about, if any.
                          type: string
                        message:
                          type: string
                          description: Plain-English explanation.
                      required:
                        - code
                        - severity
                        - message
                      additionalProperties: false
                required:
                  - valid
                  - issues
                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.