# Work with tracked changes

> Create reviewable edits, inspect open changes, and accept or reject an explicit change.



Tracked changes connect programmatic editing to human review. Operations that report tracked-mode support can request it. The review API then lists, inspects, accepts, or rejects the resulting logical changes.

## Create a reviewable edit [#create-a-reviewable-edit]

Pass `changeMode: 'tracked'` as the mutation options argument. There is no separate operation for creating a tracked change:

```ts
const result = await doc.query.match({
  select: { type: 'text', pattern: 'Amazing' },
  require: 'exactlyOne',
});
const match = result.items[0];

if (!match || match.matchKind !== 'text') {
  throw new Error('The company name was not found.');
}

const receipt = await doc.replace(
  { target: match.target, text: 'Northstar' },
  { changeMode: 'tracked', expectedRevision: result.evaluatedRevision },
);

if (!receipt.success) {
  throw new Error(receipt.failure?.message ?? 'The tracked replacement failed.');
}
```

The replacement remains open for review. Saving the DOCX preserves that review state until a person or programmatic workflow accepts or rejects it.

## Review the result in the Editor [#review-the-result-in-the-editor]

The Editor owns document rendering, selection, and human review controls. Follow [Review tracked changes](/editor/track-changes) to open the sample DOCX and accept or reject a proposal visually.

The underlying tracked-change operations remain the same in Editor and Headless hosts.

## List and inspect changes [#list-and-inspect-changes]

`trackChanges.list()` returns a compact, paginated result. Call `trackChanges.get()` when the workflow needs full before/after details for one logical change:

```ts
const changes = await doc.trackChanges.list({ limit: 20, offset: 0 });
const change = changes.items[0];

if (!change) {
  throw new Error('The document has no open tracked changes.');
}

const detail = await doc.trackChanges.get({ id: change.id });

console.log({
  id: detail.id,
  type: detail.type,
  author: detail.author,
  before: detail.before,
  after: detail.after,
});
```

The list searches the document body by default. Pass `in: 'all'` when the workflow must include supported headers, footers, footnotes, and endnotes.

## Read final, original, or redline output [#read-final-original-or-redline-output]

Use `projectHtml()` or `projectMarkdown()` when a workflow needs a serialized review view rather than the tracked-change
catalog. `final` emits accepted-side content, `original` emits the before-side, and `redline` identifies representable
before/after content with the same logical change IDs returned here. The view applies to structural paragraph, list, and
table changes as well as inline text. Moves distinguish source and destination; formatting-only changes emit one content
copy with an annotation carrier.

The projection result records annotations removed by the selected view instead of silently dropping their identity.
Source targets and maps use tracked coordinates and are valid only at `evaluatedRevision`. Read the
[HTML and Markdown projection guide](/document-api/output-projections) before saving a map for a later review action.

## Accept or reject one change [#accept-or-reject-one-change]

Decide against the logical change ID, and guard the decision with the revision returned by the list operation:

```ts
const decisionReceipt = await doc.trackChanges.decide(
  {
    decision: 'accept',
    target: { kind: 'id', id: detail.id },
  },
  {
    expectedRevision: changes.evaluatedRevision,
  },
);

if (!decisionReceipt.success) {
  throw new Error(`${decisionReceipt.failure.code}: ${decisionReceipt.failure.message}`);
}

console.log('Resolved change:', decisionReceipt.removed);
```

Use `decision: 'reject'` to restore the change's before-state instead. A review decision resolves an existing change, so `changeMode` and `dryRun` do not apply.

Re-list changes after each decision. The receipt can invalidate or remap references, and partial range decisions can create successor fragments with new IDs.

> **Verification target (success)**
>
> After the decision succeeds, a fresh `trackChanges.list()` result should no longer contain the resolved logical change
> ID. The saved DOCX should preserve the accepted or rejected document state.


For a complete code-to-human handoff, follow [Review tracked changes](/agents/workflows/review-tracked-changes). The generated [`trackChanges` reference](/document-api/reference/track-changes) covers range, side, bulk, and story-specific targets.
