---
title: "Draft journeys for a persona"
method: POST
path: "/projects/{projectId}/journeys/generate"
tags: ["Swarms"]
---

# Draft journeys for a persona

`POST /projects/{projectId}/journeys/generate`

Returns DRAFTS and persists nothing — see `POST /projects/{projectId}/personas/generate` for why, and for what this spends.

## Request body

- JourneyGenerateRequest — Exactly ONE grounding source: `serverAttachmentId` or `environmentId`. Sending both is a 400 — a request that is already confused about what it wants should not have a winner picked for it.
  - `serverAttachmentId` string
  - `environmentId` string
  - `journeyCount` integer
  - `persona` object, required — The persona to draft journeys FOR, passed BY VALUE rather than by id. Not an oversight: the create flow drafts a persona and its journeys before either exists, so requiring a persisted persona would force you to save a draft you may discard.
    - `name` string, required
    - `role` string, required
    - `notes` string
  - `description` string

## Response `200`

Draft journeys.

- GenerationDrafts — DRAFTS. Nothing here is persisted — feed what you want to keep to `POST /projects/{projectId}/personas` or `POST /projects/{projectId}/journeys`. The shape depends on the request: `POST /personas/generate` returns `{persona, journeys}` without `personaCount` and `{personas: [{persona, journeys}]}` with it; `POST /journeys/generate` returns `{journeys}`.
  - `persona` PersonaDraft — A generated persona draft. Nothing is persisted until you create it.
    - `name` string, required
    - `role` string, required
    - `notes` string
  - `personas` object[]
    - `persona` PersonaDraft — A generated persona draft. Nothing is persisted until you create it.
      - `name` string, required
      - `role` string, required
      - `notes` string
    - `journeys` JourneyDraft[]
      - `name` string
      - `goal` string, required
      - `suggestedChecks` object[] — Deterministic checks the backend suggests. Only `toolCalledAtLeastOnce` is ever suggested — it is the one kind whose validity the grounding snapshot can prove, because the tool provably exists.
        - `type` 'toolCalledAtLeastOnce', required
        - `toolName` string, required
  - `journeys` JourneyDraft[]
    - `name` string
    - `goal` string, required
    - `suggestedChecks` object[] — Deterministic checks the backend suggests. Only `toolCalledAtLeastOnce` is ever suggested — it is the one kind whose validity the grounding snapshot can prove, because the tool provably exists.
      - `type` 'toolCalledAtLeastOnce', required
      - `toolName` string, required

## 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.
- `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)
