# Document Processing

Document Processing applies one prompt to one or more HTML documents on the server, with no editor open. The response returns the edited documents and a summary of what changed. This page covers the request and response, the synchronous and streaming endpoints, fragment responses, and the request options.

When the document is open in CKEditor 5, or the editor runs on your server through the Server-side Editor API, use the `AIDocumentProcessingGateway` plugin instead. [Using CKEditor AI programmatically](../../../../ckeditor5/latest/features/ai/ckeditor-ai-programmatic.md) covers it. This page documents the endpoint for calls without an editor.

<a id="the-contract">

## The contract

Requests are stateless. Each request contains everything the edit needs. CKEditor AI changes only what the prompt asks for. HTML outside the requested edit, including attributes and classes, stays unchanged.

```http
POST /v1/documents/process
Content-Type: application/json
Authorization: Bearer <your-token>

{
  "content": [
	{
	  "type": "document",
	  "content": "<p>The norhtern lights dence across the polar skies.</p>"
	}
  ],
  "prompt": "Fix all grammar and spelling errors",
  "model": "agent-1"
}
```

The response holds one entry per document:

```json
{
  "documents": [
	{
	  "document": "<p>The northern lights dance across the polar skies.</p>",
	  "summary": "Corrected two misspelled words."
	}
  ]
}
```

On SaaS, the base URL depends on your region. See [SaaS](saas.md) for the hosts. For a development token, see [Quick start](quick-start.md). For production tokens, see [Authentication](authentication.md).

<a id="synchronous-and-streaming-requests">

## Synchronous and streaming requests

Document Processing is available as a synchronous request or as a stream. Both accept the same request body:

* **`POST /v1/documents/process`:** returns the full JSON response when the edit finishes. The service allows up to 10 minutes for one request, so set your client timeout to at least that.
* **`POST /v1/documents/process/stream`:** returns the same result as Server-Sent Events. A `metadata` event comes first, then the edited content as it is produced, then `text-delta` events with the summary, and a final `document` event with the complete result.

See [Streaming protocol](streaming-protocol.md) for event payloads and ordering.

<a id="response-format">

## Response format

With the default `responseFormat: "html"`, the response contains the whole edited document. If the edit is small and the document is long, most of that payload is text that did not change.

Set `responseFormat: "arf"` to receive only the elements the model changed, each anchored by its `data-id`. Add a `data-id` attribute to each element of your document before you send it, so your code can apply each fragment to the right element. The synchronous endpoint returns the fragment in the `document` field of the entry. The streaming endpoint returns it in `modification-delta` events.

Use this format when:

* the documents are long and the edits are small
* you need to know which elements changed
* the result goes into CKEditor 5 as track-changes suggestions

See [Fragment responses](fragment-responses.md) for what a fragment contains and how to apply one. Conversations use the same format for the document edits CKEditor AI proposes in chat.

To write the result into a collaboration document as track-changes suggestions, run the editor on the server with the [Server-side Editor API](../../developer-resources/server-side-editor-api/editor-scripts.md).

<a id="options">

## Options

<a id="several-documents-in-one-call">

### Several documents in one call

