> ## Documentation Index
> Fetch the complete documentation index at: https://superdoc-nick-sd-2070-add-content-controls-namespace-to-doc.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# AI Agents & LLMs

<Warning>
  This page covers the low-level headless Editor approach. For production AI agent workflows, use the [Document Engine AI tools](/document-engine/ai-agents/llm-tools) instead — they provide structured tool definitions, provider-ready schemas, and built-in dispatch.
</Warning>

SuperDoc can run headless in Node.js for server-side document processing, AI agent workflows, and batch automation.

## Quick example

```javascript theme={null}
import { Editor } from 'superdoc/super-editor';
import OpenAI from 'openai';

const openai = new OpenAI();
const completion = await openai.chat.completions.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: 'Write a service agreement in HTML.' }],
});

const editor = await Editor.open(templateDocx);
editor.commands.insertContent(completion.choices[0].message.content, {
  contentType: 'html',
});
const docx = await editor.exportDocx();
```

## Content formats

<CodeGroup>
  ```javascript Usage theme={null}
  editor.commands.insertContent(value, { contentType: 'html' });      // Recommended for LLMs
  editor.commands.insertContent(value, { contentType: 'markdown' });
  editor.commands.insertContent(value, { contentType: 'text' });
  editor.commands.insertContent(value, { contentType: 'schema' });     // ProseMirror JSON
  ```

  ```javascript Full Example theme={null}
  import { Editor } from 'superdoc/super-editor';

  const editor = await Editor.open(yourFile);

  editor.commands.insertContent(value, { contentType: 'html' });      // Recommended for LLMs
  editor.commands.insertContent(value, { contentType: 'markdown' });
  editor.commands.insertContent(value, { contentType: 'text' });
  editor.commands.insertContent(value, { contentType: 'schema' });     // ProseMirror JSON
  ```
</CodeGroup>

See [Import/Export](/getting-started/import-export) for format details, limitations, and guidance on choosing a format.

## AI redlining with track changes

Use `suggesting` mode so AI edits appear as tracked changes that users can accept or reject:

<CodeGroup>
  ```javascript Usage theme={null}
  const contract = await readFile('./contract.docx');
  const editor = await Editor.open(contract, {
    documentMode: 'suggesting',
  });

  // AI suggestions are tracked — users review them in Word
  editor.commands.insertContent(aiRevisions, { contentType: 'html' });
  const redlined = await editor.exportDocx();
  ```

  ```javascript Full Example theme={null}
  import { readFile } from 'node:fs/promises';
  import { Editor } from 'superdoc/super-editor';

  const contract = await readFile('./contract.docx');
  const editor = await Editor.open(contract, {
    documentMode: 'suggesting',
  });

  // AI suggestions are tracked — users review them in Word
  editor.commands.insertContent(aiRevisions, { contentType: 'html' });
  const redlined = await editor.exportDocx();
  ```
</CodeGroup>

## Programmatic block access

For multi-step workflows — extract block references, send them to an LLM, then apply edits — use the [Document API](/document-api/overview). It returns stable block addresses that work across separate editor sessions:

<CodeGroup>
  ```javascript Usage theme={null}
  // Find all paragraphs and their text
  const result = editor.doc.find({
    select: { type: 'node', nodeType: 'paragraph' },
    includeNodes: true,
  });

  // Each item has an address with a best-effort stable nodeId
  const blocks = result.items.map((item) => ({
    id: item.address.nodeId,     // usually stable across loads for unchanged DOCX content
    type: item.address.nodeType,
    text: item.node?.text,
  }));

  // Send blocks to LLM, get back edits, apply them
  ```

  ```javascript Full Example theme={null}
  import { readFile } from 'node:fs/promises';
  import { Editor } from 'superdoc/super-editor';

  const docx = await readFile('./contract.docx');
  const editor = await Editor.open(docx);

  // Find all paragraphs and their text
  const result = editor.doc.find({
    select: { type: 'node', nodeType: 'paragraph' },
    includeNodes: true,
  });

  // Each item has an address with a best-effort stable nodeId
  const blocks = result.items.map((item) => ({
    id: item.address.nodeId,     // usually stable across loads for unchanged DOCX content
    type: item.address.nodeType,
    text: item.node?.text,
  }));

  // Send blocks to LLM, get back edits, apply them
  ```
</CodeGroup>

<Info>
  Block addresses from `doc.find()` prefer DOCX-native IDs (`paraId`) for imported blocks. This is the best available cross-session anchor, but no ID is guaranteed to survive all Word round-trips. Don't read `node.attrs.sdBlockId` directly — it's regenerated on every load.
</Info>

## LLM quick reference

Point your AI assistant at these URLs for SuperDoc context:

```
https://docs.superdoc.dev/llms.txt        // Quick reference
https://docs.superdoc.dev/llms-full.txt   // Complete documentation
```

## Next steps

<CardGroup cols={2}>
  <Card title="Document API" icon="book" href="/document-api/overview">
    Stable block addressing, find/replace, and programmatic edits
  </Card>

  <Card title="SuperEditor API" icon="code" href="/core/supereditor/overview">
    Headless mode, Editor.open(), and programmatic control
  </Card>

  <Card title="Import/Export" icon="file" href="/getting-started/import-export">
    Content formats, export options, and round-trip behavior
  </Card>

  <Card title="AI Redlining (Headless)" icon="github" href="https://github.com/superdoc-dev/superdoc/tree/main/examples/headless/ai-redlining">
    Node.js script: open DOCX, LLM reviews, export redlined document
  </Card>
</CardGroup>
