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 covers it. This page documents the endpoint for calls without an editor.
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.
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"
}Copy codeThe response holds one entry per document:
{
"documents": [
{
"document": "<p>The northern lights dance across the polar skies.</p>",
"summary": "Corrected two misspelled words."
}
]
}Copy codeOn SaaS, the base URL depends on your region. See SaaS for the hosts. For a development token, see Quick start. For production tokens, see Authentication.
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. Ametadataevent comes first, then the edited content as it is produced, thentext-deltaevents with the summary, and a finaldocumentevent with the complete result.
See Streaming protocol for event payloads and ordering.
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 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.
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 sends three in one call.
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:
{
"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 } ]
}Copy codeOffsets 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.
Keep a prompt you reuse in the context library and attach it by id. A context can hold prompts and reference files:
{
"content": [
{ "type": "document", "content": "<p data-id=\"p1\">...</p>" },
{ "type": "context", "id": "editorial-style-guide" }
],
"model": "agent-1"
}Copy codeWhen a referenced context holds a prompt, prompt is optional.
Referencing a context requires the ai:contexts:<contextId> permission. See Context library permissions.
The capabilities object switches on web search and reasoning for the request. It is the same object conversations use:
{
"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": {}
}
}Copy codeThe token needs the ai:conversations:websearch and ai:conversations:reasoning permissions, and the Models page lists which models support each capability.
Use the model field to pick the model that performs the edit. The Models page lists model ids and their limits.
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:
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"
}Copy codeEvery document in the response has the same structure, whatever its source, so reviewers start from a consistent set.
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.
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"
}Copy codeThe 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:
POST /v1/documents/process/streamCopy codeevent: 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."}]}
Copy codeAny 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 for the full list and the wildcard rules.
- Document Processing API reference lists every field of the
/v1/documents/processendpoints, with constraints and validation rules. - REST API links the API reference and covers versioning, limits, and error codes.
- Context library stores the prompts and reference files you attach by id.
- What comes back in the response explains how CKEditor 5 turns fragments into track-changes suggestions.
- Reviews check a whole document and return suggestions anchored to the elements they concern.
- Actions apply one transformation to a piece of content and keep no state.
- Conversations run a chat that keeps history and can attach documents.