A request can contain more than one document part, and each one gets its own entry in the response, in request order. The example [Normalize documents from several sources](#normalize-documents-from-several-sources) sends three in one call.

<a id="editing-part-of-a-document">

### Editing part of a document

A document part takes a `selection` array. Each entry is a pair of character offsets into the HTML string you sent. This part limits the edit to the second paragraph:

```json
{
  "type": "document",
  "content": "<h1>Release notes</h1><p>The Legacy Export screen was removed.</p><p>Exporting now happens from the sharing panel.</p>",
  "selection": [ { "start": 66, "end": 118 } ]
}
```

Offsets count characters in the HTML string, tags included. `start` is the index of the first character and `end` the index after the last one. The model reads the selected span and the content around it, and limits the edit to the span.

<a id="contexts">

### Contexts

Keep a prompt you reuse in the [context library](extensions/context-library.md) and attach it by id. A context can hold prompts and reference files:

```json
{
  "content": [
	{ "type": "document", "content": "<p data-id=\"p1\">...</p>" },
	{ "type": "context", "id": "editorial-style-guide" }
  ],
  "model": "agent-1"
}
```

When a referenced context holds a prompt, `prompt` is optional.

> **Note**
>
> Referencing a context requires the `ai:contexts:<contextId>` permission. See [Context library permissions](permissions.md#context-library-permissions).

<a id="web-search-and-reasoning">

### Web search and reasoning

The `capabilities` object switches on web search and reasoning for the request. It is the same object conversations use:

```json
{
  "content": [
	{ "type": "document", "content": "<p data-id=\"p1\">Our plan starts at $29 per seat.</p>" }
  ],
  "prompt": "Check every price against the published price list and correct the ones that are out of date.",
  "model": "agent-1",
  "capabilities": {
	"webSearch": {},
	"reasoning": {}
  }
}
```

The token needs the `ai:conversations:websearch` and `ai:conversations:reasoning` permissions, and the [Models](models.md) page lists which models support each capability.

<a id="model-choice">

### Model choice

Use the `model` field to pick the model that performs the edit. The [Models](models.md) page lists model ids and their limits.

<a id="api-examples">

## API examples

<a id="normalize-documents-from-several-sources">

### Normalize documents from several sources

A company acquires three regional support teams, each with its own knowledge base:

* a Confluence space
* a folder of PDFs on a shared drive
* a set of Word documents

Each team structured its content differently. Convert the sources to HTML and send them in one request with a prompt that normalizes their structure:

```http
POST /v1/documents/process
Content-Type: application/json
Authorization: Bearer <your-token>

{
  "content": [
	{
	  "type": "document",
	  "content": "<h1>Password reset</h1><p>Open Settings, then Security. Click Reset password and follow the link in the email.</p>"
	},
	{
	  "type": "document",
	  "content": "<p>Password reset. Users who forget their password contact the helpdesk. The helpdesk sends a reset link that is valid for 24 hours.</p>"
	},
	{
	  "type": "document",
	  "content": "<ul><li>Q: I forgot my password.</li><li>A: Use the Forgot password link on the sign-in page.</li></ul>"
	}
  ],
  "prompt": "Restructure each document into a short overview, numbered steps for any process described, and an FAQ for anything phrased as a question. Keep the original meaning and make the shape consistent.",
  "model": "agent-1"
}
```

Every document in the response has the same structure, whatever its source, so reviewers start from a consistent set.

<a id="update-a-manual-when-the-product-changes">

### Update a manual when the product changes

A release removes the old export screen, and exporting now happens from the sharing panel. The user manual still describes the old flow in several places:

* a walkthrough with numbered steps for the removed screen
* a troubleshooting entry for a problem that can no longer happen
* a comparison table with a row for a setting that is gone
* a “see also” pointer to the removed section

Some of it needs rewriting, some needs removing, and the cross-references need updating.

```http
POST /v1/documents/process
Content-Type: application/json
Authorization: Bearer <your-token>

{
  "content": [
	{
	  "type": "document",
	  "content": "<h1>User manual</h1><h2 id=\"export\">Exporting a document</h2><ol><li>Open the Legacy Export screen.</li><li>Choose a format.</li><li>Click Export.</li></ol><h2>Troubleshooting</h2><p>If the Legacy Export screen does not load, clear the browser cache.</p><p>See also: <a href=\"#export\">Exporting a document</a>.</p>"
	}
  ],
  "prompt": "The Legacy Export screen is gone. Exporting now happens from the sharing panel: open a document, click Share, then Export. Update this manual for that change. Rewrite the steps that use the old screen, remove anything that only made sense while it existed, and fix references that point at removed sections.",
  "model": "agent-1"
}
```

The `summary` in the response lists what changed, so reviewers know which parts of the manual to check.

To show the edit as it is produced, send the same body to the streaming endpoint and read the events:

```http
POST /v1/documents/process/stream
```

```
event: metadata
data: {"streamId":"strm-id-0000000000000"}

event: document-delta
data: {"textDelta":"<h1>User manual</h1><h2 id=\"export\">Exporting a document</h2>"}

event: text-delta
data: {"textDelta":"Rewrote the export steps for the sharing panel"}

event: document
data: {"documents":[{"document":"<h1>User manual</h1>...","summary":"Rewrote the export steps for the sharing panel, removed the troubleshooting entry for the Legacy Export screen, and updated the cross-reference."}]}
```

<a id="permissions">

## Permissions

Any request to `/v1/documents/process` needs `ai:documents:process` in the token. A `context` part also needs `ai:contexts:<contextId>`, and web search and reasoning need `ai:conversations:websearch` and `ai:conversations:reasoning`. See [Permissions](permissions.md) for the full list and the wildcard rules.

<a id="api-reference">

## API reference

* **[Document Processing API reference](https://ai.cke-cs.com/v1/docs#tag/Document-processing)** lists every field of the `/v1/documents/process` endpoints, with constraints and validation rules.
* **[REST API](rest-api.md)** links the API reference and covers versioning, limits, and error codes.

<a id="next-steps">

## Next steps

* **[Context library](extensions/context-library.md)** stores the prompts and reference files you attach by id.
* **[What comes back in the response](how-it-works.md#what-comes-back-in-the-response)** explains how CKEditor 5 turns fragments into track-changes suggestions.
* **[Reviews](reviews.md)** check a whole document and return suggestions anchored to the elements they concern.
* **[Actions](actions.md)** apply one transformation to a piece of content and keep no state.
* **[Conversations](conversations.md)** run a chat that keeps history and can attach documents.

---

Full index of the Cloud Services documentation: [llms.txt](../../../llms.txt)
