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

# Manage Journeys with MCP

> Create, duplicate, and update Journeys from an MCP client with schema retrieval, native JSON requests, concurrency protection, and lifecycle controls.

Create and manage Journeys from your Model Context Protocol (MCP) client.

In a chat client, try a request like this:

```text theme={null}
Create a draft Journey named Welcome series in APP_NAME for SEGMENT_NAME, with a 60-second Wait step. Do not activate it.
```

Your client constructs the tool requests. The formats below are for developers who build or troubleshoot integrations.

## Prerequisites

* Connect your client through [OneSignal MCP Server](https://documentation.onesignal.com/docs/en/model-context-protocol.md#set-up-onesignal-mcp-server) with your OneSignal account.
* Use an app with the required Journey tools enabled and account permissions for the requested action.
* Get your App ID with `list_apps`. For an existing Journey, get its ID with `list_journeys`.

Journey tools require OAuth, the browser-based OneSignal sign-in flow. Tool discovery depends on MCP enablement for your app or account. Each operation also checks your OneSignal app permissions.

High-impact access means additional MCP enablement for state changes, deletion, and edits to active Journeys. It is separate from app permissions and any confirmation in your AI client.

## Structure tool requests

Pass routing IDs and request metadata as tool arguments. Put Journey fields in the object for the operation:

| Tool | Journey fields | Other required arguments |
| - | - | - |
| `create_journey_draft` | `body` | `app_id` |
| `duplicate_journey` | `overrides` (optional) | `app_id`, `source_journey_id` |
| `update_journey` | `patch` | `app_id`, `journey_id`, `concurrency_key` |
| `update_journey_node` | `patch` | `app_id`, `journey_id`, `node_id`, `concurrency_key` |

Send objects and arrays as native JSON values, not JSON-encoded strings. For example, use `"body": {"name": "Welcome"}`, not `"body": "{\"name\":\"Welcome\"}"`.

The examples below show the tool name and its `arguments`, not the complete MCP protocol request. Replace `YOUR_...` placeholders with IDs and keys from your app.

## Get the schema

Use `get_journey_schema` to retrieve the schema for the operation you plan to perform. You can reuse a schema you already retrieved for that operation.

```json theme={null}
{
  "name": "get_journey_schema",
  "arguments": {
    "app_id": "YOUR_APP_ID",
    "operation": "create"
  }
}
```

Use the returned `document` value to identify what the schema describes:

| Operation | `document` | What the schema describes |
| - | - | - |
| `create` | `body` | The Journey document to create |
| `duplicate` | `overrides` | Optional fields to apply to the copy |
| `update` | `patch` | The partial update to a Journey |
| `update_node` | `merged_node` | The complete node after applying a partial update, not the patch alone |

For `update_node`, send only changed fields in `patch`. The schema describes the resulting node, so required unchanged fields do not need to appear in the patch.

Schema retrieval describes accepted JSON structure. It does not grant permission to write or replace the checks on the write request.

The HTTP schema endpoint is public and app-independent. It requires no authentication or App ID.

The MCP tool still requires `app_id` for authoring context and an authenticated MCP connection. The schema itself does not vary by app.

See [Get Journey schema](https://documentation.onesignal.com/reference/get-journey-schema.md) for the response contract. Use the Journey API reference for field definitions and document rules.

## Create a draft

Call `create_journey_draft` with Journey fields inside `body`:

```json theme={null}
{
  "name": "create_journey_draft",
  "arguments": {
    "app_id": "YOUR_APP_ID",
    "body": {
      "name": "Welcome series",
      "audience": {
        "kind": "segment",
        "included_segment_ids": ["YOUR_SEGMENT_ID"]
      },
      "nodes": [
        { "kind": "wait", "duration_seconds": 60 }
      ]
    }
  }
}
```

Pass only `app_id` and `body` as top-level arguments. Both are required. Put all Journey fields inside `body`. The outer `app_id` selects the app.

The result is a draft, even if you supply a schedule. To check available channels before you add message steps, call `get_app_channel_availability` with `app_id`.

See [Create Journey](https://documentation.onesignal.com/reference/create-journey.md) for audience fields, step types, and local references with `client_node_id`.

## Duplicate a Journey

Call `duplicate_journey` with the source ID. Use `overrides` to change fields on the copy:

```json theme={null}
{
  "name": "duplicate_journey",
  "arguments": {
    "app_id": "YOUR_APP_ID",
    "source_journey_id": "YOUR_SOURCE_JOURNEY_ID",
    "overrides": {
      "name": "Welcome series v2"
    }
  }
}
```

The copy is a new draft. The source Journey does not change.

> [!WARNING]
>
> Goals and A/B tests are not copied.

See [Duplicate Journey](https://documentation.onesignal.com/reference/duplicate-journey.md) for inherited fields, ID remapping, and override behavior.

## Update a Journey or step

Read the Journey with `get_journey` before you update it. Copy its current `concurrency_key` unchanged into the tool arguments.

To rename a Journey, call `update_journey`:

```json theme={null}
{
  "name": "update_journey",
  "arguments": {
    "app_id": "YOUR_APP_ID",
    "journey_id": "YOUR_JOURNEY_ID",
    "concurrency_key": "YOUR_CURRENT_CONCURRENCY_KEY",
    "patch": {
      "name": "Welcome series v3"
    }
  }
}
```

To change one step, use its `id` from `get_journey` as `node_id`. For example, update an existing Wait step with `update_journey_node`:

```json theme={null}
{
  "name": "update_journey_node",
  "arguments": {
    "app_id": "YOUR_APP_ID",
    "journey_id": "YOUR_JOURNEY_ID",
    "node_id": "YOUR_WAIT_NODE_ID",
    "concurrency_key": "YOUR_CURRENT_CONCURRENCY_KEY",
    "patch": {
      "duration_seconds": 120
    }
  }
}
```

Use the new concurrency key from each successful update for your next change. Both MCP update tools require this key, even though the REST API makes it optional.

If you receive `409 journey-stale`, read the Journey again. Reassess your patch against the current Journey before another update.

Field edits support draft and scheduled Journeys. Active Journey edits require high-impact access and can affect people already in the flow. Archived and processing Journeys do not accept field edits through these tools.

See [Update Journey](https://documentation.onesignal.com/reference/update-journey.md) for merge behavior, array replacement, and [sending-step references](https://documentation.onesignal.com/reference/update-journey.md#reference-sending-steps). See [Update Journey node](https://documentation.onesignal.com/reference/update-journey-node.md) for changes to an individual step.

## Change Journey state

Use `update_journey` with a state-only patch. Send other field changes in a separate call:

```json theme={null}
{
  "name": "update_journey",
  "arguments": {
    "app_id": "YOUR_APP_ID",
    "journey_id": "YOUR_JOURNEY_ID",
    "concurrency_key": "YOUR_CURRENT_CONCURRENCY_KEY",
    "patch": {
      "state": "active"
    }
  }
}
```

Every state change requires high-impact access. The tool accepts `draft`, `scheduled`, `active`, or `archived` as the target state. OneSignal checks whether the transition is permitted.

To schedule a draft, first update `schedule.start_at` with a future UTC timestamp. Then send `{"state": "scheduled"}` in a separate patch with the returned concurrency key.

> [!WARNING]
>
> Review the audience and messages before activation, which can start customer messaging.
>
> Archiving permanently stops user progress. You cannot resume an archived Journey.

A `processing` result means activation is not yet complete. Processing Journeys reject updates, including state changes. Use `get_journey` to read the state after activation.

See [Journey states](https://documentation.onesignal.com/reference/update-journey.md#journey-states) for state requirements.

## Delete a Journey

Call `delete_journey` with `app_id` and `journey_id`. Deletion requires high-impact access. You do not need to archive the Journey first.

> [!CAUTION]
>
> Deleting a Journey permanently removes it and its associated data. Review the target Journey before you approve deletion in your client.

See [Delete Journey](https://documentation.onesignal.com/reference/delete-journey.md) for the deletion contract.

## Handle failed or uncertain writes

Read the result before you decide whether to send another write. MCP makes one attempt for each Journey write and does not automatically retry it.

* **Validation error:** Correct the reported fields before another attempt.
* **Stale concurrency key:** Read the Journey again and reassess the change.
* **Server error (5xx), unknown outcome, timeout, or malformed success:** Read the saved Journey before another attempt. The write can succeed even if the client receives no usable receipt.
* **Uncertain create or duplicate:** Use `list_journeys` to find the draft, then inspect it with `get_journey`. Repeating the call can create another draft.

Successful create, duplicate, and update calls return a compact receipt, not the full graph. Use `get_journey` to inspect the saved structure.

## FAQ

### Can I pass a REST request body directly as tool arguments?

No. Use the object for the tool: `body` for create, `overrides` for duplicate, or `patch` for updates. Keep routing IDs and the concurrency key outside that object. Create calls require both `app_id` and `body`; flat Journey fields are not accepted.

### Do I need to include every field when I update a step?

No. Send only changed fields in `patch`. For `update_node`, the returned schema describes the complete node after the patch, not the partial patch itself.

### Why is a Journey tool missing from my client?

Tool discovery depends on MCP enablement for your app or account. Connect through the hosted OAuth endpoint. Each operation also requires the relevant OneSignal app permissions. See [MCP troubleshooting](https://documentation.onesignal.com/docs/en/model-context-protocol.md#troubleshooting).

## Related pages

> [card] [OneSignal MCP Server](https://documentation.onesignal.com/docs/en/model-context-protocol.md)
>
> Connect your AI client and explore the available tools.

> [card] [Get Journey schema](https://documentation.onesignal.com/reference/get-journey-schema.md)
>
> Retrieve the schema for a Journey authoring operation.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.