Conversations
A conversation holds a chat and everything it refers to: the messages, and the documents, files, and web resources attached to them. CKEditor AI answers from that content, or proposes edits to it. The API is used by the editor’s AI Chat feature. The endpoints are documented in the Conversations, Conversation Documents, Conversation Files, and Conversation Messages sections of the API reference.
The flow is three calls: create the conversation, upload what the message refers to, and send the message.
POST /v1/conversations
Content-Type: application/json
Authorization: Bearer <your-token>
{
"id": "my-conversation-123",
"group": "research"
}Copy codeUpload an HTML document before a message references it:
POST /v1/conversations/my-conversation-123/documents
Content-Type: application/json
Authorization: Bearer <your-token>
{
"content": "<h1>Hello, world!</h1>"
}Copy codeResponse:
{
"id": "doc-123"
}Copy codeA file goes to a different endpoint. Send POST /v1/conversations/{conversationId}/files as multipart/form-data with the file in a file field:
POST /v1/conversations/my-conversation-123/files
Content-Type: multipart/form-data; boundary=----boundary
Authorization: Bearer <your-token>
------boundary
Content-Disposition: form-data; name="file"; filename="report.pdf"
Content-Type: application/pdf
<binary content>
------boundary--Copy codeThe format comes from the content type of the file part, and from the file extension when that content type is application/octet-stream. An unsupported format is rejected with 415 and an unsupported-file-type code. To have the service download the file instead, post a JSON body with a url to the same endpoint.
See the Conversation Documents and Conversation Files references for the full schemas.
POST /v1/conversations/my-conversation-123/messages
Content-Type: application/json
Authorization: Bearer <your-token>
{
"prompt": "Analyze the attached document and provide a summary of the key points",
"model": "agent-1",
"content": [
{
"type": "document",
"id": "doc-123"
}
],
"capabilities": {
"webSearch": {},
"reasoning": {}
}
}Copy codecontent takes as many entries as the message needs, so a request can put a document and a web resource in front of the model at once:
"content": [
{ "type": "document", "id": "doc-123" },
{ "type": "web-resource", "id": "web-123" }
]Copy codeThe reply arrives as a stream. The first event carries the id of the reply, and the text follows in chunks:
event: message-metadata
data: {"messageId":"mesg-id-0000000000006"}
event: text-delta
data: {"textDelta":"The attached document "}
event: text-delta
data: {"textDelta":"has 10 words."}
Copy codeStreaming events lists every event a conversation stream can carry.
To be able to replay the reply after a dropped connection, send the message to the /v1.1 endpoint instead. See Resuming a dropped reply.
- Attachments: a message references documents, files, and web resources uploaded to the conversation. Files can be PDF, DOCX, HTML, Markdown, plain text, PNG, or JPEG. Conversation context permissions set the formats a user may attach, and File and content limits set the sizes.
- Web search:
"webSearch": {}in thecapabilitiesobject makes CKEditor AI search the web and read the results, so the reply can use current information. Each page it used arrives as asourceevent. The token needsai:conversations:websearch. - Reasoning:
"reasoning": {}in the same object lets the model work through the request before it answers. The reasoning text is not returned. The stream sends areasoningevent for each step, so your interface can show that the reply is in progress. The token needsai:conversations:reasoning, and Reasoning lists which models support it.
POST /v1/conversations/{conversationId}/messages returns the reply over Server-Sent Events (SSE). A reply can search the web, reason, call tools, and set the conversation title. Each of those steps has its own event, so a conversation stream has more event types than the other endpoints:
message-metadataarrives first and carries themessageIdof the reply. Store it, because cancelling and resuming both use that id.text-deltacarries the reply text, andmodification-deltacarries the document edits it proposes.reasoning,web-search,document-read, andsourcereport work in progress, so your interface can show something while no text arrives.mcp-tool-result,mcp-tool-notification, andhook-progressarrive when a reply calls a tool on one of your MCP servers or a hook you configured. A tool call needs no confirmation from the user, and the event arrives after the call ran.conversation-titlearrives at the end, for a conversation created without a title. Store it with the conversation.errorends the stream, and a cancelled reply ends the same way.
See Streaming protocol for the payload of each event, the order they arrive in, and how to join the chunks of one modification.
If the connection drops during a reply, the part already generated is not lost. Send the message to POST /v1.1/conversations/{conversationId}/messages instead of the /v1 endpoint. That version buffers the reply, so you can reconnect and replay the events you missed. The request and the response are otherwise the same as on /v1.
To reconnect, send a GET request to /v1.1/conversations/{conversationId}/messages/{messageId}/stream with the id of the last SSE event you received as the lastEventId query parameter. Without it, the whole reply is replayed. The same call recovers a message left in the streaming status. A DELETE request to the same URL cancels a reply in progress. See the resume stream endpoint reference.
CKEditor AI stores the conversations and their messages, so you do not have to store them yourself.
CKEditor AI deletes conversations after a retention period. See Storage and retention.
The editor’s chat reads them back after a reload through these endpoints:
GET /v1/conversationslists the user’s conversations with their titles and timestamps. The response is one page. PassnextCursorback as thecursorparameter to get the next one, and stop when it arrivesnull.GET /v1/conversations/{conversationId}/messagesreturns the messages of one conversation. Ausermessage carries what the user typed inpromptand its attachments incontent. Anassistantmessage carries the reply incontent, and astatusthat iscompleted,cancelled,error, orstreaming. A reply stillstreamingcan be resumed, as Resuming a dropped reply describes.PATCH /v1/conversations/{conversationId}renames a conversation, and setspinned,group, andattributes. A conversation created without a title gets one generated from its first message.
See the Conversations and Conversation Messages sections of the API reference for the query parameters and the full response schemas.
Rate a reply by how many of its suggestions the user accepted. Send a PUT request to /v1/conversations/{conversationId}/messages/{messageId}/ratings with positiveCount, the number the user accepted, and totalCount, the number they received. If you send the request again for the same message, the new rating replaces the old one. Ratings work on messages sent through /v1 and through /v1.1. See the API reference for the schema.
Access is set per token. ai:conversations:read covers listing conversations and reading their messages, and ai:conversations:write covers creating conversations and sending messages. Web search and reasoning need ai:conversations:websearch and ai:conversations:reasoning. See Conversation permissions for the full list, including the file formats a user may attach.
- REST API lists every endpoint family and the mechanics they share.
- Streaming protocol defines the SSE events for every endpoint family.
- Permissions lists the scopes a token can carry.
- Context library stores prompts and reference files in your environment, and a message references them by id.