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

# Create a persona

`POST /projects/{projectId}/personas`

Creates one persona. To draft several with a model first, use `POST /projects/{projectId}/personas/generate` — that route persists nothing.

## Headers

- `Idempotency-Key` string

## Request body

- PersonaCreateRequest
  - `name` string, required — 1–120 characters.
  - `role` string, required — What this person is, in the product's terms — "finance ops lead", "first-time buyer". 1–120 characters.
  - `notes` string — Free-text context the model is grounded in. Up to 2000 characters.
  - `avatarShape` integer — Index into the app's fixed shape set. Out of range is a 400 naming the field, not an upstream error about a constant you have never seen.
  - `avatarPalette` integer — Index into the app's fixed palette set.

## Response `201`

The created persona.

- Persona — A reusable synthetic character. The GOAL lives on the journey, not here — one persona can be pointed at many different tasks.
  - `id` string, required — Durable id — what journeys reference and what every route here addresses.
  - `projectId` string, required
  - `slug` string, required — Stable slug key, shared with exported session data. Useful for correlating transcripts; NOT an address for this API.
  - `name` string, required
  - `role` string, required
  - `notes` string, nullable, required
  - `source` 'manual' | 'generated' | 'cluster', required — How the persona came to exist.
  - `seedKeywords` string[] — Present on cluster-derived personas: the terms the cluster was built from.
  - `avatar` object, required — Look, as indices into the app's fixed shape/palette sets. `null` when unset — the app then derives one from the id.
    - `shape` integer, nullable, required
    - `palette` 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/7d1aff84ce3b/schema)
