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

# Backend reference

> Every export of @reviseio/editor/server, the Node entry point of the SDK.

`@reviseio/editor/server` runs Revise's converters and document-local semantic tools in
Node, against a `Y.Doc` your process owns. It needs no React, browser, or
model, and makes no calls to a Revise service. Use it to let your server take
part in the collaborative documents your users have open in the browser.

```ts theme={null}
import {
  createServerDocumentSession,
  fileToYDoc,
  ydocToDocx,
} from "@reviseio/editor/server";
```

Peer dependencies: `yjs` (one copy, shared with everything else that touches
the document) and `jsdom` (the converters parse XML and HTML with DOM APIs).
The entry point is ESM-only and ships fully typed declarations, including for
`moduleResolution: "NodeNext"`.

Large modules load lazily. A host that only converts files never loads the
editor's mutation engine. The first call installs the DOM shims.

## Conversion

These are the converters the editor runs in the browser. A document produced
here is identical to one built in a client.

<ResponseField name="parseDocument(bytes, filename)" type="Promise<ReviseDocument>">
  Parse `.docx`, `.odt`, `.rtf`, `.md`, `.txt`, or `.html` into Revise's
  document model. The format is read from the filename. `ReviseDocument` is
  opaque: convert it instead of inspecting it.
</ResponseField>

<ResponseField name="documentToDocx(doc)" type="Promise<Uint8Array>">
  Serialize the document model to `.docx` bytes, including comments and
  tracked changes.
</ResponseField>

## Rooms

