Skip to content

Autosaves

Autosaves write a draft copy of the current template to your backend at a fixed interval, so an interrupted session can be restored from the editor's autosave panel.

Autosaving is off until enabled, and every draft travels through your own API endpoints, which keeps the stored history on your infrastructure.

Enabling autosaves

Add the following setting to TOPOL_OPTIONS:

ts
enableAutosaves: true,

Setting the autosave frequency

The autosaveInterval option controls how often a draft is written. The value is in seconds, and the default is 60 seconds when the option is omitted.

ts
autosaveInterval: 60 * 3, // Saves every 3 minutes

Values below 30 are raised to 30 seconds. A request is only sent when the template has unsaved changes, so an idle editor produces no autosave traffic at all.

Autosaves are attributed to a person through the current user object described in Current user.

INFO

TopolPlugin.toggleAutosaves() opens and closes the autosave panel from your own UI.

API integration for autosaves

Autosaves use three separate API paths, each configured independently. Pointing only AUTOSAVES at your backend is a common mistake, because the create call goes to AUTOSAVE instead.

Path keyPurpose
AUTOSAVESLists existing autosaves
AUTOSAVECreates a new autosave
GET_AUTOSAVERetrieves one autosave by key

WARNING

Before implementing the endpoints, check how to work with API endpoints.

List Autosaves

Called to fetch the list of autosaved drafts for the current template and user.

  • URL: /{API.AUTOSAVES}
  • Method: GET
  • Params: key, hostname, templateId, uuid

Response:

json
{
  "success": true,
  "data": [
    {
      "key": "autosaveKey", // used in the GET_AUTOSAVE path when retrieving this autosave
      "time": "2025-05-01T12:00:00Z", // ISO 8601 time
      "created_by": {
        "user_id": 0,
        "name": "John Doe",
        "profile_photo_url": "https://example.com/profile.jpg"
      }
    }
  ]
}

key and time are both required, and time has to be a parseable date. The list is validated as a whole, so a single malformed entry leaves the panel empty rather than dropping just that row.

created_by is optional and only enriches the display. When it is omitted the panel shows the timestamp alone. When it is present, all three of user_id, name and profile_photo_url have to be there, otherwise the editor discards the object and falls back to the timestamp.

Create Autosave

Called when the editor creates a new autosave. Store the template JSON, the creation time, the user ID and a unique key, since that key is what the editor sends back when restoring.

  • URL: /{API.AUTOSAVE}
  • Method: POST

Request:

json
{
  "definition": "{...}", // JSON string of the email template (MJML in JSON)
  "key": "api key value",
  "hostname": "origin",
  "templateId": "id of the template",
  "uuid": "userId",
  "current_user_id": "id of the current user" // provided in the current user identification object
}

definition arrives as a serialized JSON string, not an object. current_user_id is only included when a current user is configured.

Response:

HTTP 200 OK

Get a Specific Autosave

Called to retrieve a previously saved autosave by its key, which the editor appends to the GET_AUTOSAVE path.

  • URL: /{API.GET_AUTOSAVE}/{autosave-key}
  • Method: GET
  • Params: key, hostname, templateId, uuid

Response:

json
{
  "success": true,
  "data": {
    "template": "{...}" // JSON string of the saved template
  }
}

template has to be a JSON string, matching what was sent as definition. The editor parses it, so returning a nested object here fails.