---
title: persona_update
description: Change the sections, the age range or the slug of a persona. The revision that the agent read stops it from overwriting a change that it did not see.
---

Ask for a change to a persona. The agent changes only the parts that you name.

> "The Loyalists say 'my daily trainer'. Add that to their language."

The agent reads the persona with [`persona_get`](/mcp/tools/persona-get), and then calls `persona_update`. You then see the new language, and the other sections as they were.

The job guide [Describe a brand](/mcp/tools/describe-a-brand) shows each step of the job.

## Reference

Update a persona. Pass base_revision (from persona_get) — the update is rejected if the persona changed since you read it. Only the fields you pass are changed; pass null for a section or age bound to clear it. Optionally rename the slug handle.

### Input

| Argument | Type | Required | Description |
| --- | --- | --- | --- |
| `age_max` | integer, 0 to 120 or null | no | New upper age bound. Pass null to clear it ("and older"). |
| `age_min` | integer, 0 to 120 or null | no | New lower age bound. Pass null to clear it ("and younger"). |
| `base_revision` | integer | yes | The revision you last read via persona_get. Guards against overwriting a concurrent edit. |
| `brand_name` | string | yes | The slug of the brand that owns the persona. |
| `description` | string | no | New one-line summary. |
| `frictions` | string or null | no | New objections and barriers. Pass null to clear the section. |
| `language` | string or null | no | New voice-of-customer wording — the audience's own words, not a locale. Pass null to clear the section. |
| `motivations` | string or null | no | New jobs, triggers and outcomes. Pass null to clear the section. |
| `name` | string | no | New display name. |
| `persona_name` | string | yes | The current persona slug identifying which to update. |
| `profile` | string or null | no | New description of who they are. Pass null to clear the section. |
| `slug` | string | no | Optional new slug handle (a deliberate rename); normalized to kebab-case. Callers of the old handle must be updated. |

### Output

A successful call returns this object in `structuredContent`.

| Field | Type | Always present | Description |
| --- | --- | --- | --- |
| `persona` | object | yes | The persona in full. |
| `persona.ageMax` | integer, 0 to 120 or null | yes | The highest age of the audience. `null` when the range has no upper bound. |
| `persona.ageMin` | integer, 0 to 120 or null | yes | The lowest age of the audience. `null` when the range has no lower bound. |
| `persona.brandId` | string | yes | The brand that owns the persona (`brd_…`). |
| `persona.createdAt` | number | yes | Milliseconds since the Unix epoch, in UTC. |
| `persona.createdBy` | string | yes | The user who created the record (`usr_…`). |
| `persona.description` | string | yes | One line about the persona. An agent picks a persona on it. |
| `persona.frictions` | string or null | yes | What stops the audience: objections, doubts, perceived risk. Markdown. `null` when the section is not written. |
| `persona.id` | string | yes | The id of the persona (`psn_…`). |
| `persona.language` | string or null | yes | The words that the audience uses for the problem. It is not a locale. Markdown. `null` when the section is not written. |
| `persona.motivations` | string or null | yes | What the audience wants: jobs to be done, triggers, outcomes. Markdown. `null` when the section is not written. |
| `persona.name` | string | yes | The display name. |
| `persona.profile` | string or null | yes | Who the audience is: life stage, situation, role. Markdown. `null` when the section is not written. |
| `persona.revision` | number | yes | The version of the record. Each change adds 1. Send it as `base_revision` to update or delete the record. |
| `persona.slug` | string | yes | The handle of the persona. It is unique in its brand, not in the organization. The tools take it as `persona_name`. |
| `persona.updatedAt` | number or null | yes | Milliseconds since the Unix epoch, in UTC. `null` until the first change. |

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

### Example

The arguments:

```json
{
  "base_revision": 1,
  "brand_name": "acme",
  "language": "They say \"my daily trainer\" and \"I got 900 out of the last pair\". They ask about the drop and the stack, never about the technology.",
  "motivations": "They want the same shoe again, and proof that it is the same. A resole keeps them running on a pair they trust.",
  "persona_name": "loyalists",
  "profile": "Runners of 40 to 80 kilometres a week, ten years in, with one pair in rotation and one on the shelf."
}
```

The result, in `structuredContent`:

```json
{
  "persona": {
    "ageMax": 45,
    "ageMin": 28,
    "brandId": "brd_6a9c33",
    "createdAt": 1790000000000,
    "createdBy": "usr_4d8b12",
    "description": "Runners who already own a pair, and who buy the next one without looking at another brand.",
    "frictions": "They fear the new model is worse than the one they know. A change of sole or of last reads to them as a risk, not as progress.",
    "language": "They say \"my daily trainer\" and \"I got 900 out of the last pair\". They ask about the drop and the stack, never about the technology.",
    "motivations": "They want the same shoe again, and proof that it is the same. A resole keeps them running on a pair they trust.",
    "profile": "Runners of 40 to 80 kilometres a week, ten years in, with one pair in rotation and one on the shelf.",
    "id": "psn_8c4a20",
    "name": "Loyalists",
    "revision": 2,
    "slug": "loyalists",
    "updatedAt": 1790086400000
  }
}
```
