Sign up (with export icon)

Editor scripts

Show the table of contents

The Server-side Editor API can be accessed through the POST /collaborations/{document_id}/evaluate-script endpoint from the REST API. This endpoint allows you to execute JavaScript code that uses the CKEditor–5 API directly on the Cloud Services server.

Prerequisites

Copy link
  • An editor bundle needs to be uploaded.
  • The source document needs to be created after uploading the editor bundle.

Request Structure

Copy link

The request body should contain a script parameter with the JavaScript code to be executed:

{
    "script": "// Your JavaScript code here that uses the CKEditor 5 API"
}
Copy code

The script parameter should contain valid JavaScript code that can access the CKEditor–5 API. The script has access to:

  • Editor instance: The CKEditor–5 editor instance is available in the script context
  • Document model: Access to the document’s data model for content manipulation
  • Editor plugins: All loaded plugins and their APIs
  • Collaboration features: Access to comments, suggestions, and revision history

It should be a properly formatted string according to ECMA-404 (The JSON Data Interchange Standard). The only characters you must escape are \ and ". Control codes such as \n, \t, etc., can be removed or escaped as well.

You can also include a user object in the request body to control the user details, like name, during script execution.

Note

By default, the system uses hardcoded user data with the ServerSideEditorAPI identifier for the script execution. You can implement special handling for this user in your application, for example, to process webhook events or track script execution activities.

The example below shows a basic script for getting editor data, along with user context configuration that allows you to execute scripts with specific user context and to control how the user appears in the collaboration session:

{
    "script": "return editor.getData()",
    "user": {
        "id": "user-123",
        "name": "John Doe",
    }
}
Copy code

You can specify a plugins_to_remove parameter in the request body to provide a list of plugin names for removal from the editor before executing the script. It is useful when you need to disable certain editor features or plugins that might interfere with your script execution. Note that, it is different from the removePlugins option that you may have specified in the editor bundle configuration during the bundle upload, as it permanently excludes those plugins from typical document conversions. The removePlugins option is often used to exclude plugins that communicate with the internet. However, in the case of the Server-side Editor API, such plugins can be included in your editor bundle and used in scripts if needed.

{
    "script": "return editor.getData()",
    "plugins_to_remove": ["DocumentOutline", "ExportInlineStyles"]
}
Copy code

Syntax

Copy link

Scripts can be written in both async and non-async ways. You can use await for asynchronous operations:

// Non-async script
editor.getData();

// Async script
await Promise.resolve( editor.getData() );
Copy code

You can return data from your script using the return statement. The returned value will be available as literal data or as a JSON (in case of an object) in the API response:

// Return processed data
const content = editor.getData();

return {
    content: content,
    wordCount: content.split(' ').length
};
Copy code
Note

The SSE API can return only serializable values (e.g., plain objects, arrays, strings, numbers, booleans, and null). Functions, classes, DOM elements, and other non-serializable objects, like Map or Set, cannot be returned. If your script returns a non-serializable value, the API will attempt to serialize it into a JSON object. However, it may omit some custom properties.

The CKEditor 5 editor instance is available globally as the editor object. You can access all editor methods and properties:

// Get editor content
const content = editor.getData();

// Set editor content
editor.setData('<p>New content</p>');

// Access editor model
const model = editor.model;

// Use editor commands
editor.execute('bold');
Copy code

Scripts have access to most browser and JavaScript APIs, with some restrictions for security reasons.

Refer to the security considerations guide for detailed implementation.

Note

Regular HTTP calls using fetch() or HTTP requests through the editor’s data layer are permitted and can be used to communicate with third-party services.

Authentication

Copy link

All requests to the Server-side Editor API require proper authentication using:

  • X-CS-Timestamp header with the current timestamp
  • X-CS-Signature header with a valid request signature

Refer to the request signature guide for detailed implementation.

Response

Copy link

The API returns a 201 status code on successful execution. The response contains the data returned by your script under the data attribute:

{
  "data": "<p>Editor content</p>"
}
Copy code

For objects returned by your script, the response will be:

{
  "data": {
    "content": "<p>Editor content</p>",
    "wordCount": 5
  }
}
Copy code
Note

The script execution time is limited to 18s. For complex operations, consider breaking them into smaller, more focused scripts.

Error handling

Copy link

When a script fails to execute, the API returns detailed error information. Example error response:

{
    "message": "Editor script failed to evaluate",
    "trace_id": "2daa364a-a658-4123-9630-50497447ed07",
    "status_code": 400,
    "data": {
        "error": {
            "name": "TypeError",
            "message": "Cannot read properties of undefined (reading 'get')",
            "details":[
                "Cannot read properties of undefined (reading 'change')"
            ]
        }
    },
    "level": "trace",
    "explanation": "The provided script cannot be evaluated due to the attached error",
    "action": "Please check the error and script syntax or contact support if the problem persists"
}
Copy code

The data.error.details field contains an array of intercepted and parsed browser console errors, which can help you identify the root cause of script execution failures.

Note

Serialization omits custom error attributes, as only serializable content can be returned. In this case, it only preserves the name and message properties in the response.

Debugging and Testing

Copy link

When developing and testing your editor scripts, you can enable the debug mode by setting the debug: true parameter in your API request. This will allow you to collect the console.debug logs from the script execution. It can be helpful for troubleshooting and understanding script behavior.

{
    "script": "console.debug('Processing editor data', { wordCount: editor.getData().length }); return editor.getData();",
    "debug": true
}
Copy code

With debug mode enabled, any console.debug() calls in your script will be captured and included in the response. This provides additional insight into your script’s execution flow:

{
    "data": "<p>Editor content</p>",
    "metadata": {
        "logs": [
            {
                "type": "debug",
                "createdAt": "2025-08-08T12:00:00.000Z",
                "data": [
                    "Processing editor data",
                    { "wordCount": 245 }
                ]
            }
        ]
    }
}
Copy code

In order to improve the debugging experience in case of an error tracking process, the evaluation error also includes the collected logs during the script evaluation. This means that if a script fails to execute when debug mode is enabled, you will receive both the error details and any debug logs that were captured before the failure occurred, providing valuable context for troubleshooting script issues.

{
    "message": "Editor script failed to evaluate",
    "trace_id": "2daa364a-a658-4123-9630-50497447ed07",
    "status_code": 400,
    "data": {
        "error": {
            "name": "TypeError",
            "message": "Cannot read properties of undefined (reading 'get')",
        },
        "logs": [
            {
                "createdAt": "2025-08-08T12:00:00.000Z",
                "type": "debug",
                "data": [
                    "Processing editor data",
                    { "wordCount": 245 }
                ]
            }
        ]
    },
    "explanation": "The provided script cannot be evaluated due to the attached error",
    "action": "Please check the error and script syntax or contact support if the problem persists"
}
Copy code

Please remember, that only serializable objects can be outputted in debug logs. Custom error attributes and non-serializable content will be omitted from the response.

Note

Debug mode is disabled by default. Only enable it during development and testing, as it may impact performance in production environments.

Next steps

Copy link