Version History
Aphex tracks every draft save and publish, lets editors browse the history, and supports one-click restore.
Every change to a document — draft saves and publishes — is captured as an immutable snapshot in the cms_document_versions table. Editors can browse history from the document editor, restore any version with one click, and the system rolls older versions out automatically once the configured cap is reached.
Configuration
Tune retention in aphex.config.ts:
createCMSConfig({
versioning: {
maxVersions: 25 // default; the oldest entries are pruned on write
}
});Prop
Type
Versions store full snapshots of the document data. If you set maxVersions: 0, large documents
with frequent edits can grow the table quickly — keep an eye on storage.
What gets recorded
Each row in cms_document_versions captures:
Prop
Type
HTTP API
The endpoints are mounted under each document. All three require document.read (or document.update for restore).
List versions
GET /api/documents/{id}/versions?limit=25&offset=0Returns versions newest-first, with the author resolved to a createdByName.
{
"success": true,
"data": [
{
"id": "ver_abc",
"documentId": "doc_xyz",
"versionNumber": 14,
"eventType": "publish",
"data": { "title": "Hello", "body": "..." },
"createdBy": "user_123",
"createdByName": "Ada Lovelace",
"createdAt": "2026-04-25T17:32:00Z"
}
],
"total": 14
}Get a specific version
GET /api/documents/{id}/versions/{versionNumber}Restore a version
POST /api/documents/{id}/versions/{versionNumber}/restoreRestoring replaces the document's draft with the snapshot's data and writes a new version (with eventType: 'draft') recording the restore. Published data is untouched until the editor explicitly publishes again.
curl -X POST \
-H "x-api-key: $KEY" \
"https://your-app.com/api/documents/doc_xyz/versions/8/restore"The response contains the restored document, ready to be loaded back into the editor.
In the admin UI
The document editor ships with a version history panel. From there editors can:
Browse every snapshot taken for the current document, grouped by date with a coloured pill marking publish vs draft events.
Preview any historical version side-by-side with the current draft to see what changed before committing to a restore.
Restore with one click. The current draft is replaced with the snapshot, and a new draft-event version is written so the action itself is auditable.
Programmatic access
The Local API exposes a versionService for scripts and migrations:
import { authToContext } from '@aphexcms/cms-core/server';
const api = locals.aphexCMS.localAPI;
const adapter = locals.aphexCMS.databaseAdapter;
const ctx = authToContext(locals.auth);
const { versions, total } = await api.versionService.listVersions(adapter, ctx.organizationId, 'doc_xyz', {
limit: 50,
offset: 0
});
const target = await api.versionService.getVersion(adapter, ctx.organizationId, 'doc_xyz', 8);
// Returns the restored document, or `null` if the version doesn't exist.
const restored = await api.versionService.restoreVersion(
adapter,
ctx.organizationId,
'doc_xyz',
8,
ctx.user?.id
);See also
Last updated on