> ## Documentation Index
> Fetch the complete documentation index at: https://revise.io/developer/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# ReviseEditorHandle

> The controllers your application drives the editor with.

`onReady` passes you a `ReviseEditorHandle`. Store it in a ref. Every
controller on it is stable for the life of the component.

```ts theme={null}
const editor = useRef<ReviseEditorHandle | null>(null);

<ReviseEditor onReady={(handle) => (editor.current = handle)} />;
```

## Routing

Document-local controllers act on the active document. Each one can be bound to
a specific document instead:

```ts theme={null}
editor.review.next();
editor.review.forDocument("exhibit-a").next();
editor.document("exhibit-a").review.next();  // equivalent
```

Scoped controllers: `tools`, `toolbar`, `review`, `view`, `zoom`, `selection`,
`agent`, `comments`.

## documents

<ResponseField name="open(document, options?)" type="Promise<ReviseDocumentHandle>">
  Opens and parses a document. `{ activate: false }` loads it in the background.
</ResponseField>

<ResponseField name="close(documentId)" type="boolean" />

<ResponseField name="activate(documentId)" type="boolean" />

<ResponseField name="get(documentId?)" type="ReviseDocumentHandle | null" />

<ResponseField name="require(documentId?)" type="ReviseDocumentHandle">
  As `get`, but throws instead of returning `null`.
</ResponseField>

<ResponseField name="getActiveId()" type="string | null" />

<ResponseField name="list()" type="ReviseOpenDocument[]" />

<ResponseField name="getState()" type="ReviseDocumentCollectionState" />

<ResponseField name="subscribe(listener)" type="() => void" />

## tools

<ResponseField name="getDefinitions()" type="ReviseEditorToolDefinition[]">
  Native document-local tool schemas, without the delegation tool. Hand these
  to your own model. `editor.getToolDefinitions()` returns the same tools with
  an `execute` function each, plus `revise_run_agent` when an
  [agent is configured](/developer/docs/developer/docs/editor-sdk/guides/delegated-agent).
</ResponseField>

<ResponseField name="execute(name, input?, options?)" type="Promise<ReviseToolResult<Name>>">
  Typed inputs from the shared tool contract. Expected failures return
  `{ ok: false }`. Options: `{ documentId?, directMode? }`. `context_notes`,
  which a model uses to carry context between reads, is optional here and
  defaults to `"N/A"`.
</ResponseField>

<ResponseField name="executeDynamic(name, input?, options?)" type="Promise<ReviseToolResult<string>>">
  For untrusted model-provided calls, browser-only tools (`get_selection`,
  `view_image`, `revise_run_agent`), and model-facing `document_id` routing.
</ResponseField>

<ResponseField name="call(name, input?, options?)" type="Promise<ReviseToolResponse<Name>>">
  Returns the successful response, or throws `ReviseToolError`.
</ResponseField>

<ResponseField name="exportDocx(documentId?)" type="Promise<Blob>" />

