Skip to main content
A journey is a graph of nodes that runs once per user when triggered.
An onboarding journey on the canvas: an API Invoke trigger, a welcome email, a two-day delay, an AI node, then a branch whose two paths send and rejoin at Exit
You build it visually, publish it, and invoke it from your app or a Segment event. Courier runs the nodes in order, taking branches, waiting on delays, and sending messages until the run ends. A journey combines the other pieces: a trigger that starts it, that decide what happens between sends, and content written the way a is written. Each recipient is a whose profile the run reads once at invoke.

Which one to use

Most notifications do not need a journey, and the difference is whether the messaging spans steps and time. Use the when one call can say everything. Use a journey when the messaging unfolds over time, with branching, enrichment, or rate limiting between steps.

How it works

Trigger, then nodes

Every journey starts with a trigger that decides how users enter it:
  • API: your code calls the invoke endpoint.
  • Segment: Courier starts the journey when a matching event arrives.
Nodes then run in sequence: send, delay, branch, fetch (pull external data), throttle, batch, add-to-digest, and exit. A branch splits the flow into conditional paths. The run continues until every path reaches an end.

A run works from a snapshot of its data

On invoke, Courier loads the recipient’s profile once and stores the run’s { data, profile } as a snapshot. Every node reads from that snapshot. Editing a user’s stored profile or an audience after the run starts does not re-evaluate the run or update its data. Only in-journey nodes change a run’s context mid-flight: a fetch node that pulls new data, or an update-profile step. Both merge into the stored context. Branch on data you pass at invoke or fetch during the run, not on edits made elsewhere.

Delays

A delay node waits before continuing, in two modes:
  • Duration (relative): wait a span, like 3 days.
  • Until (absolute): wait for a timestamp, which can come from your data, like an appointment_time field.
A single delay can wait up to 93 days. Courier rejects a longer delay. Chain delays for a longer total gap.

Idempotency

Invoking is safe to retry. Send an Idempotency-Key header on the invoke request. For a repeated key, Courier returns the stored result instead of starting a second run, so a network retry does not double-send. Without the key, each invoke starts a new run.

Canceling a run

There is no pause, only cancel. The cancel endpoint takes either a cancelation_token (set in the journey’s settings and stamped on each run as it starts, cancels every run sharing it) or a single run_id. Only active runs are affected. A run that already finished, errored, or was canceled is left as-is. A journey can also cancel itself with an in-journey cancel node. See .

Journey Templates

A send node’s content is a Journey Template: created inline in the send node, scoped to that Journey, and versioned with it. They are separate from the workspace used with the Send API. You cannot reference one from a regular send, or import an existing Template into a Journey. Journey Templates reference the Journey’s data with double-brace syntax:
  • {{order_id}} for a trigger schema field
  • {{first_name}} for a Profile field
  • a field from an upstream fetch node
Publishing the Journey makes each linked Template’s current draft its active version. Editing a Template after publishing creates a new draft that needs a re-publish to take effect.

Limits & behavior

  • A single delay caps at 93 days. Chain delays for a longer wait.
  • Run data is a snapshot from invoke. External profile or audience edits after the run starts are not re-read. Only in-journey fetch/update nodes change the context.
  • Cancel, do not pause. Cancel runs by token or run_id. There is no pause and resume.
  • Invoke with an Idempotency-Key to make retries safe. Without it, each call is a new run.

FAQ

Cancel active runs with the cancel endpoint by cancelation_token (cancels all runs with that token) or a single run_id. Finished runs are unaffected. There is no pause.
A run works from the snapshot taken at invoke. External changes are not re-read. Use a fetch node inside the journey to pull fresh data mid-flow.
Invoking a journey is idempotent when you make it so. Send an Idempotency-Key header and a repeated key returns the stored result instead of starting a second run.
Up to 93 days per delay node. For a longer total wait, chain multiple delays.
Journeys is the current v3 surface (visual editor, data contracts, run inspection) on the same engine as the older Automations product. Automations are superseded. Build new workflows as journeys.