---
title: "Create a journey"
method: POST
path: "/journeys"
tags: ["Journeys"]
---

# Create a journey

`POST /journeys`

Creates a journey from a set of nodes, in draft state unless you pass a published state. Send nodes cannot be included until their templates exist.

## Headers

- `Idempotency-Key` string
- `x-idempotency-expiration` string

## Request body

- CreateJourneyRequest — Request body for creating a journey.
  - `name` string, required
  - `nodes` JourneyNode[], required
    - union — A single node in a journey DAG. Discriminated by `type`, with a secondary discriminator on some variants (`trigger_type` for trigger, `mode` for delay, `method` for fetch, `scope` for throttle).
      - JourneyApiInvokeTriggerNode — Trigger fired when the journey is invoked via the API. The optional `schema` field is a JSON Schema that validates the invocation payload.
        - `id` string
        - `type` 'trigger', required
        - `trigger_type` 'api-invoke', required
        - `schema` object — A JSONSchema object (Draft-07-compatible). Validated at runtime by Ajv.
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneySegmentTriggerNode — Trigger fired by a segment event (`identify`, `group`, or `track`).
        - `id` string
        - `type` 'trigger', required
        - `trigger_type` 'segment', required
        - `request_type` 'identify' | 'group' | 'track', required
        - `event_id` string
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneySendNode — Send to the recipient. A send node sources its content from EXACTLY ONE of `message.template` (a single notification template) or `experiment` (an A/B split across weighted template variants) — supplying both, or neither, is rejected. Optionally override the recipient address, send as a tenant, delay the send, or attach `data`.
        - `id` string
        - `type` 'send', required
        - `message` object, required
          - `template` string
          - `to` object
            - `email_override` string
            - `phone_number_override` string
            - `user_id_override` string
          - `context` object — Tenant context for this send. Set it to deliver on behalf of one of your customers, so the message uses that tenant's brand and settings.
            - `tenant_id` string, required — The tenant to send as. Accepts either a literal tenant id (`acme-tenant`) or a whole-string mustache reference to a value the run already holds — `{{data.tenant_id}}` from the invocation payload, or `{{f1.body.tenant_id}}` from the response of an earlier fetch node with id `f1`. A reference is resolved separately on every run, so a single journey can deliver as many tenants. Two forms are rejected with `400`: mid-string interpolation such as `tenant-{{data.region}}`, and any value beginning with `refs.`, which is reserved for internal use. A reference that resolves to nothing at run time does not stop the run — the message is still sent, with no tenant context — so make sure the referenced value is always present. `GET` returns the value in the same form it was supplied.
          - `delay` object
            - `until` string, required
            - `timezone` string
          - `data` object
        - `experiment` JourneyExperiment — A/B experiment config for a send node. The recipient is deterministically bucketed by `bucketingKey` and routed to one of the `variants` in proportion to its `weight`. Present on a send node INSTEAD OF `message.template`.
          - `id` string — Unique experiment id (prefixed `exp_`). Omit to have one generated automatically; when supplied it must be a valid `exp_` id.
          - `name` string — Optional display name for the experiment.
          - `bucketingKey` string, required — The value used to deterministically assign a recipient to a variant. Must be non-empty with no leading or trailing whitespace.
          - `variants` JourneyExperimentVariant[], required — Between 2 and 10 weighted template variants.
            - `id` string, required
            - `name` string — Optional display name for the variant.
            - `weight` number, required — Relative routing weight. Must be non-negative.
            - `templateId` string, required — The notification template sent for this variant.
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyDelayDurationNode — Pause the journey run for a fixed `duration`.
        - `id` string
        - `type` 'delay', required
        - `mode` 'duration', required
        - `duration` string, required
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyDelayUntilNode — Pause the journey run `until` a specific time.
        - `id` string
        - `type` 'delay', required
        - `mode` 'until', required
        - `until` string, required
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyFetchGetDeleteNode — Issue an HTTP GET or DELETE request and merge the response into the journey state per `merge_strategy`.
        - `id` string
        - `type` 'fetch', required
        - `method` 'get' | 'delete', required
        - `url` string, required
        - `merge_strategy` 'overwrite' | 'soft-merge' | 'replace' | 'none', required — Strategy for merging a fetch response into the journey run state.
        - `headers` object
        - `query_params` object
        - `response_schema` object — A JSONSchema object (Draft-07-compatible). Validated at runtime by Ajv.
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyFetchPostPutNode — Issue an HTTP POST or PUT request with a `body` and merge the response into the journey state per `merge_strategy`.
        - `id` string
        - `type` 'fetch', required
        - `method` 'post' | 'put', required
        - `url` string, required
        - `merge_strategy` 'overwrite' | 'soft-merge' | 'replace' | 'none', required — Strategy for merging a fetch response into the journey run state.
        - `headers` object
        - `query_params` object
        - `response_schema` object — A JSONSchema object (Draft-07-compatible). Validated at runtime by Ajv.
        - `body` string
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyAINode — Invoke an AI step with `user_prompt` and optional `web_search`. Returns a structured response conforming to `output_schema`.
        - `id` string
        - `type` 'ai', required
        - `model` string
        - `user_prompt` string
        - `web_search` boolean
        - `output_schema` object, required — A JSONSchema object (Draft-07-compatible). Validated at runtime by Ajv.
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyThrottleStaticNode — Throttle the journey by a static `scope` (`user` or `global`), allowing at most `max_allowed` invocations per `period`.
        - `id` string
        - `type` 'throttle', required
        - `scope` 'user' | 'global', required
        - `max_allowed` integer, required
        - `period` string, required
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyThrottleDynamicNode — Throttle the journey by a dynamic `throttle_key`, allowing at most `max_allowed` invocations per `period`.
        - `id` string
        - `type` 'throttle', required
        - `scope` 'dynamic', required
        - `max_allowed` integer, required
        - `period` string, required
        - `throttle_key` string, required
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyBatchNode — Collect events arriving at the node into a single batch and fire one downstream step with the aggregated payload. The first event into a batch owns the run; later contributing events terminate at the batch step. The batch releases when any of `max_items` is reached, a quiet window of `wait_period` elapses, or the `max_wait_period` ceiling hits.
        - `id` string
        - `type` 'batch', required
        - `scope` 'user', required
        - `wait_period` string, required — ISO 8601 duration. Quiet window that releases the batch when it elapses with no new contributing events. Must be less than `max_wait_period`.
        - `max_wait_period` string, required — ISO 8601 duration. Hard ceiling from the first event into the batch; releases the batch unconditionally when it elapses.
        - `max_items` integer — Releases the batch once this many events have been collected.
        - `retain` object, required — How to select which collected events to retain in the aggregated payload when the batch releases.
          - `type` 'first' | 'last' | 'highest' | 'lowest', required
          - `count` integer, required
          - `sort_key` string — Dot-path into the event payload (e.g. `data.priority`). Required when `type` is `highest` or `lowest`.
        - `category_key` string — Optional partition key. Events with the same `category_key` are batched together; events with different values are batched separately.
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyAddToDigestNode — Add the current event to a digest keyed by the given subscription topic. The digest accumulates events and releases them on the schedule configured for the topic.
        - `id` string
        - `type` 'add-to-digest', required
        - `subscription_topic_id` string, required — The subscription topic that owns the digest the event is added to.
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyExitNode — Terminate the journey run.
        - `id` string
        - `type` 'exit', required
      - object — Branch node. Routes to the first entry in `paths[]` whose `conditions` match, else falls through to `default.nodes`.
        - `id` string
        - `type` 'branch', required
        - `paths` object[], required
          - `label` string
          - `conditions` union, required — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
            - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
            - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
              - …
            - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
              - …
          - `nodes` JourneyNode[], required
        - `default` object, required
          - `label` string
          - `nodes` JourneyNode[], required
  - `enabled` boolean
  - `state` 'DRAFT' | 'PUBLISHED' — Lifecycle state of a journey.

