---
title: persona_create
description: Add an audience archetype to a brand — who it is talking to — with as much or as little written up front as you have.
---

Creates a **Persona** on a Brand: an audience archetype describing who the brand is talking _to_.

Everything except `name` and `description` is optional. A persona is authored incrementally — creating one with nothing but a name is a valid starting point, and sections get filled in as you learn them.

## Input

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `brand_name` | `string` | yes | The slug of the brand this persona belongs to. |
| `name` | `string` | yes | Display name, e.g. `"Time-poor Parent"`. |
| `description` | `string` | yes | One-line summary used to pick this persona from a list. |
| `slug` | `string` | no | Explicit handle; normalized to kebab-case. Defaults to one derived from the name. |
| `profile` | `string` | no | Who they are: life stage, situation, role, context. |
| `motivations` | `string` | no | What they want: jobs to be done, triggers, outcomes. |
| `frictions` | `string` | no | What stops them: objections, doubts, perceived risk. |
| `language` | `string` | no | The words **they** use for the problem — not a locale. |
| `age_min` | `integer` | no | Lower age bound. Omit for "and younger". |
| `age_max` | `integer` | no | Upper age bound. Omit for "and older". |

## Example

```ts
persona_create({
  brand_name: 'acme-running',
  name: 'Marathon Maya',
  description: 'Trains before work, races twice a year.',
  age_min: 30,
  age_max: 44,
  frictions: 'Thinks carbon plates are a gimmick sold on hype.',
});
// → { persona: { slug: 'marathon-maya', revision: 1, … } }
```

:::info[The slug is unique per brand, not per organization]

Two brands may each have a `loyalists`. That is why every persona tool takes `brand_name` alongside `persona_name` — the pair is the handle. A collision _within_ one brand returns an error rather than silently adding a suffix.

:::

:::tip[Age is the only structured field]

Everything else is prose, deliberately. Location, interests and job titles are written into `profile` rather than typed, because they resolve differently on every ad platform — a persona describes an audience, it is not a targeting spec. Both age bounds are independently optional, so `age_min: 35` on its own means "35 and older".

:::

Requires the `brand:write` scope.

## Reference

Create a persona on a brand — an audience archetype describing who the brand talks to (not the voice it speaks in, which is the brand's own 'voice' section). Every section and both age bounds are optional; a persona is authored incrementally. The slug is unique within the brand, so two brands may each have a 'loyalists'.

### Input

| Argument | Type | Required | Description |
| --- | --- | --- | --- |
| `age_max` | integer, 0 to 120 | no | Upper age bound. Omit for "and older". |
| `age_min` | integer, 0 to 120 | no | Lower age bound. Omit for "and younger". |
| `brand_name` | string | yes | The slug of the brand this persona belongs to. |
| `description` | string | yes | One-line summary used to pick this persona from a list. |
| `frictions` | string | no | What stops them: objections, doubts, perceived risk, inertia. |
| `language` | string | no | The words the audience itself uses for the problem — verbatims and vocabulary, in their own register. This is not a locale. |
| `motivations` | string | no | What they want: jobs to be done, triggers, the outcome they picture. |
| `name` | string | yes | Display name, e.g. "Time-poor Parent". |
| `profile` | string | no | Who they are: life stage, situation, role, context. |
| `slug` | string | no | Optional explicit slug handle; normalized to kebab-case. Defaults to one derived from the name. |

### Failure codes

A failed call has `isError` set, and `structuredContent.error` holds one of these codes. [Errors](/mcp/errors) describes the shape of a failed call.

- `not_found`
- `invalid_slug`
- `invalid_age_range`
- `slug_conflict`
- `forbidden`
- `invalid_request`
- `internal_error`

### Scope

The token must hold `brand:write`. [Auth & scopes](/mcp/auth) lists each scope.

### Annotations

A client reads these hints. A hint that the tool does not declare has the default value of the MCP specification.

- **Writes.** The tool can change data.
- **Destructive.** The tool can make a change that you cannot undo. A client can ask you to confirm before it calls the tool.
- **Not idempotent.** A second call with the same arguments can change more.
- **Closed world.** The tool reads and writes the data of AdCrunch only.
