---
title: "Undo the last change to a content draft"
method: POST
path: "/api/v1/content-draft/{draftId}/undo"
tags: ["content-draft"]
---

# Undo the last change to a content draft

`POST /api/v1/content-draft/{draftId}/undo`

## Path parameters

- `draftId` string, uuid, required

## Request body

- ContentDraftNavigateRequestDTO
  - `baseVersion` integer, required — The record version the editor was showing when the author pressed undo or redo; 409 when the draft has moved on. The write counter, never `cursorVersion`.

## Response `201`

- ContentDraftNavigationResponseDTO
  - `canRedo` boolean, required — Whether a redo would move the draft.
  - `canUndo` boolean, required — Whether another undo would move the draft.
  - `changedSections` string[], required — Names of the top-level draft sections the move changed. Empty when the version landed on held identical content, or when nothing moved at all. The values themselves are in `draft`.
  - `cursorVersion` number, required — The version whose content the draft now shows. Differs from `version` once something has been undone.
  - `draft` EditableMissionDraft, required
    - `additional_material` object[] — Array of additional materials (e.g. links, documents) provided for the mission.
      - `relationTo` 'client-documents' | 'external-links', required
      - `value` string, required
    - `conversation_topic` MissionConversationTopic[]
    - `difficulty` 'easy' | 'medium' | 'hard', required
    - `hide_examples` boolean — Whether learners should not see desired behaviour examples for this mission.
    - `hide_scorecard` boolean — Whether learners should not see the mission scorecard.
    - `keywords` string[]
    - `language` 'de' | 'en' | 'fr' | 'es' | 'it' | 'nl' | 'zh-Hans', required
    - `persona` object, required
      - `age` number
      - `ai_instruction` string, required — [Third Person Singular][Description of Persona][Only for Persona]: Private background and behavioral instructions shown only to the Persona during the roleplay. Include attitudes, motivations, needs, challenges, objections, decision criteria, communication style, personal background, and observable quirks needed to play the role authentically.
      - `avatar_file` object
        - `age` integer, required
        - `alt` string, nullable
        - `createdAt` string, required
        - `filename` string, required
        - `filesize` number, required
        - `gender` 'male' | 'female', required
        - `height` number, required
        - `id` string, required
        - `mimeType` string, required
        - `reusable` boolean, required
        - `sizes` object
          - `card` object
            - `url` string, nullable
          - `thumbnail` object
            - `url` string, nullable
        - `updatedAt` string, required
        - `url` string, required
        - `width` number, required
      - `description` string, required
      - `gender` 'male' | 'female', required
      - `language` 'de' | 'en' | 'fr' | 'es' | 'it' | 'nl' | 'zh-Hans', required
      - `name` string, required — The name of the Persona. (e.g., Amy Johnson)
      - `role` string, required — [Conversation Role] The role the persona plays in the conversation. For B2B sales conversations, use their job title or function. If there is no workplace, use their relationship to the conversation, such as "Prospective buyer," "Existing customer," or "Private customer." For role-plays about manager skills, use their relationship to the learner, such as "Team member." This is shown to the learner and used to instruct the AI during the role-play.
      - `voice` object
        - `id` string, required
        - `voice_id` string, required
      - `workplace_description` string, nullable
      - `workplace_name` string, nullable — [Proper Noun or Descriptive Label] The name or type of the workplace/company where the persona currently works, shown to the learner. (e.g., Brisbane Cruises) Leave empty when a workplace is not relevant, including private-customer and manager-skills role-plays. Never invent a workplace just to populate this field.
    - `scenario` object, required
      - `conversation_items` object[], required — array - A list of conversation items, using conversationItems.
        - `conversation_step_instructions` string — [You][Address Persona][Imperative][Use Conditional IF THEN for Instructions][Only for Persona] Instructions, including reactions to observable events, for the Persona. Adjust the conversation flow and the Persona's reactions based on the Learner's behavior. Shown only to the Persona. The first item should instruct the Persona how to begin. The decision step should establish the outcome without ending the conversation, and the final step should explicitly end it.
        - `conversation_step_title` string, required — [Noun Phrase] OR [Address AI Persona][You][Imperative][Only for Persona]: A conversation step the Persona should follow. Formulate it as an instruction to the Persona. Only shown to the Persona. (e.g. "Answer the phone warmly", "Decide whether you agree with the learner", "Let the learner continue", "End the conversation")
      - `description` string, required — [Address Learner][You][Imperative][Only for Learner] In no more than 3 short sentences, describe the conversation type, why it is happening, and any previous interaction with the Persona. Include only facts the Learner would realistically know at the start. Do not repeat the goal or reveal private Persona information. Shown to the Learner.
      - `description_for_ai` string, required — [Address Persona][You][Only for Persona] Set the scene as a director would brief an actor immediately before the interaction. Include the current mood, preceding events, whether the interaction is planned, and relevant prior contact. Focus on what is happening, not who the Persona is. Shown only to the Persona.
      - `duration` number, required
      - `firstMessage` string
      - `firstMessageMode` 'assistant-speaks-first' | 'assistant-waits-for-user' | 'assistant-speaks-first-with-model-generated-message'
      - `goal` string, required
      - `language` 'de' | 'en' | 'fr' | 'es' | 'it' | 'nl' | 'zh-Hans', required
      - `tag` string, required
    - `scorecard` object, required
      - `items` object[], required
        - `description` string, required — [Address Coach][Imperative][You] but [Use Third Person for Learner/Persona][Indicative][Only for Coach] Concise, evidence-focused scoring instructions. State the shared context, where in the conversation to look for evidence, what happened immediately beforehand when relevant, and how strict or lenient to be. Do not repeat the Desired Behaviors.
        - `desired_behaviours` object[] — array - Typically 2 or 3, and no more than 4, Desired Behavior objects chosen to represent the ideal observable steps toward the Desired Outcome. Every object pairs exactly one `behaviour` field with exactly one corresponding `examples` field; examples for one behavior must never be placed in another behavior or in the `behaviour` field itself.
          - `behaviour` string, required — [Information for Coach and Learner][Third Person][Indicative][Descriptive] Exactly one discrete, observable verbal behavior the Learner needs to demonstrate to master this scorecard item. Start with the Learner’s actual role descriptor, such as "The seller" or "The manager"; never use the generic word "learner". This field contains only the behavior sentence and must not contain example utterances or an "Examples:" label. (e.g. "The seller asks the customer about their experience with the product." | "The manager summarizes the team member’s concern.")
          - `examples` string — string - [Direct Quotes] The one Examples field paired with this Desired Behavior. It must be non-empty and contain exactly 3 relevant example utterances that demonstrate only this behavior, formatted as 3 newline-separated list items in the exact form `- "quote"`. Include only the 3 quoted list items, with no heading, label, explanation, or behavior description. The examples should differ in wording and tone.
        - `desired_outcome` string — [Third Person][Persona][Indicative] The observable outcome the Learner is expected to achieve, expressed as a behavior shown by the Persona. Use the form "The [Persona descriptor] [does an observable action]." (e.g. "The customer agrees to a follow-up." | "The team member confirms their concern was understood.")
        - `item_title` string, required
      - `language` 'de' | 'en' | 'fr' | 'es' | 'it' | 'nl' | 'zh-Hans', required
      - `tag` string, required
      - `title` string, required — [Proper Noun] A short, descriptive title for the scorecard, shown to the coach.
    - `title` string, required
    - `toolIds` string[]
  - `draftId` string, required — The draft this move was applied to
  - `moved` boolean, required — False when there was nothing left in that direction, or when the draft was already showing the requested version. Nothing was written.
  - `summary` string, required — What happened, ready to show the author - including the reason a refused move refused.
  - `version` number, required — The write counter after the move. A move is a write, so this climbs even though the content is older. Send it as `baseVersion` on the next request.

## Changes

- **2026-09-04** `37a0dba85517` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/wejam/apis/jam/changes/api/v1/content-draft/:draftId/undo/post.md)

---

[API](https://skmtc.dev/wejam/apis/jam.md) · [All operations](https://skmtc.dev/wejam/apis/jam/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/wejam/jam/revisions/37a0dba85517/schema)
