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

> ## Agent Instructions
> Install the Courier skill before writing code: `npx skills add trycourier/courier-skills`. It carries the verified SDK shapes and the rules you cannot get wrong.
> Authenticate every request with `Authorization: Bearer <API_KEY>`. A workspace has several environments and each has its own keys, which are plain `pk_` strings with no environment prefix. Start with Test.
> Send with `client.send.message`, the default import of the v7 Node SDK. Reference a template by its `nt_` id or its alias.
> A send accepts a bare Elemental element list, but storing content on a template requires the top-level elements wrapped in a channel element.
> Templates and journeys can be built in the Courier app or created through the API. Either way they live in the workspace and are referenced by ID when you send.
> The hosted MCP server is https://mcp.courier.com. For a briefing on what Courier is and when to use it, read https://www.courier.com/llms.txt.
> Prefer the Guides tab for how-do-I questions and the Docs tab for how-does-it-behave questions. The API reference lives under /api-reference.

# Journey cancel node

> Stop in-flight runs from inside a journey, or a group of runs sharing a cancellation token.

export const AppLink = ({href, children, name, bare}) => {
  const label = children || name || "Open in Courier";
  if (bare) {
    return <a href={href} target="_blank" rel="noreferrer">{label}</a>;
  }
  return <a className="cx-endpoint" data-kind="app" href={href} target="_blank" rel="noreferrer">
      <span className="cx-endpoint-label">{label}</span>
      <span className="cx-endpoint-method" aria-hidden="true">↗</span>
    </a>;
};

export const Doc = ({href, children, name, bare}) => {
  const label = children || name || href;
  if (bare) {
    return <a href={href}>{label}</a>;
  }
  return <a className="cx-endpoint" data-kind="doc" href={href}>
      <span className="cx-endpoint-label">{label}</span>
      <span className="cx-endpoint-method">DOC</span>
    </a>;
};

The Cancel node stops in-flight journey runs from inside a flow. You can also cancel from your own code with the cancel API, so a Cancel node is not required to stop a run.

Either way, you target runs one of two ways: a single run by its `run_id`, or a group of runs by a shared **cancellation token**. Courier cancels only **active** runs. Canceling is idempotent, so a run that has already finished or errored is left untouched.

To cancel from your own code, call the cancel endpoint with either key. See <Doc href="/docs/journeys/invoke#cancel-a-run">invoke a journey</Doc> for the request and its response statuses.

## Cancel a group with a cancellation token

A cancellation token is an addressing key you attach to runs. Cancel a whole set by a business identifier, without tracking individual run IDs. How you build the token decides what it covers:

* `order-{{data.order_id}}` cancels the runs for one order
* `user-{{profile.id}}` cancels every run for a user, even across different journeys
* `black-friday-2026` cancels an entire campaign

Set the token in the journey's **settings**. It's templated, so you build it from run data with `{{data.…}}`, `{{profile.…}}`, or `{{recipient}}`. Use a dynamic value so the token maps to the runs you mean, not every run of the journey.

**A token that references a missing variable is dropped, not rejected.** The run is created without one, so it is uncancelable by token while still looking correctly configured. Cancel it by run ID instead.

Once runs are tagged, cancel the token two ways:

* **From your code**: <Doc href="/docs/journeys/invoke#cancel-a-run">cancel by token</Doc>. The field is `cancelation_token`, spelled with one L.
* **From a Cancel node**: add a **Cancel** node and set its **Cancelation Token**. When a run reaches the node, Courier cancels every active run sharing that token. This is how one path cancels another: an "invoice paid" branch routes to a Cancel node set to `invoice-{{data.invoice_id}}`, stopping that invoice's remaining reminders.