<ResponseField name="export(options?, documentId?)" type="Promise<Blob>">
  Export as `"docx"` (default), `"pdf"`, `"html"`, `"markdown"`, or `"txt"`.
  With `mode: "review"` (default) a .docx keeps pending tracked changes and
  comments, and other formats show the text with changes accepted.
  `mode: "final"` accepts every pending change and drops comments first — a
  clean copy. See [export](/developer/docs/developer/docs/editor-sdk/guides/formats#export).
</ResponseField>

<ResponseField name="acceptAllSuggestions(documentId?)" type="ReviseSuggestionDecision" />

<ResponseField name="rejectAllSuggestions(documentId?)" type="ReviseSuggestionDecision" />

## toolbar

<ResponseField name="getState() / subscribe(listener)" type="ReviseToolbarState">
  Live selection formatting, block type, undo/redo availability, and review
  counts.
</ResponseField>

<ResponseField name="setActiveTab(tab) / openFind()" type="void">
  `setActiveTab` switches the ribbon's row. The SDK has no tab strip for the
  ribbon, so connect your own controls to
  `toolbar.setActiveTab("layout" | "insert" | "review" | "edit")`. Page and
  section breaks are on the Layout row. The SDK has no Tools row. Get word and
  character counts from [`editor.getStatistics()`](#convenience).
</ResponseField>

Commands return `false` when they cannot apply.

| Area | Methods |
| - | - |
| History and clipboard | `undo`, `redo`, `copy`, `copyAs`, `cut`, `paste`, `pasteTextOnly`, `pasteFormattingOnly` |
| Inline | `toggleInline`, `toggleBold`, `toggleItalic`, `toggleUnderline`, `toggleStrikethrough`, `toggleDoubleStrikethrough`, `toggleSmallCaps`, `toggleAllCaps`, `toggleCode`, `toggleLatex`, `toggleSuperscript`, `toggleSubscript`, `clearFormatting` |
| Type | `setFontFamily`, `setFontSize`, `setLetterSpacing`, `setTextColor`, `setHighlightColor` |
| Paragraph | `setHeading`, `setAlignment`, `setLineSpacing`, `toggleList`, `createLink`, `increaseIndent`, `decreaseIndent` |
| Insert | `insertTable`, `insertImage`, `insertContainer`, `insertCodeBlock`, `insertMathBlock`, `insertDiagram`, `insertFootnote`, `insertPageNumber`, `insertPageBreak`, `insertSectionBreak` |
| Review | `openReview`, `closeReview`, `reviewPrevious`, `reviewNext`, `acceptCurrent`, `rejectCurrent`, `acceptAll`, `rejectAll`, `setShowRemovals`, `setSuggestionViewMode` |

## view

Title, document mode, comments panel, and review panel.

<ResponseField name="getState() / subscribe(listener)" type="ReviseViewState">
  `{ ready, title, documentMode, readOnly, commentsOpen, commentCount, reviewOpen, reviewTargetCount }`
</ResponseField>

<ResponseField name="setTitle(title)" type="void" />

<ResponseField name="setDocumentMode(mode)" type="void" />

<ResponseField name="setCommentsOpen(open)" type="void" />

<ResponseField name="setReviewOpen(open)" type="void" />

## review

<ResponseField name="getState() / subscribe(listener)" type="ReviseReviewState">
  Open state, target counts, suggestion IDs, active comment, display mode, and
  every comment thread.
</ResponseField>

| Area | Methods |
| - | - |
| Navigation | `open`, `close`, `previous`, `next`, `nextAgentSuggestion`, `navigateToSuggestion`, `navigateWithinSuggestions` |
| Decisions | `acceptCurrent`, `rejectCurrent`, `acceptAll`, `rejectAll`, `acceptSuggestions`, `rejectSuggestions` |
| Preview | `previewCurrent`, `previewAll`, `previewSuggestions` |
| Display | `setShowRemovals`, `setSuggestionViewMode`, `getOpenSuggestionIds` |
| Comments | `openComments`, `closeComments`, `selectComment`, `addCommentAtSelection`, `addCommentToRanges`, `addCommentToBlock`, `addCommentForSuggestion`, `replyToComment`, `setCommentResolved`, `deleteComment`, `getRelatedSuggestionIds`, `acceptCommentSuggestions`, `rejectCommentSuggestions` |

<ResponseField name="listChanges()" type="ReviseTrackedChange[]">
  Every pending change with `kind`, `author`, `authorType`, `createdAt`,
  `blockIds`, `insertedText`/`deletedText`, and `description`. It is not part
  of the subscribed state. Each call reads the document once. See [building your
  own review panel](/developer/docs/developer/docs/editor-sdk/guides/tracked-changes#custom-review-panel).
</ResponseField>

<ResponseField name="getChange(suggestionId)" type="ReviseTrackedChange | null">
  One change, or `null` after it is resolved.
</ResponseField>

## selection

<ResponseField name="getSnapshot()" type="ReviseSelectionSnapshot" />

<ResponseField name="observe(listener) / subscribe(listener)" type="() => void" />

<ResponseField name="capture()" type="ReviseSelectionCapture | null">
  Saves the selection so it survives focus moving into your UI. Returns `null`
  when nothing is selected.
</ResponseField>

<ResponseField name="restore(capture)" type="ReviseSelectionRestoreResult">
  Returns a typed failure when the document has changed since the capture.
</ResponseField>

<ResponseField name="clear()" type="void" />

## zoom

<ResponseField name="getState()" type="{ zoom, scale }" />

<ResponseField name="setZoom(zoom) / fitWidth()" type="void" />

<ResponseField name="subscribe(listener)" type="() => void" />

## agent

<ResponseField name="run(task, options?)" type="Promise<ReviseAgentRunResult>" />

<ResponseField name="steer(message)" type="boolean">
  Send guidance to a run in progress.
</ResponseField>

<ResponseField name="cancel()" type="void" />

<ResponseField name="subscribe(listener)" type="() => void" />

## comments

Agent runs scoped to a single comment thread.

<ResponseField name="run(threadId, prompt?)" type="Promise<CommentAgentRunResult>" />

<ResponseField name="steer(threadId, message)" type="boolean" />

<ResponseField name="cancel(threadId)" type="void" />

<ResponseField name="getState(threadId)" type="CommentAgentRunState | undefined" />

<ResponseField name="subscribe(listener)" type="() => void">
  Publishes a map of every run in progress.
</ResponseField>

## collaboration

Presence and sync state for a shared document. See
[collaboration](/developer/docs/developer/docs/editor-sdk/guides/collaboration).

<ResponseField name="getState()" type="ReviseCollaborationState">
  `{ enabled, synced, peers }`. `peers` lists everyone in the room, including
  the local participant (`isLocal: true`), each with the `color` their caret is
  drawn in. Empty when no awareness was supplied.
</ResponseField>

<ResponseField name="subscribe(listener)" type="() => void">
  Fires on join, leave, caret movement, and sync-state changes.
</ResponseField>

## Convenience

Shorthands that act on the active document unless given an ID.

<Note>
  `onReady` fires **before** any document exists. Subscriptions can be added
  immediately and attach when a document opens. Calls that act on a document
  throw until one is open. Wait for `onDocumentReady`, or
  `await editor.whenReady()`.
</Note>

```ts theme={null}
await editor.whenReady();             // resolves when a document is open
editor.getRole(documentId?);          // "editor" | "suggester" | "viewer"
editor.getDocument(documentId?);
editor.getStatistics(documentId?);    // { wordCount, characterCount }
editor.getDocumentMode(documentId?);
editor.setDocumentMode(mode, documentId?);
editor.getToolDefinitions(documentId?);
editor.focus(documentId?);
editor.openReview(documentId?);
editor.closeReview(documentId?);
editor.openComments(documentId?);
editor.closeComments(documentId?);
```

`getStatistics()` counts are computed without a layout pass, so they are safe
to call per keystroke behind a debounce. Counts follow the markup view, as in
Word: pending insertions count and pending deletions do not. In the
`"original"` suggestion view mode, counts use the text as if all suggestions
were rejected. `editor.document(id).getStatistics()` takes no argument.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.