API 參考
Revisions
Management API: GET /sites/{id}/revisions, GET /sites/{id}/revisions/{revisionId}, POST /sites/{id}/revisions/{revisionId}/restore
List content revisions for a website draft (subject: WEBSITE, subjectId omitted or equal to websiteId), a blog post (subject: BLOG_POST, subjectId: postId), or a custom collection item (subject: CONTENT_ITEM, subjectId: itemId). Revisions are retained for 30 days and coalesced within 10-minute autosave windows. Optionally pass pageId when listing WEBSITE revisions to filter to edits that touched that page. Newest first. Errors: FORBIDDEN, INVALID_CURSOR.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
subject"WEBSITE" | "BLOG_POST" | "CONTENT_ITEM" · queryDefaults to WEBSITE.
subjectIdstring · queryRequired unless subject is WEBSITE (pass postId for BLOG_POST, itemId for CONTENT_ITEM); defaults to websiteId for WEBSITE.
pageIdstring · queryOptional filter for WEBSITE revisions: only revisions that modified this page or whole-site checkpoints.
limitinteger · queryMaximum number of items to return, 1–100. Defaults to 20.
cursorstring · queryOpaque cursor from the previous page's nextCursor. Omit for the first page.
Response 200
dataobject[]requireddata[].idstringrequireddata[].websiteIdstringrequireddata[].subject"WEBSITE" | "BLOG_POST" | "CONTENT_ITEM"requiredSubject type: WEBSITE for site-wide draft and page sections, BLOG_POST for a blog article, CONTENT_ITEM for a custom collection item.
data[].subjectIdstringrequireddata[].kind"AUTO" | "PUBLISH" | "PRE_RESTORE" | "PRE_AI" | "MANUAL"requiredWhy the revision was recorded.
data[].schemaVersionintegerrequireddata[].contentHashstringrequireddata[].summaryobject | nullrequireddata[].summary.titlestringdata[].summary.editedPageIdsstring[]data[].summary.editedPageTitlesobjectdata[].summary.editedScopes"sections" | "header" | "footer" | "siteSettings" | "theme" | "pages"[]data[].summary.collectionKeystringCONTENT_ITEM only: the collection this item belongs to.
data[].summary.status"draft" | "published" | "changed"CONTENT_ITEM only.
data[].summary.backup"beforeDelete"Set when the system recorded this revision automatically (e.g. right before the item was moved to the trash).
data[].labelstring | nullrequireddata[].actorobjectrequireddata[].actor.idstring | nullrequireddata[].actor.namestring | nullrequireddata[].actor.emailstring | nullrequireddata[].actor.imagestring | nullrequireddata[].actor.isAgentbooleanrequiredTrue when the revision was written through an API token or MCP client.
data[].actor.tokenNamestring | nulldata[].createdAtstringrequireddata[].updatedAtstringrequiredhasMorebooleanrequiredTrue when another page exists; pass nextCursor to fetch it.
nextCursorstring | nullrequiredCursor for the next page, or null on the last page.
Errors
FORBIDDEN403INVALID_CURSOR400
MCP tool revisions_list
curl -X GET "https://app.kanorio.com/api/v1/sites/{id}/revisions?subject=WEBSITE&limit=20" \
-H "Authorization: Bearer $KANORIO_TOKEN"{
"data": [
{
"id": "rev_example01",
"websiteId": "ws_example123",
"subject": "WEBSITE",
"subjectId": "ws_example123",
"kind": "AUTO",
"schemaVersion": 1,
"contentHash": "a1b2c3d4:1240",
"summary": {
"editedPageIds": [
"pg_example456"
],
"editedPageTitles": {
"pg_example456": "Home"
},
"editedScopes": [
"sections"
]
},
"label": null,
"actor": {
"id": "usr_example01",
"name": "Sunny Lin",
"email": "sunny@example.com",
"image": null,
"isAgent": true,
"tokenName": "Cursor MCP"
},
"createdAt": "2026-10-01T02:30:00.000Z",
"updatedAt": "2026-10-06T08:00:00.000Z"
}
],
"hasMore": false,
"nextCursor": null
}Retrieve a revision
/sites/{id}/revisions/{revisionId}Get the full unpacked snapshot of a content revision by revisionId. Media references belonging to this site's library are presented as asset:<assetId> with display metadata in assets. Errors: FORBIDDEN, REVISION_NOT_FOUND.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
revisionIdstring · pathrequiredRevision identifier from revisions.list.
Response 200
revisionobjectrequiredrevision.idstringrequiredrevision.websiteIdstringrequiredrevision.subject"WEBSITE" | "BLOG_POST" | "CONTENT_ITEM"requiredSubject type: WEBSITE for site-wide draft and page sections, BLOG_POST for a blog article, CONTENT_ITEM for a custom collection item.
revision.subjectIdstringrequiredrevision.kind"AUTO" | "PUBLISH" | "PRE_RESTORE" | "PRE_AI" | "MANUAL"requiredWhy the revision was recorded.
revision.schemaVersionintegerrequiredrevision.contentHashstringrequiredrevision.summaryobject | nullrequiredrevision.summary.titlestringrevision.summary.editedPageIdsstring[]revision.summary.editedPageTitlesobjectrevision.summary.editedScopes"sections" | "header" | "footer" | "siteSettings" | "theme" | "pages"[]revision.summary.collectionKeystringCONTENT_ITEM only: the collection this item belongs to.
revision.summary.status"draft" | "published" | "changed"CONTENT_ITEM only.
revision.summary.backup"beforeDelete"Set when the system recorded this revision automatically (e.g. right before the item was moved to the trash).
revision.labelstring | nullrequiredrevision.actorobjectrequiredrevision.actor.idstring | nullrequiredrevision.actor.namestring | nullrequiredrevision.actor.emailstring | nullrequiredrevision.actor.imagestring | nullrequiredrevision.actor.isAgentbooleanrequiredTrue when the revision was written through an API token or MCP client.
revision.actor.tokenNamestring | nullrevision.createdAtstringrequiredrevision.updatedAtstringrequiredsnapshotobjectrequiredassetsobjectrequired
Errors
FORBIDDEN403REVISION_NOT_FOUND404
MCP tool revisions_get
curl -X GET "https://app.kanorio.com/api/v1/sites/{id}/revisions/{revisionId}" \
-H "Authorization: Bearer $KANORIO_TOKEN"{
"revision": {
"id": "rev_example01",
"websiteId": "ws_example123",
"subject": "WEBSITE",
"subjectId": "ws_example123",
"kind": "AUTO",
"schemaVersion": 1,
"contentHash": "a1b2c3d4:1240",
"summary": {
"editedPageIds": [
"pg_example456"
],
"editedPageTitles": {
"pg_example456": "Home"
},
"editedScopes": [
"sections"
]
},
"label": null,
"actor": {
"id": "usr_example01",
"name": "Sunny Lin",
"email": "sunny@example.com",
"image": null,
"isAgent": true,
"tokenName": "Cursor MCP"
},
"createdAt": "2026-10-01T02:30:00.000Z",
"updatedAt": "2026-10-06T08:00:00.000Z"
},
"snapshot": {
"siteSettings": {},
"globalSections": [],
"themeSettings": {
"sectionDensity": "standard"
},
"pages": [
{
"id": "pg_example456",
"slug": "/",
"title": "Home",
"isHomePage": true,
"sections": []
}
]
},
"assets": {}
}Restore a revision
/sites/{id}/revisions/{revisionId}/restoreRestore a website draft, blog post working copy, or custom collection item to a previous revision. Before writing, the current draft is automatically backed up as a PRE_RESTORE revision so the restore itself can be undone. Restoring writes only to the draft/working copy and never alters the live published site directly; call site.publish, posts.publish or items.publish to publish. For WEBSITE revisions, pass mode: "page" with pageId to restore only a single page's sections, or mode: "full" (default) to restore the entire site draft and theme settings. A CONTENT_ITEM that is in the trash cannot be restored to a revision (SUBJECT_NOT_FOUND): call items.restore first. Errors: FORBIDDEN, REVISION_NOT_FOUND, SUBJECT_NOT_FOUND, PAGE_NOT_FOUND_IN_REVISION, PAGE_NOT_FOUND_IN_SITE, VALIDATION_FAILED, WRITE_FROZEN.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
revisionIdstring · pathrequiredRevision identifier from revisions.list.
Request body
mode"full" | "page"Defaults to "full". Use "page" with pageId to restore only one page of a WEBSITE revision.
pageIdstringRequired when mode is "page".
Response 200
restoredtruerequiredsubject"WEBSITE" | "BLOG_POST" | "CONTENT_ITEM"requiredSubject type: WEBSITE for site-wide draft and page sections, BLOG_POST for a blog article, CONTENT_ITEM for a custom collection item.
subjectIdstringrequiredrevisionIdstringrequiredpreRestoreRevisionIdstring | nullrequiredkind"AUTO" | "PUBLISH" | "PRE_RESTORE" | "PRE_AI" | "MANUAL"requiredWhy the revision was recorded.
mode"full" | "page"requiredpageIdstringResolved page id when mode is page.
collectionKeystringCONTENT_ITEM only: the collection this item belongs to.
Errors
FORBIDDEN403REVISION_NOT_FOUND404SUBJECT_NOT_FOUND404PAGE_NOT_FOUND_IN_REVISION422PAGE_NOT_FOUND_IN_SITE422VALIDATION_FAILED422WRITE_FROZEN503
MCP tool revisions_restore
curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/revisions/{revisionId}/restore" \
-H "Authorization: Bearer $KANORIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"mode":"page","pageId":"pg_example456"}'{
"restored": true,
"subject": "WEBSITE",
"subjectId": "ws_example123",
"revisionId": "rev_example01",
"preRestoreRevisionId": "rev_backup01",
"kind": "AUTO",
"mode": "page"
}