Skip to main content
PATCH
Update journey node
Beta. The Journeys API is in beta. Endpoints and response fields can still change.

Overview

Update a single node within an existing Journey. The request is a JSON Merge Patch (RFC 7396): send only the node fields you want to change, and the rest of the node, along with the rest of the journey graph, is left unchanged.
Prefer this endpoint over Update journey when you only need to change one node. The journey-level PATCH replaces the entire nodes array wholesale, so it requires re-sending every node with its id. This endpoint touches just the addressed node and preserves in-flight users on the others.

How to use this API

Authenticate with your App API Key. The authenticated key must have permission to update journeys. Find the journey id and the node id from a prior View journey fetch. Send only the fields to change. Node fields follow the same schema and validation as Create journey. For example, to shorten a wait node’s delay:

Merge patch behavior

The request body is merged onto the addressed node:
  • A field you send replaces the current value. Omitted fields are untouched.
  • A null value clears a nullable field. Send "expiration": null on a wait_until node to wait indefinitely.
  • Arrays are replaced as a unit. branches and windows are not merged element-wise. Send the full array you want.
  • A node’s kind and its server-assigned id cannot be changed. A node keeps its kind for the life of its id, so changing the kind is rejected (send_push, send_email, and send_sms count as different kinds).

Optimistic concurrency

To avoid overwriting a concurrent change, pass the concurrency_key returned by a prior View journey fetch. If the journey has changed since that fetch, the request is rejected with 409 journey-stale and nothing is written. Omit concurrency_key to skip the check. The key covers the whole journey, not just the addressed node, so a concurrent edit to any part of the journey rejects the request. concurrency_key is not merged onto the node.
Treat concurrency_key as an opaque token: read it from the journey you are editing and send it back unchanged. Do not construct, parse, or compare it yourself.

Editing an active journey

The same active-journey rules as Update journey apply. An edit that would strand in-flight users (for example, changing a branching node’s branches) returns 400 with a field-level error.

Response

A successful request returns 200 OK with the full updated journey, including server-assigned id fields and a concurrency_key. Pass that concurrency_key unchanged on a later update to avoid overwriting a concurrent change.

Error responses

Coded errors use the shape { "errors": [{ "code", "title", "meta" }] }. For validation errors the failing field is in meta.attribute. Schema failures on this endpoint are reported against the merged journey, so the offending property is identified in the message by its position in the full graph, such as #/nodes/1/bogus.

Headers

Authorization
string
default:Key YOUR_APP_API_KEY
required

Your App API key with prefix Key. See Keys & IDs.

Content-Type
string
default:application/json; charset=utf-8
required

Path Parameters

app_id
string
default:YOUR_APP_ID
required

Your OneSignal App ID in UUID v4 format. See Keys & IDs.

id
string
default:YOUR_JOURNEY_ID
required

UUID of the journey that owns the node.

node_id
string
default:YOUR_NODE_ID
required

Server-assigned UUID of the node to update, from a prior View journey fetch.

Body

application/json

Node fields to change, merged onto the current node. The node's kind and id cannot be changed. Send null to clear a nullable field.

concurrency_key
string | null

Optional optimistic-concurrency token. Pass the concurrency_key from a prior fetch to reject the update with 409 if the journey changed in the meantime. Omit to skip the check. It is not merged onto the node.

Response

200

Full journey representation returned by the detail and create endpoints.

id
string

Journey UUID. Read-only.

app_id
string

UUID of the app the journey belongs to. Read-only.

name
string

Journey name, up to 300 characters.

description
string | null

Journey description, up to 1024 characters. Defaults to an empty string.

state
enum<string>

Journey state. Read-only. New journeys are created as draft. processing is a transient state while an activation is in progress, and archived is a journey that has been stopped. Change it through the state field on Update journey.

Available options:
draft,
scheduled,
processing,
active,
archived
created_at
string

ISO 8601 creation time. Read-only.

updated_at
string

ISO 8601 last-update time. Read-only.

started_at
string | null

ISO 8601 time the journey was activated, or null. Read-only. May stay null briefly after you set state to active: activation is enqueued for processing, and started_at populates once the journey finishes processing and becomes active.

archived_at
string | null

ISO 8601 time the journey was archived, or null. Read-only.

created_source
string | null

Origin of the journey, for example public_api or dashboard. Read-only.

audience
segment · object

The journey entry audience. Either a segment-based or event-triggered audience.

early_exit
object | null

Conditions that remove a user from the journey before it completes. At least one rule must be set under rules; an early_exit that configures no rule is rejected. Send null to remove early exit entirely, or null for an individual rule to drop just that rule.

reentry_rules
object | null

Controls whether and how soon a user can re-enter the journey. null means re-entry is not allowed.

schedule
object | null

Optional future start and/or stop time. null means no scheduled activation.

nodes
object[]

Ordered list of journey nodes.

A journey node. The kind field selects the shape. Branching nodes (split_range, yes_no, wait_until) nest their sub-graphs inline via branches[].nodes.

concurrency_key
string

Opaque optimistic-concurrency token. Read-only. Pass it back on update to guard against overwriting a concurrent change (409 journey-stale). Send it back exactly as read from this response; do not construct or parse it.