These Yjs primitives let a server create, seed, store, and export documents.
See [collaboration](/developer/docs/developer/docs/editor-sdk/guides/collaboration#server-editing)
for the workflows that use them.

<ResponseField name="createReviseYDoc()" type="Y.Doc">
  A `Y.Doc` built with the settings the editor requires. Start here when the
  server creates the room.
</ResponseField>

<ResponseField name="fileToYDoc(bytes, filename)" type="Promise<Y.Doc>">
  Parse a file and return a new `Y.Doc` that holds it.
</ResponseField>

<ResponseField name="seedYDocFromFile(ydoc, bytes, filename)" type="Promise<boolean>">
  Seed an **empty** shared document from a file and report whether anything
  was written. A room that already holds a document is not changed, so it is
  safe to call on every connection.
</ResponseField>

<ResponseField name="encodeYDoc(ydoc)" type="Uint8Array">
  Encode the whole room as one opaque update, for storage or transfer.
</ResponseField>

<ResponseField name="decodeYDoc(update)" type="Y.Doc">
  Restore a room from stored bytes.
</ResponseField>

<ResponseField name="hasDocument(ydoc)" type="boolean">
  Whether a `Y.Doc` already holds a Revise document.
</ResponseField>

<ResponseField name="ydocToDocument(ydoc)" type="ReviseDocument">
  Read a room back as the document model.
</ResponseField>

<ResponseField name="ydocToDocx(ydoc)" type="Promise<Uint8Array>">
  Export a room to `.docx` with no browser, for example from a download
  endpoint or an archive job. Pending tracked changes export as native Word
  revisions.
</ResponseField>

<ResponseField name="exportDocument(source, options?)" type="Promise<Uint8Array>">
  Export a room (`Y.Doc`) or a parsed document as `"docx"` (default),
  `"html"`, `"markdown"`, or `"txt"`. `mode: "review"` (default) keeps pending
  tracked changes and comments in a .docx; `mode: "final"` accepts every
  pending change and drops comments first. A room imported from a .docx keeps
  the original file's bytes for untouched content in both modes; blocks that
  changed, or that the accepted changes touched, are regenerated. PDF export
  needs a browser — use `tools.export` in the editor.
</ResponseField>

<ResponseField name="assertUsableSharedDocument(ydoc)" type="void">
  Throws if a document already uses the editor's reserved top-level keys
  (`RESERVED_DOCUMENT_KEYS`) for something else. The editor runs the same
  check before joining.
</ResponseField>

<ResponseField name="installDomShims()" type="Promise<void>">
  Install the DOM globals the converters need. Every function here calls it.
  Call it yourself only when importing converters directly.
</ResponseField>

## Document session

<ResponseField name="createServerDocumentSession(ydoc, options)" type="Promise<ServerDocumentSession>">
  Bind Revise's semantic tools to a host-owned `Y.Doc`. It is async because
  it loads the editor's mutation engine on first use.
</ResponseField>

```ts theme={null}
const session = await createServerDocumentSession(ydoc, {
  documentId: "agreement-1", // required, host-owned
  mode: "suggesting",        // default; "editing" applies directly
  searchPageSize: 25,        // optional
  agentName: "Contract Bot", // optional, default "Revise Agent"
});
```

Sessions default to **suggesting** mode, as in the browser. A service proposes
tracked changes unless it opts into direct edits. Tool calls on one session run
in arrival order. Each call captures the session mode when it is submitted, so
changing modes with queued work is deterministic.

`agentName` is the author of the suggestions and comments the session's tools
create, and becomes `w:author` when the document exports to .docx.

### Mode

<ResponseField name="getMode()" type="&#x22;suggesting&#x22; | &#x22;editing&#x22;">
  The mode subsequent mutations will capture.
</ResponseField>

<ResponseField name="setSuggestingMode() / setEditingMode()" type="void">
  Switch the mode for subsequent calls. A per-call
  `{ directMode: boolean }` option overrides it in either direction.
</ResponseField>

### Tools

The session's `tools` object uses the [shared tool
contract](/developer/docs/developer/docs/editor-sdk/guides/agent-tools#results): the same envelope, typed
inputs, and error class as `editor.tools` in the browser.

<ResponseField name="tools.getDefinitions()" type="ReviseToolDefinition[]">
  The document-local tool catalog: 24 of the browser's 26 tools, without
  `get_selection` and `view_image`. Schemas and descriptions have no
  `document_id`, because a session is bound to one document. See the
  [tool reference](/developer/docs/developer/docs/editor-sdk/api/agent-tools).
</ResponseField>

<ResponseField name="tools.execute(name, input?, options?)" type="Promise<ReviseToolResult<Name>>">
  Typed execution. Expected failures return `{ ok: false, error }`.
</ResponseField>

<ResponseField name="tools.executeDynamic(name, input?, options?)" type="Promise<ReviseToolResult<string>>">
  Execute untrusted, model-provided names and JSON. A supplied `document_id`
  is rejected with a structured failure.
</ResponseField>

<ResponseField name="tools.call(name, input?, options?)" type="Promise<ReviseToolResponse<Name>>">
  For application code. Returns the successful response, or throws a typed
  `ReviseToolError` when the tool rejects the call.
</ResponseField>

Successful mutations report `suggestionIds`: the tracked records the call
created. The list is empty for direct edits and `null` for read, search, and
measure tools. Store the IDs with your review workflow. You use them to accept
or reject later, in the browser or on the server.

### Suggestion review

The same per-ID review methods as the browser's `review` controller.

<ResponseField name="listSuggestions()" type="ReviseSuggestionRecord[]">
  Every pending tracked suggestion in the `Y.Doc` as a reviewable record with
  authorship metadata (`authorType`, `agentName`, `agentModel`, `source`,
  `label`, `createdAt`). Includes collaborators' suggestions in a shared
  document. Filter by author before bulk decisions.
</ResponseField>

<ResponseField name="getPendingSuggestionIds()" type="string[]">
  The bare ID list underneath `listSuggestions()`.
</ResponseField>

<ResponseField name="acceptSuggestions(ids) / rejectSuggestions(ids)" type="ReviseSuggestionDecision">
  Accept or reject specific suggestions by ID. This is the main review path.
  The result is per ID: `resolved` were settled, `missing` were not pending (a
  later edit to the same block can supersede earlier records), and
  `unresolved` could not be settled.
</ResponseField>

<ResponseField name="acceptAllSuggestions() / rejectAllSuggestions()" type="ReviseSuggestionDecision">
  Accept or reject every pending suggestion, including collaborators'. Use the
  ID-targeted methods unless the host owns the entire document.
</ResponseField>

### Lifecycle

<ResponseField name="dispose()" type="void">
  Release Revise's observers and request and search state. The host-owned
  `Y.Doc` stays alive. Safe to call twice. Every other member throws after
  disposal.
</ResponseField>

## Errors

<ResponseField name="ReviseToolError" type="class extends Error">
  Thrown by `tools.call()` on both surfaces for expected tool rejections.
  Carries `tool`, `code`, `callId`, and the full `failure` object. Expected
  failures through `execute()`/`executeDynamic()` arrive as
  `{ ok: false, error }` results instead.
</ResponseField>

## Shared contract types

`@reviseio/editor` and `@reviseio/editor/server` export the same tool contract types:
`ReviseToolResult`, `ReviseToolResponse`, `ReviseToolFailure`,
`ReviseSuggestionDecision`, `ReviseSuggestionRecord`, the generated
`ReviseToolInputMap`, and related types. Result-handling code works unchanged
in the browser and in Node. The shapes are listed in
[types](/developer/docs/developer/docs/editor-sdk/api/types#tools).

Node-only types: `ServerDocumentSession`, `ServerDocumentSessionOptions`,
`ServerDocumentMode`, and `ReviseServerFormat` (`"docx" | "odt" | "rtf" |
"markdown" | "txt" | "html"`, the formats the server can read). PDF and images
are browser-only.


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