---
title: "Create a journey"
method: POST
path: "/projects/{projectId}/journeys"
tags: ["Swarms"]
---

# Create a journey

`POST /projects/{projectId}/journeys`

Creates one journey: a persona pursuing a `goal` against one or more environments. To draft several with a model first, use `POST /projects/{projectId}/journeys/generate` — that route persists nothing.

`personaId` and `swarmId` must belong to THIS project. Naming one from another project is a `404`, not a silent cross-project reference.

Creating a journey does not run it. Launch it with `POST /projects/{projectId}/journeys/{journeyId}/runs`.

## Headers

- `Idempotency-Key` string

## Request body

- JourneyCreateRequest
  - `name` string
  - `goal` string, required — 1–4000 characters.
  - `personaId` string, required — An existing persona in this project.
  - `swarmId` string — Authoring provenance only — which swarm container this was made in.
  - `environmentIds` string[] — The environments to fan out across. NON-EMPTY when present: `[]` reads as "these, naming none", and would silently fall back to something else.
  - `serverAttachmentId` string — Legacy host-pinned grounding.
  - `hostIds` string[]
  - `sessionsPerTarget` integer, required
  - `maxTurns` integer, required

## Response `201`

The created journey.

- Journey — A persona's task: what they are trying to accomplish, and across which targets. Launching one is `POST /projects/{projectId}/journeys/{journeyId}/runs`.
  - `id` string, required
  - `projectId` string, required
  - `name` string, required
  - `goal` string, required — What the persona is trying to accomplish. This drives the whole run.
  - `personaId` string, required
  - `swarmId` string, nullable, required — The swarm container this journey was authored under. Provenance only — nothing resolves through it at run time, and a journey created outside a swarm has none.
  - `environmentIds` string[], required — Environments this journey fans out across. EMPTY on a host-pinned journey — that is a different execution model, not a journey with no targets.
  - `serverAttachmentId` string — Legacy host-pinned grounding. Absent on an environment-based journey.
  - `sessionsPerTarget` integer, nullable, required — Sessions run against EACH target. Total sessions = targets × this.
  - `maxTurns` integer, nullable, required
  - `createdAt` number, required — Epoch milliseconds.
  - `updatedAt` number, required — Epoch milliseconds.

## Other responses

- `400` — Malformed body or parameters.
- `401` — Missing, invalid, revoked, or orphaned key (`UNAUTHORIZED`) — or the **target MCP server** needs an OAuth grant (`OAUTH_REQUIRED`), which is a property of the server, not your key.
- `403` — Key is valid but not allowed to do this.
- `404` — Unknown project, server, or resource.
- `409` — The resource is not in a state that accepts this write — a stale `expectedRevision`, a duplicate name, or an environment that cannot currently be launched. The request was well-formed; re-read the resource and retry.
- `429` — Per-key rate limit exceeded (60 requests/minute sustained, bursts up to 10). Honor `Retry-After` and back off with jitter.
- `500` — Something failed on MCPJam's side.

---

[API](https://skmtc.net/mcpjam/apis/mcpjam-api.md) · [All operations](https://skmtc.net/mcpjam/apis/mcpjam-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/mcpjam/mcpjam-api/revisions/d3adfe49fbbf/schema)
