pex

Adaptive Journeys

Adaptive Journeys are self-optimizing lifecycle journeys. They're a leg of the Apex Loop — the place where everything you know about your customers (from segments and beliefs) gets composed into a sequence of nudges, branches, and decisions that learn over time.

A journey is a directed graph of steps:

  • Trigger — the entry condition (an event, a schedule, or audience entry)
  • Wait — a duration or "until-event" pause
  • Branch — a routing decision; either conditional (rules-based) or adaptive (Thompson-sampled)
  • Send — a communication fire over email, in-app, or push
  • Experiment — a content A/B/n test: send one of N competing creatives (control + variants) per subject and let science pick the winner
  • Webhook — an outbound call to your own systems
  • Exit — the journey terminates

Each step has a stable ID and routes to a next step. Branches fan out; an Experiment step converges (every arm continues to the same next); everything else is linear.

Experiment steps

An Experiment step is a journey-native A/B/n test. Unlike a Branch (which routes users down different journeys), an Experiment sends different versions of the same message and everyone continues down the same path:

  • Choose what to test: Content (compare message variants on the same channels) or Channels (compare delivery channels for one fixed creative). The factorial "both at once" mode is on the roadmap.
  • Pick the communication to test. In Content mode its variants — authored side-by-side in the communication composer columns (Control is the base content; click Variant to add alternatives) — become the arms. In Channels mode each selected channel is an arm, and only subjects reachable on every channel are measured (others still receive the message on a channel they can get).
  • On publish, the communication is frozen to its current version (the immutable treatment) and the experiment starts. It is locked for edits while it runs — a treatment must not change mid-test. (A plain Send delivers Control only; if a communication has variants, a Send is blocked at publish and you're steered to an Experiment step.)
  • The winner is judged on a goal event (a downstream conversion, not opens/clicks), with a confidence-first readiness gate: a winner is "decisive" only when probability-to-be-best ≥ 95% AND a minimum sample per arm AND a minimum runtime are all met. Small tests aren't blocked — they report "collecting" or honestly "inconclusive."
  • Promotion is manual (you approve) or automatic. Promoting writes the winner's content into the canonical communication as a new version and archives the losers.
  • An optional holdout (marketing only) withholds a sticky percentage as a no-send baseline to measure absolute lift.

Why "Adaptive"

Static drip campaigns ship a sequence and hope. Adaptive Journeys ship a sequence AND learn what's working — automatically routing more users through the variants that are converting, while keeping the global holdout untouched as the control.

You don't decide when arm B "wins" over arm A. The Experiment step does, by tracking each arm's posterior conversion rate on the goal event and reporting a confidence-first readiness verdict. (Branches now route only — the legacy "Adaptive Branch" experiment mode is retired in favor of the dedicated Experiment step.)

How journeys differ from communications

CommunicationAdaptive Journey
ShapeA single messageA graph of steps
When it firesManual or via trigger eventTriggered + walked over time
OptimizationVariants within the message (subject lines, copy)Branches between strategies (which message, which path, when)
StorageTenantCommunicationAdaptiveJourney (versioned)

A Send step in a journey references an existing communication — you don't re-author copy inside the journey. Edit the comm, and it stays connected. Publish the journey, and the Send step pins the comm version so in-flight users keep using the version that was current at journey publish time.

Versioning

Journeys are versioned the same way communications are. Each publish creates an immutable v<n> record; the latest pointer advances atomically. In-flight executions stay on the version they started; new executions pick up the latest.

This means you can edit a published journey freely — your changes live in the draft until you re-publish. The two-version-history (draft + latest) keeps the editor's mental model simple.

Subjects

Phase 1 ships end-user subjects only. Affiliate-subject journeys (where the journey runs against an affiliate, not an end-user) are reserved for Phase 2 alongside the Partner Network expansion.

The runtime is tested against end-user identity resolution, end-user preferences, and end-user comm channels (email + in-app + mobile push). Schedule and audience-entry triggers run on a 1-minute EventBridge tick — schedule fires when the cron matches, audience-entry fires on the cohort transition (out → in).

What you author vs. what's automatic

You decide:

  • The shape of the graph (what steps in what order)
  • Which communication each Send step uses
  • Which event triggers entry
  • The optimization goal for each Adaptive Branch (e.g. "subscription.created within 7 days")
  • The audience (which subset of end-users is eligible)

The journey decides automatically:

  • Which arm of an Adaptive Branch each user gets (cold-start round-robin → Thompson sampling)
  • Whether each Send is allowed (eligibility contract: opt-out, suppression, frequency cap, holdout)
  • When to retire a losing arm (it stops being sampled once posteriors stabilize)
  • How to attribute outcomes to arms (within the configured attribution window, censoring stopped/failed runs)