## Response `201`

Journey created

- JourneyResponse — A journey, with its current draft or published nodes and metadata.
  - `id` string, required
  - `name` string, required
  - `state` 'DRAFT' | 'PUBLISHED', required — Lifecycle state of a journey.
  - `enabled` boolean, required
  - `nodes` JourneyNode[], required
    - union — A single node in a journey DAG. Discriminated by `type`, with a secondary discriminator on some variants (`trigger_type` for trigger, `mode` for delay, `method` for fetch, `scope` for throttle).
      - JourneyApiInvokeTriggerNode — Trigger fired when the journey is invoked via the API. The optional `schema` field is a JSON Schema that validates the invocation payload.
        - `id` string
        - `type` 'trigger', required
        - `trigger_type` 'api-invoke', required
        - `schema` object — A JSONSchema object (Draft-07-compatible). Validated at runtime by Ajv.
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneySegmentTriggerNode — Trigger fired by a segment event (`identify`, `group`, or `track`).
        - `id` string
        - `type` 'trigger', required
        - `trigger_type` 'segment', required
        - `request_type` 'identify' | 'group' | 'track', required
        - `event_id` string
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneySendNode — Send to the recipient. A send node sources its content from EXACTLY ONE of `message.template` (a single notification template) or `experiment` (an A/B split across weighted template variants) — supplying both, or neither, is rejected. Optionally override the recipient address, send as a tenant, delay the send, or attach `data`.
        - `id` string
        - `type` 'send', required
        - `message` object, required
          - `template` string
          - `to` object
            - `email_override` string
            - `phone_number_override` string
            - `user_id_override` string
          - `context` object — Tenant context for this send. Set it to deliver on behalf of one of your customers, so the message uses that tenant's brand and settings.
            - `tenant_id` string, required — The tenant to send as. Accepts either a literal tenant id (`acme-tenant`) or a whole-string mustache reference to a value the run already holds — `{{data.tenant_id}}` from the invocation payload, or `{{f1.body.tenant_id}}` from the response of an earlier fetch node with id `f1`. A reference is resolved separately on every run, so a single journey can deliver as many tenants. Two forms are rejected with `400`: mid-string interpolation such as `tenant-{{data.region}}`, and any value beginning with `refs.`, which is reserved for internal use. A reference that resolves to nothing at run time does not stop the run — the message is still sent, with no tenant context — so make sure the referenced value is always present. `GET` returns the value in the same form it was supplied.
          - `delay` object
            - `until` string, required
            - `timezone` string
          - `data` object
        - `experiment` JourneyExperiment — A/B experiment config for a send node. The recipient is deterministically bucketed by `bucketingKey` and routed to one of the `variants` in proportion to its `weight`. Present on a send node INSTEAD OF `message.template`.
          - `id` string — Unique experiment id (prefixed `exp_`). Omit to have one generated automatically; when supplied it must be a valid `exp_` id.
          - `name` string — Optional display name for the experiment.
          - `bucketingKey` string, required — The value used to deterministically assign a recipient to a variant. Must be non-empty with no leading or trailing whitespace.
          - `variants` JourneyExperimentVariant[], required — Between 2 and 10 weighted template variants.
            - `id` string, required
            - `name` string — Optional display name for the variant.
            - `weight` number, required — Relative routing weight. Must be non-negative.
            - `templateId` string, required — The notification template sent for this variant.
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyDelayDurationNode — Pause the journey run for a fixed `duration`.
        - `id` string
        - `type` 'delay', required
        - `mode` 'duration', required
        - `duration` string, required
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyDelayUntilNode — Pause the journey run `until` a specific time.
        - `id` string
        - `type` 'delay', required
        - `mode` 'until', required
        - `until` string, required
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyFetchGetDeleteNode — Issue an HTTP GET or DELETE request and merge the response into the journey state per `merge_strategy`.
        - `id` string
        - `type` 'fetch', required
        - `method` 'get' | 'delete', required
        - `url` string, required
        - `merge_strategy` 'overwrite' | 'soft-merge' | 'replace' | 'none', required — Strategy for merging a fetch response into the journey run state.
        - `headers` object
        - `query_params` object
        - `response_schema` object — A JSONSchema object (Draft-07-compatible). Validated at runtime by Ajv.
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyFetchPostPutNode — Issue an HTTP POST or PUT request with a `body` and merge the response into the journey state per `merge_strategy`.
        - `id` string
        - `type` 'fetch', required
        - `method` 'post' | 'put', required
        - `url` string, required
        - `merge_strategy` 'overwrite' | 'soft-merge' | 'replace' | 'none', required — Strategy for merging a fetch response into the journey run state.
        - `headers` object
        - `query_params` object
        - `response_schema` object — A JSONSchema object (Draft-07-compatible). Validated at runtime by Ajv.
        - `body` string
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyAINode — Invoke an AI step with `user_prompt` and optional `web_search`. Returns a structured response conforming to `output_schema`.
        - `id` string
        - `type` 'ai', required
        - `model` string
        - `user_prompt` string
        - `web_search` boolean
        - `output_schema` object, required — A JSONSchema object (Draft-07-compatible). Validated at runtime by Ajv.
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyThrottleStaticNode — Throttle the journey by a static `scope` (`user` or `global`), allowing at most `max_allowed` invocations per `period`.
        - `id` string
        - `type` 'throttle', required
        - `scope` 'user' | 'global', required
        - `max_allowed` integer, required
        - `period` string, required
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyThrottleDynamicNode — Throttle the journey by a dynamic `throttle_key`, allowing at most `max_allowed` invocations per `period`.
        - `id` string
        - `type` 'throttle', required
        - `scope` 'dynamic', required
        - `max_allowed` integer, required
        - `period` string, required
        - `throttle_key` string, required
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyBatchNode — Collect events arriving at the node into a single batch and fire one downstream step with the aggregated payload. The first event into a batch owns the run; later contributing events terminate at the batch step. The batch releases when any of `max_items` is reached, a quiet window of `wait_period` elapses, or the `max_wait_period` ceiling hits.
        - `id` string
        - `type` 'batch', required
        - `scope` 'user', required
        - `wait_period` string, required — ISO 8601 duration. Quiet window that releases the batch when it elapses with no new contributing events. Must be less than `max_wait_period`.
        - `max_wait_period` string, required — ISO 8601 duration. Hard ceiling from the first event into the batch; releases the batch unconditionally when it elapses.
        - `max_items` integer — Releases the batch once this many events have been collected.
        - `retain` object, required — How to select which collected events to retain in the aggregated payload when the batch releases.
          - `type` 'first' | 'last' | 'highest' | 'lowest', required
          - `count` integer, required
          - `sort_key` string — Dot-path into the event payload (e.g. `data.priority`). Required when `type` is `highest` or `lowest`.
        - `category_key` string — Optional partition key. Events with the same `category_key` are batched together; events with different values are batched separately.
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyAddToDigestNode — Add the current event to a digest keyed by the given subscription topic. The digest accumulates events and releases them on the schedule configured for the topic.
        - `id` string
        - `type` 'add-to-digest', required
        - `subscription_topic_id` string, required — The subscription topic that owns the digest the event is added to.
        - `conditions` union — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
          - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
          - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
            - `AND` JourneyConditionAtom[]
              - …
            - `OR` JourneyConditionAtom[]
              - …
          - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
            - `AND` JourneyConditionGroup[]
              - …
            - `OR` JourneyConditionGroup[]
              - …
      - JourneyExitNode — Terminate the journey run.
        - `id` string
        - `type` 'exit', required
      - object — Branch node. Routes to the first entry in `paths[]` whose `conditions` match, else falls through to `default.nodes`.
        - `id` string
        - `type` 'branch', required
        - `paths` object[], required
          - `label` string
          - `conditions` union, required — Condition spec for a journey node. Accepts a single condition atom, an AND/OR group, or an AND/OR nested group. Omit the `conditions` property entirely to express "no conditions".
            - string[] — A single condition expressed as a positional tuple of strings. - Binary form (3 elements): `[path, operator, value]` where `operator` is one of `is equal`, `is not equal`, `contains`, `does not contain`, `starts with`, `ends with`, `greater than`, `greater than or equal`, `less than`, `less than or equal`. Example: `["user.tier", "is equal", "gold"]`. - Unary form (2 elements): `[path, operator]` where `operator` is one of `exists`, `does not exist`. Example: `["user.email", "exists"]`. The first element is a non-empty dot-path. The second element is the operator (must come from one of the two operator sets above). For the binary form, the third element is the comparison value (string). Runtime validation of the operator value and arity is performed by the backend; SDKs surface this as a string list.
            - JourneyConditionGroup — A leaf condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionAtom` tuples.
              - …
            - JourneyConditionNestedGroup — A nested condition group. Exactly one of `AND` or `OR` must be present at runtime; each is a list of `JourneyConditionGroup` items.
              - …
          - `nodes` JourneyNode[], required
        - `default` object, required
          - `label` string
          - `nodes` JourneyNode[], required
  - `created` integer, nullable, required
  - `creator` string, nullable, required
  - `updated` integer, nullable, required
  - `updater` string, nullable, required
  - `published` integer, nullable, required

## Other responses

- `400` — Bad request
- `404` — Not found
- `422` — Unprocessable entity

---

[API](https://skmtc.net/trycourier/apis/courier.md) · [All operations](https://skmtc.net/trycourier/apis/courier/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/trycourier/courier/versions/04f69fbf96a5/schema)
