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

# Campaign journey pipeline: enroll to funnel measurement

> The pipeline a campaign journey runs every enrolled contact through — enrollment sources, per-recipient personalization, channel selection, frequency-cap and quiet-hour gates, and the funnel metrics that close the loop for blast, drip, and journey campaigns.

# Campaign journey pipeline

The [campaign lifecycle](/concepts/campaign-lifecycle) page frames a campaign as one object with a status machine; the [journey enrollment fan-out](/concepts/journey-enrollment-fan-out) page details who gets in. This page covers what happens in between — the pipeline every enrolled contact moves through, from enrollment to measured funnel outcome, and the surfaces where you build and operate it: the journey builder at `/campaigns/journey` and the campaign execution view at `/campaigns/:id`.

The same pipeline shape holds for all three modes — a fixed-set audience (blast and drip) enters in batch, a streamed audience (journey) enters one contact at a time — and from that point on the stages are identical: personalize, pick the channel, pass the gate, measure.

## Dashboard anatomy: builder vs execution

Two dashboard surfaces share one campaign id:

* **`/campaigns/journey` — the builder.** A visual canvas for the journey graph: a node palette (trigger, send, wait, branch, goal, exit), a graph validator that rejects cycles and unreachable nodes, a template picker, a dry-run simulator, and a goal-attachment panel. Everything you build here persists into the campaign's journey definition; launching it is still the standard campaign launch.
* **`/campaigns/:id` — the execution view.** Recipients and per-step analytics, the attribution funnel panel, holdout and lift panels, A/B results, link analytics, and the pause/resume controls. For a journey campaign, this is also where the per-node funnel overlay reads its numbers from.

The builder answers "what does the graph do"; the execution view answers "what did it do". Both bind to the same `cmp_` id, so clone, enroll, and analytics endpoints stay pointed at one campaign.

## Pipeline stages

Every enrolled contact, however they entered, moves through the same five stages:

**1. Enroll** — entry into the audience. For a blast or drip, the whole audience resolves once at launch (a list, a segment, a filter, or all contacts). For a journey, enrollment is continuous and per-contact: inbound-reply keyword, segment entry/exit, CDP-track event, a rollout, or the single-contact enrollment endpoint behind the contact-360 enroll action. Every source funnels into the same guarded entry chain — offboard precheck, active-enrollment guard, re-entry policy, entry rate limit — detailed in [journey enrollment fan-out](/concepts/journey-enrollment-fan-out).

**2. Personalize** — the template's per-recipient variables resolve against the contact record (`{{first_name}}` and your custom fields), so one template renders a concrete message per contact. Channel branches in a journey graph — `channelPreferenceBranch`, `smartChannel` — pick the send channel from the contact's preferences or engagement signal at this point, so the channel decision rides on the resolved profile.

**3. Channel** — the send dispatches over whatever channels the graph or campaign configuration picked: SMS, WhatsApp, email, voice, or the others your channels support. In a drip, each step carries its own channel; a journey graph has one send node per edge. Omnichannel fallback chains let one send attempt advance to a secondary channel when the primary fails to deliver.

**4. Gate** — the scheduling and safety gates all hold on the send path, tenant-owned and tenant-configured: the campaign's throttle pace, quiet-hours windows in the recipient's local timezone, frequency caps, send-time optimization (`fixed` or `recipient-optimal`), and the credit-cap governor. A gate defers or persists first — a contact in a quiet-hours window parks rather than failing — so gate outcomes show up in the funnel as a delay, not a drop.

**5. Measure** — outcomes persist per contact as they happen: sends, deliveries, link clicks, journey goal conversions, and terminal enrollment statuses. The funnel stage below is a read over those records, computed when you ask, not a batch job you wait on.

The stages are per-contact, so in a journey you see all five in flight at once — one contact is enrolling while another waits at a gate and a third converts against the goal.

## Funnel metrics surface

Measurement in this pipeline is funnel-shaped: a counted base that progressively narrows through each next step.

* **Per-node contact funnel** — `GET /campaigns/:id/journey/node-analytics` returns, for every node in the journey graph, the distinct contacts that entered it, completed it end-to-end, dropped out of it, and are currently parked at it. The builder overlays this on the canvas, so a node shows its own enter/convert counts. Zero-fills nodes with no activity yet, so the graph always renders every node.
* **Attribution funnel** — `GET /campaigns/:id/attribution-funnel` answers "how many contacts moved through, and what is that worth": touched (contacts the campaign sent at least one message to), clicked (touched contacts who clicked a tracked short link), converted (touched contacts who fired the campaign's journey goal), and ordered (the converted subset whose conversion links to a commerce order), with per-stage drop-off rates and the converted cohort's gross purchase value, send spend, and ROAS. It is deliberately allocation-model-free — the ROAS counterpart across contributing campaigns lives at `GET /campaigns/:id/roas`.
* **Message-level delivery stats** — `GET /campaigns/:id/journey-analytics` reports per-node total/delivered/failed message rows, complementing the contact-level funnel when you need to know *why* a node lost contacts.

For the message statuses dripping under these counts, see [delivery lifecycle](/concepts/delivery-lifecycle).

## API surface

Pipeline-interaction endpoints most integrations care about:

| Endpoint                                    | Role in the pipeline                                                                                                                                             |
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `POST /campaigns`                           | Create the campaign — fixed-set (`type: blast` or `drip`) with its audience, or streamed (`type: journey`) holding the graph definition                          |
| `POST /campaigns/:id/send`                  | Launch it; for a journey this opens continuous enrollment                                                                                                        |
| `POST /campaigns/:id/enroll-contact`        | Enroll a single contact mid-flight (powers the contact-360 enroll action; journey and drip campaigns only — a blast refuses with `CAMPAIGN_TYPE_NOT_ENROLLABLE`) |
| `POST /campaigns/:id/enroll-segment`        | Enroll a segment's members through the same guarded entry chain                                                                                                  |
| `GET /campaigns/:id/journey/node-analytics` | Per-node contact funnel (entered / completed / dropped / currently-at)                                                                                           |
| `GET /campaigns/:id/attribution-funnel`     | Funnel stage counts, drop-offs, and money over the converted cohort                                                                                              |
| `GET /campaigns/:id/journey-analytics`      | Per-node message delivery stats                                                                                                                                  |
| `GET /campaigns/:id`                        | Campaign state, stats, and the journey/execution detail the dashboard views read                                                                                 |

Guides walk these calls end to end: [build a journey in the canvas](/guides/campaign-journey-builder) and [send a campaign end-to-end](/guides/campaign-end-to-end). The [campaigns API reference](/api-reference/endpoints/campaigns) is the payload contract.
