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

# Backend reference

> Every export of @reviseio/sdk/backend — the Node half of the SDK.

`@reviseio/sdk/backend` is the server half of the same package: Revise's
converters and document-local semantic tools running under plain Node, against
a `Y.Doc` your process owns. No React, no browser, no model required — and no
separate service of ours in the path. It is what lets your server participate
in the same collaborative documents your users have open in the browser.

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

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"`.

Everything heavy loads lazily: a host that only converts files never pays for
the editor's mutation engine, and the first call installs the DOM shims for
you.

## Conversion

The same converters the editor runs in the browser, so a document produced
here is identical to one a client would have built.

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

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

## Rooms: create, seed, persist, export

The Yjs-document primitives that make a server the *owner* of document
lifecycle rather than a bystander. See
[collaboration](/guides/collaboration#your-server-is-a-participant) for the
workflows these compose into.

<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 fresh `Y.Doc` holding it — server-side document
  creation in one call.
</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 left alone, so this is
  safe to call on every connection.
</ResponseField>

<ResponseField name="encodeYDoc(ydoc)" type="Uint8Array">
  The whole room as one opaque update, for storage or shipping.
</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 straight to `.docx` — a download endpoint or an archive job,
  with no browser involved. Pending tracked changes export as native Word
  revisions.
</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 check the editor itself
  runs before joining.
</ResponseField>

<ResponseField name="installDomShims()" type="Promise<void>">
  Install the DOM globals the converters need. Every function here calls it
  for you; exported for hosts importing converters directly.
</ResponseField>

## The document session

<ResponseField name="createServerDocumentSession(ydoc, options)" type="Promise<ServerDocumentSession>">
  Bind Revise's canonical semantic tools to a host-owned `Y.Doc`. Async
  because the tool session loads the editor's mutation engine on first use —
  conversion-only hosts never pay for it.
</ResponseField>

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

Sessions default to **suggesting** mode — the same posture as the browser
surface: a service proposes tracked changes unless it explicitly opts into
direct edits. All tool calls on one session are serialized in arrival order,
and each call captures the session mode when it is submitted, so toggling
modes with queued work is deterministic.

### 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 posture for subsequent calls. A per-call
  `{ directMode: boolean }` option overrides in either direction.
</ResponseField>

### Tools

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

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

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

<ResponseField name="tools.executeDynamic(name, input?, options?)" type="Promise<ReviseToolResult<string>>">
  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>>">
  Application-code form: returns the successful response and throws a typed
  `ReviseToolError` when the tool rejects the call.
</ResponseField>

Successful mutations report `suggestionIds` — the tracked records that call
created (empty for direct edits, `null` for read/search/measure tools).
Persist them with your review workflow; they are the handle for accept and
reject later, on either surface.

### Suggestion review

The same per-ID decision surface the browser's `review` controller exposes.

<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`) — including 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">
  Settle specific suggestions by ID — the primary review path. The result is
  per-ID: `resolved` settled now, `missing` were not pending (a later edit to
  the same block can supersede earlier records), `unresolved` could not be
  settled.
</ResponseField>

<ResponseField name="acceptAllSuggestions() / rejectAllSuggestions()" type="ReviseSuggestionDecision">
  Whole-document decisions, collaborators' pending suggestions included.
  Prefer the ID-targeted path unless the host owns the entire document.
</ResponseField>

### Lifecycle

<ResponseField name="dispose()" type="void">
  Release Revise's observers and request/search state. The host-owned `Y.Doc`
  deliberately remains alive. Safe to call twice; every other member throws
  once disposed.
</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

The tool contract — `ReviseToolResult`, `ReviseToolResponse`,
`ReviseToolFailure`, `ReviseSuggestionDecision`, `ReviseSuggestionRecord`,
the generated `ReviseToolInputMap`, and friends — is exported by
`@reviseio/sdk` and `@reviseio/sdk/backend` alike, so host result-handling
code is shared verbatim between web and Node. The shapes are listed in
[types](/api/types#tools).

Node-only types: `ServerDocumentSession`, `ServerDocumentSessionOptions`,
`ServerDocumentMode`, `ReviseServerFormat` (`"docx" | "markdown" | "txt" |
"html"` — the formats readable on the server; PDF and images are
browser-only).
