API reference
Items
Management API: GET /sites/{id}/collections/{key}/items, POST /sites/{id}/collections/{key}/items, POST /sites/{id}/collections/{key}/items/bulk, …
List or query items with the same filter/sort DSL the Content Delivery API uses: AND of up to 10 conditions, 3 sort fields, cursor paging (limit + cursor from the previous page's nextCursor). source=draft (default) includes unpublished edits; source=published returns only what the public API serves. pendingReview=true returns only items submitted for review (items.request_review) and not yet published or rejected. Over REST (GET) pass filter and sort as JSON strings, e.g. ?filter={"subjects":{"has":"math"}}&sort=-publishedAt. Errors: FORBIDDEN, COLLECTION_NOT_FOUND, VALIDATION (details.queryIssues: unknown field, op not allowed for the type, invalid value), INVALID_CURSOR.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
keystring · pathrequiredCollection key (slug). Get it from collections.list.
source"draft" | "published" · querystatus"draft" | "published" | "changed" · queryOnly with source=draft.
pendingReviewboolean · queryOnly with source=draft: true returns only items awaiting review.
filterobject | string · querysortstring | object[] · queryArray of { field, direction } or a comma-separated shorthand, e.g. "-publishedAt,name".
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.
fieldsstring[] · queryOnly return these fieldIds.
expandstring[] · queryReference fields to expand one level (id, slug, title).
Response 200
dataobject[]requireddata[].idstringrequireddata[].collectionKeystringrequireddata[].slugstringrequireddata[].status"draft" | "published" | "changed"requiredchanged = published, but the draft has unpublished edits.
data[].titlestringrequireddata[].fieldDataobjectrequiredDraft values (what the dashboard shows).
data[].publishedFieldDataobject | nullrequiredWhat the Content Delivery API serves; null when never published or unpublished.
data[].publishedSlugstring | nullrequireddata[].publishedAtstring | nullrequireddata[].sortOrderintegerrequireddata[].createdAtstringrequireddata[].updatedAtstringrequireddata[].archivedAtstring | nullrequiredSet when the item is in the trash (soft-deleted by items.delete); null otherwise. Trashed items still count against the plan's item quota until purged.
data[].reviewRequestedAtstring | nullrequiredSet by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.
data[].reviewRequestedByUserIdstring | nullrequiredWho last requested review; kept after a rejection so items.request_review can be called again by the same person.
data[].reviewNotestring | nullrequiredReason from the last items.reject_review call; cleared on the next request or successful publish.
data[].scheduledAtstring | nullrequiredSet by items.publish with scheduledAt; non-null means it will be published at this future time from a frozen snapshot. Cleared on items.unschedule or when published.
hasMorebooleanrequiredTrue when another page exists; pass nextCursor to fetch it.
nextCursorstring | nullrequiredCursor for the next page, or null on the last page.
Errors
FORBIDDEN403COLLECTION_NOT_FOUND404VALIDATION400 · details.queryIssues: unknown field, op not allowed for the type, invalid valueINVALID_CURSOR400
MCP tool items_list
curl -X GET "https://app.kanorio.com/api/v1/sites/{id}/collections/{key}/items?source=published&filter=%7B%22subjects%22%3A%7B%22has%22%3A%22math%22%7D%2C%22name%22%3A%7B%22contains%22%3A%22chen%22%7D%7D&sort=-publishedAt%2Cname&limit=20" \
-H "Authorization: Bearer $KANORIO_TOKEN"{
"data": [
{
"id": "item_example01",
"collectionKey": "teachers",
"slug": "amy-chen",
"status": "published",
"title": "Amy Chen",
"fieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedFieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedSlug": "amy-chen",
"publishedAt": "2026-10-06T08:00:00.000Z",
"sortOrder": 0,
"createdAt": "2026-10-01T02:30:00.000Z",
"updatedAt": "2026-10-06T08:00:00.000Z",
"archivedAt": null,
"reviewRequestedAt": null,
"reviewRequestedByUserId": null,
"reviewNote": null,
"scheduledAt": null
}
],
"hasMore": false,
"nextCursor": null
}Create an item
/sites/{id}/collections/{key}/itemsCreate one item. Values are validated against the collection schema; fix the listed fieldIds on VALIDATION. slug is generated from the title field when omitted. publish defaults to true, but is silently downgraded to false if the token/role has collections:manage without collections:publish (no error; check the returned status). Errors: FORBIDDEN, COLLECTION_NOT_FOUND, VALIDATION (details.issues: fieldId, code, message, example), UNIQUE_CONFLICT, SLUG_TAKEN, PLAN_ITEM_LIMIT_REACHED (details.quota), COLLECTION_ITEM_LIMIT_REACHED, SYSTEM_COLLECTION (blog collections are read-only here; use blog.*).
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
keystring · pathrequiredCollection key (slug). Get it from collections.list.
Idempotency-Keystring · headerClient-chosen key (1-200 chars). Retrying with the same key and the same body returns the original result; the same key with a different body is rejected with IDEMPOTENCY_CONFLICT (409). Keys expire after 24 hours.
Request body
fieldDataobjectrequiredField values keyed by fieldId. Call collections.get first to read the schema (types, required, options, aiHint). Image/gallery/file fields take assetIds from media.upload; reference fields take item ids from the target collection.
slugstringpublishbooleanDefault true: the write is published immediately. false keeps it as a draft (status draft or changed).
Response 201
idstringrequiredcollectionKeystringrequiredslugstringrequiredstatus"draft" | "published" | "changed"requiredchanged = published, but the draft has unpublished edits.
titlestringrequiredfieldDataobjectrequiredDraft values (what the dashboard shows).
publishedFieldDataobject | nullrequiredWhat the Content Delivery API serves; null when never published or unpublished.
publishedSlugstring | nullrequiredpublishedAtstring | nullrequiredsortOrderintegerrequiredcreatedAtstringrequiredupdatedAtstringrequiredarchivedAtstring | nullrequiredSet when the item is in the trash (soft-deleted by items.delete); null otherwise. Trashed items still count against the plan's item quota until purged.
reviewRequestedAtstring | nullrequiredSet by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.
reviewRequestedByUserIdstring | nullrequiredWho last requested review; kept after a rejection so items.request_review can be called again by the same person.
reviewNotestring | nullrequiredReason from the last items.reject_review call; cleared on the next request or successful publish.
scheduledAtstring | nullrequiredSet by items.publish with scheduledAt; non-null means it will be published at this future time from a frozen snapshot. Cleared on items.unschedule or when published.
Errors
FORBIDDEN403COLLECTION_NOT_FOUND404VALIDATION400 · details.issues: fieldId, code, message, exampleUNIQUE_CONFLICT409SLUG_TAKEN409PLAN_ITEM_LIMIT_REACHED403 · details.quotaCOLLECTION_ITEM_LIMIT_REACHED403SYSTEM_COLLECTION409 · blog collections are read-only here; use blog.*
MCP tool items_create
curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/collections/{key}/items" \
-H "Authorization: Bearer $KANORIO_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"fieldData":{"name":"Amy Chen","avatar":"asset_example01","subjects":["math","physics"],"bio":"Ten years of teaching high-school math.","website":"https://amychen.example.com","course":"item_example02"},"publish":true}'{
"id": "item_example01",
"collectionKey": "teachers",
"slug": "amy-chen",
"status": "published",
"title": "Amy Chen",
"fieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedFieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedSlug": "amy-chen",
"publishedAt": "2026-10-06T08:00:00.000Z",
"sortOrder": 0,
"createdAt": "2026-10-01T02:30:00.000Z",
"updatedAt": "2026-10-06T08:00:00.000Z",
"archivedAt": null,
"reviewRequestedAt": null,
"reviewRequestedByUserId": null,
"reviewNote": null,
"scheduledAt": null
}Bulk create
/sites/{id}/collections/{key}/items/bulkCreate up to 200 items in one transaction (all or nothing). On failure nothing is written and failed[] lists each bad entry by index with its issues. publish defaults to true, but is silently downgraded to false if the token/role has collections:manage without collections:publish. Errors: FORBIDDEN, COLLECTION_NOT_FOUND, VALIDATION, UNIQUE_CONFLICT, SLUG_TAKEN, PLAN_ITEM_LIMIT_REACHED (details.quota), COLLECTION_ITEM_LIMIT_REACHED, SYSTEM_COLLECTION.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
keystring · pathrequiredCollection key (slug). Get it from collections.list.
Request body
itemsobject[]requireditems[].fieldDataobjectrequiredField values keyed by fieldId. Call collections.get first to read the schema (types, required, options, aiHint). Image/gallery/file fields take assetIds from media.upload; reference fields take item ids from the target collection.
items[].slugstringpublishbooleanDefault true: the write is published immediately. false keeps it as a draft (status draft or changed).
Response 201
createdobject[]requiredcreated[].idstringrequiredcreated[].collectionKeystringrequiredcreated[].slugstringrequiredcreated[].status"draft" | "published" | "changed"requiredchanged = published, but the draft has unpublished edits.
created[].titlestringrequiredcreated[].fieldDataobjectrequiredDraft values (what the dashboard shows).
created[].publishedFieldDataobject | nullrequiredWhat the Content Delivery API serves; null when never published or unpublished.
created[].publishedSlugstring | nullrequiredcreated[].publishedAtstring | nullrequiredcreated[].sortOrderintegerrequiredcreated[].createdAtstringrequiredcreated[].updatedAtstringrequiredcreated[].archivedAtstring | nullrequiredSet when the item is in the trash (soft-deleted by items.delete); null otherwise. Trashed items still count against the plan's item quota until purged.
created[].reviewRequestedAtstring | nullrequiredSet by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.
created[].reviewRequestedByUserIdstring | nullrequiredWho last requested review; kept after a rejection so items.request_review can be called again by the same person.
created[].reviewNotestring | nullrequiredReason from the last items.reject_review call; cleared on the next request or successful publish.
created[].scheduledAtstring | nullrequiredSet by items.publish with scheduledAt; non-null means it will be published at this future time from a frozen snapshot. Cleared on items.unschedule or when published.
failedobject[]requiredfailed[].indexintegerrequiredfailed[].errorobjectrequiredfailed[].error.codestringrequiredfailed[].error.messagestringrequiredfailed[].error.issuesany[]failed[].error.conflictobjectPresent when code is CONFLICT: the item's current updatedAt to re-read and retry with.
Errors
FORBIDDEN403COLLECTION_NOT_FOUND404VALIDATION400UNIQUE_CONFLICT409SLUG_TAKEN409PLAN_ITEM_LIMIT_REACHED403 · details.quotaCOLLECTION_ITEM_LIMIT_REACHED403SYSTEM_COLLECTION409
MCP tool items_bulk_create
curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/collections/{key}/items/bulk" \
-H "Authorization: Bearer $KANORIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"items":[{"fieldData":{"name":"Amy Chen","avatar":"asset_example01","subjects":["math","physics"],"bio":"Ten years of teaching high-school math.","website":"https://amychen.example.com","course":"item_example02"}},{"fieldData":{"name":"Ben Lin","subjects":["english"]}}],"publish":true}'{
"created": [
{
"id": "item_example01",
"collectionKey": "teachers",
"slug": "amy-chen",
"status": "published",
"title": "Amy Chen",
"fieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedFieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedSlug": "amy-chen",
"publishedAt": "2026-10-06T08:00:00.000Z",
"sortOrder": 0,
"createdAt": "2026-10-01T02:30:00.000Z",
"updatedAt": "2026-10-06T08:00:00.000Z",
"archivedAt": null,
"reviewRequestedAt": null,
"reviewRequestedByUserId": null,
"reviewNote": null,
"scheduledAt": null
},
{
"id": "item_example03",
"collectionKey": "teachers",
"slug": "ben-lin",
"status": "published",
"title": "Ben Lin",
"fieldData": {
"name": "Ben Lin",
"subjects": [
"english"
]
},
"publishedFieldData": {
"name": "Ben Lin",
"subjects": [
"english"
]
},
"publishedSlug": "ben-lin",
"publishedAt": "2026-10-06T08:00:00.000Z",
"sortOrder": 1,
"createdAt": "2026-10-01T02:30:00.000Z",
"updatedAt": "2026-10-06T08:00:00.000Z",
"archivedAt": null,
"reviewRequestedAt": null,
"reviewRequestedByUserId": null,
"reviewNote": null,
"scheduledAt": null
}
],
"failed": []
}Bulk update
/sites/{id}/collections/{key}/items/bulkUpdate up to 200 items in one transaction (all or nothing); each entry is a partial update by itemId. publish defaults to true, but is silently downgraded to false if the token/role has collections:manage without collections:publish. Pass ifUnmodifiedSince per entry (the updatedAt from items.list) to abort the whole batch instead of silently overwriting items changed since you read them; the stale entries are reported in failed[] with code CONFLICT. If any item in the batch was submitted for review (items.request_review) and publish resolves to true, warning is set to REVIEW_CONTENT_CHANGED when its content differs from what was submitted (publish still proceeds). Errors: FORBIDDEN, COLLECTION_NOT_FOUND, ITEM_NOT_FOUND, VALIDATION, UNIQUE_CONFLICT, SLUG_TAKEN, CONFLICT, SYSTEM_COLLECTION.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
keystring · pathrequiredCollection key (slug). Get it from collections.list.
Request body
itemsobject[]requireditems[].itemIdstringrequiredItem id. Get it from items.list.
items[].fieldDataobjectrequiredField values keyed by fieldId. Call collections.get first to read the schema (types, required, options, aiHint). Image/gallery/file fields take assetIds from media.upload; reference fields take item ids from the target collection.
items[].slugstringitems[].ifUnmodifiedSincestringISO-8601 timestamp with timezone, e.g. 2026-10-05T12:34:56.789Z.
publishbooleanDefault true: the write is published immediately. false keeps it as a draft (status draft or changed).
Response 200
updatedobject[]requiredupdated[].idstringrequiredupdated[].collectionKeystringrequiredupdated[].slugstringrequiredupdated[].status"draft" | "published" | "changed"requiredchanged = published, but the draft has unpublished edits.
updated[].titlestringrequiredupdated[].fieldDataobjectrequiredDraft values (what the dashboard shows).
updated[].publishedFieldDataobject | nullrequiredWhat the Content Delivery API serves; null when never published or unpublished.
updated[].publishedSlugstring | nullrequiredupdated[].publishedAtstring | nullrequiredupdated[].sortOrderintegerrequiredupdated[].createdAtstringrequiredupdated[].updatedAtstringrequiredupdated[].archivedAtstring | nullrequiredSet when the item is in the trash (soft-deleted by items.delete); null otherwise. Trashed items still count against the plan's item quota until purged.
updated[].reviewRequestedAtstring | nullrequiredSet by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.
updated[].reviewRequestedByUserIdstring | nullrequiredWho last requested review; kept after a rejection so items.request_review can be called again by the same person.
updated[].reviewNotestring | nullrequiredReason from the last items.reject_review call; cleared on the next request or successful publish.
updated[].scheduledAtstring | nullrequiredSet by items.publish with scheduledAt; non-null means it will be published at this future time from a frozen snapshot. Cleared on items.unschedule or when published.
failedobject[]requiredfailed[].indexintegerrequiredfailed[].errorobjectrequiredfailed[].error.codestringrequiredfailed[].error.messagestringrequiredfailed[].error.issuesany[]failed[].error.conflictobjectPresent when code is CONFLICT: the item's current updatedAt to re-read and retry with.
warningstring | nullrequired
Errors
FORBIDDEN403COLLECTION_NOT_FOUND404ITEM_NOT_FOUND404VALIDATION400UNIQUE_CONFLICT409SLUG_TAKEN409CONFLICT409SYSTEM_COLLECTION409
MCP tool items_bulk_update
curl -X PATCH "https://app.kanorio.com/api/v1/sites/{id}/collections/{key}/items/bulk" \
-H "Authorization: Bearer $KANORIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"items":[{"itemId":"item_example01","fieldData":{"subjects":["math"]},"ifUnmodifiedSince":"2026-10-06T08:00:00.000Z"}],"publish":true}'{
"updated": [
{
"id": "item_example01",
"collectionKey": "teachers",
"slug": "amy-chen",
"status": "published",
"title": "Amy Chen",
"fieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedFieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedSlug": "amy-chen",
"publishedAt": "2026-10-06T08:00:00.000Z",
"sortOrder": 0,
"createdAt": "2026-10-01T02:30:00.000Z",
"updatedAt": "2026-10-06T08:00:00.000Z",
"archivedAt": null,
"reviewRequestedAt": null,
"reviewRequestedByUserId": null,
"reviewNote": null,
"scheduledAt": null
}
],
"failed": [],
"warning": null
}Publish an item
/sites/{id}/collections/{key}/items/publishPublish up to 200 items: copies each draft to the public copy. Returns the updated items and ids that were not found. If an item was submitted for review (items.request_review) and its content changed since, warnings[itemId] is set to REVIEW_CONTENT_CHANGED (publish still proceeds). Pass scheduledAt (a future ISO timestamp) to schedule all of them instead: freezes each item's fieldData and slug as a revision and publishes exactly that snapshot when the time comes (further edits to those do not change what gets published); sortOrder is NOT frozen and uses its value at publish time. Cancel per item with items.unschedule. Publishing immediately (here without scheduledAt, or items.update / items.bulk_update with publish: true) cancels any pending schedule, so it will not publish again later. Requires collections:publish (separate from collections:manage). Errors: FORBIDDEN, COLLECTION_NOT_FOUND, VALIDATION (scheduledAt not in the future, or an item is already scheduled: items.unschedule it first to change the time), SYSTEM_COLLECTION.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
keystring · pathrequiredCollection key (slug). Get it from collections.list.
Request body
itemIdsstring[]requiredscheduledAtstringFuture ISO timestamp. When set, schedules instead of publishing immediately.
Response 200
itemsobject[]requireditems[].idstringrequireditems[].collectionKeystringrequireditems[].slugstringrequireditems[].status"draft" | "published" | "changed"requiredchanged = published, but the draft has unpublished edits.
items[].titlestringrequireditems[].fieldDataobjectrequiredDraft values (what the dashboard shows).
items[].publishedFieldDataobject | nullrequiredWhat the Content Delivery API serves; null when never published or unpublished.
items[].publishedSlugstring | nullrequireditems[].publishedAtstring | nullrequireditems[].sortOrderintegerrequireditems[].createdAtstringrequireditems[].updatedAtstringrequireditems[].archivedAtstring | nullrequiredSet when the item is in the trash (soft-deleted by items.delete); null otherwise. Trashed items still count against the plan's item quota until purged.
items[].reviewRequestedAtstring | nullrequiredSet by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.
items[].reviewRequestedByUserIdstring | nullrequiredWho last requested review; kept after a rejection so items.request_review can be called again by the same person.
items[].reviewNotestring | nullrequiredReason from the last items.reject_review call; cleared on the next request or successful publish.
items[].scheduledAtstring | nullrequiredSet by items.publish with scheduledAt; non-null means it will be published at this future time from a frozen snapshot. Cleared on items.unschedule or when published.
missingstring[]requiredwarningstring | nullrequiredREVIEW_CONTENT_CHANGED when any item in this batch was edited after being submitted for review. Always null when scheduling (scheduledAt set).
Errors
FORBIDDEN403COLLECTION_NOT_FOUND404VALIDATION400 · scheduledAt not in the future, or an item is already scheduled: items.unschedule it first to change the timeSYSTEM_COLLECTION409
MCP tool items_publish
curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/collections/{key}/items/publish" \
-H "Authorization: Bearer $KANORIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"itemIds":["item_example01"]}'{
"items": [
{
"id": "item_example01",
"collectionKey": "teachers",
"slug": "amy-chen",
"status": "published",
"title": "Amy Chen",
"fieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedFieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedSlug": "amy-chen",
"publishedAt": "2026-10-06T08:00:00.000Z",
"sortOrder": 0,
"createdAt": "2026-10-01T02:30:00.000Z",
"updatedAt": "2026-10-06T08:00:00.000Z",
"archivedAt": null,
"reviewRequestedAt": null,
"reviewRequestedByUserId": null,
"reviewNote": null,
"scheduledAt": null
}
],
"missing": [],
"warning": null
}Unpublish an item
/sites/{id}/collections/{key}/items/unpublishUnpublish up to 200 items: removes them from the Content Delivery API; drafts are kept. Requires collections:publish (separate from collections:manage). Errors: FORBIDDEN, COLLECTION_NOT_FOUND, VALIDATION, SYSTEM_COLLECTION.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
keystring · pathrequiredCollection key (slug). Get it from collections.list.
Request body
itemIdsstring[]required
Response 200
itemsobject[]requireditems[].idstringrequireditems[].collectionKeystringrequireditems[].slugstringrequireditems[].status"draft" | "published" | "changed"requiredchanged = published, but the draft has unpublished edits.
items[].titlestringrequireditems[].fieldDataobjectrequiredDraft values (what the dashboard shows).
items[].publishedFieldDataobject | nullrequiredWhat the Content Delivery API serves; null when never published or unpublished.
items[].publishedSlugstring | nullrequireditems[].publishedAtstring | nullrequireditems[].sortOrderintegerrequireditems[].createdAtstringrequireditems[].updatedAtstringrequireditems[].archivedAtstring | nullrequiredSet when the item is in the trash (soft-deleted by items.delete); null otherwise. Trashed items still count against the plan's item quota until purged.
items[].reviewRequestedAtstring | nullrequiredSet by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.
items[].reviewRequestedByUserIdstring | nullrequiredWho last requested review; kept after a rejection so items.request_review can be called again by the same person.
items[].reviewNotestring | nullrequiredReason from the last items.reject_review call; cleared on the next request or successful publish.
items[].scheduledAtstring | nullrequiredSet by items.publish with scheduledAt; non-null means it will be published at this future time from a frozen snapshot. Cleared on items.unschedule or when published.
missingstring[]required
Errors
FORBIDDEN403COLLECTION_NOT_FOUND404VALIDATION400SYSTEM_COLLECTION409
MCP tool items_unpublish
curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/collections/{key}/items/unpublish" \
-H "Authorization: Bearer $KANORIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"itemIds":["item_example01"]}'{
"items": [
{
"id": "item_example01",
"collectionKey": "teachers",
"slug": "amy-chen",
"status": "draft",
"title": "Amy Chen",
"fieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedFieldData": null,
"publishedSlug": null,
"publishedAt": null,
"sortOrder": 0,
"createdAt": "2026-10-01T02:30:00.000Z",
"updatedAt": "2026-10-06T08:00:00.000Z",
"archivedAt": null,
"reviewRequestedAt": null,
"reviewRequestedByUserId": null,
"reviewNote": null,
"scheduledAt": null
}
],
"missing": []
}List archived
/sites/{id}/collections/{key}/items/trashList items in the trash (soft-deleted by items.delete), newest first. Use items.restore to bring one back or items.purge to permanently delete it. Errors: FORBIDDEN, COLLECTION_NOT_FOUND, INVALID_CURSOR.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
keystring · pathrequiredCollection key (slug). Get it from collections.list.
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[].collectionKeystringrequireddata[].slugstringrequireddata[].status"draft" | "published" | "changed"requiredchanged = published, but the draft has unpublished edits.
data[].titlestringrequireddata[].fieldDataobjectrequiredDraft values (what the dashboard shows).
data[].publishedFieldDataobject | nullrequiredWhat the Content Delivery API serves; null when never published or unpublished.
data[].publishedSlugstring | nullrequireddata[].publishedAtstring | nullrequireddata[].sortOrderintegerrequireddata[].createdAtstringrequireddata[].updatedAtstringrequireddata[].archivedAtstring | nullrequiredSet when the item is in the trash (soft-deleted by items.delete); null otherwise. Trashed items still count against the plan's item quota until purged.
data[].reviewRequestedAtstring | nullrequiredSet by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.
data[].reviewRequestedByUserIdstring | nullrequiredWho last requested review; kept after a rejection so items.request_review can be called again by the same person.
data[].reviewNotestring | nullrequiredReason from the last items.reject_review call; cleared on the next request or successful publish.
data[].scheduledAtstring | nullrequiredSet by items.publish with scheduledAt; non-null means it will be published at this future time from a frozen snapshot. Cleared on items.unschedule or when published.
hasMorebooleanrequiredTrue when another page exists; pass nextCursor to fetch it.
nextCursorstring | nullrequiredCursor for the next page, or null on the last page.
Errors
FORBIDDEN403COLLECTION_NOT_FOUND404INVALID_CURSOR400
MCP tool items_list_archived
curl -X GET "https://app.kanorio.com/api/v1/sites/{id}/collections/{key}/items/trash" \
-H "Authorization: Bearer $KANORIO_TOKEN"{
"data": [
{
"id": "item_example04",
"collectionKey": "teachers",
"slug": "ben-lin",
"status": "published",
"title": "Ben Lin",
"fieldData": {
"name": "Ben Lin",
"subjects": [
"english"
]
},
"publishedFieldData": null,
"publishedSlug": null,
"publishedAt": null,
"sortOrder": 0,
"createdAt": "2026-10-01T02:30:00.000Z",
"updatedAt": "2026-10-06T08:00:00.000Z",
"archivedAt": "2026-10-06T08:00:00.000Z",
"reviewRequestedAt": null,
"reviewRequestedByUserId": null,
"reviewNote": null,
"scheduledAt": null
}
],
"hasMore": false,
"nextCursor": null
}Retrieve an item
/sites/{id}/collections/{key}/items/{itemId}Get one item by id or slug, with draft and published values. Errors: FORBIDDEN, COLLECTION_NOT_FOUND, ITEM_NOT_FOUND.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
keystring · pathrequiredCollection key (slug). Get it from collections.list.
itemIdstring · pathrequiredItem id or slug.
Response 200
idstringrequiredcollectionKeystringrequiredslugstringrequiredstatus"draft" | "published" | "changed"requiredchanged = published, but the draft has unpublished edits.
titlestringrequiredfieldDataobjectrequiredDraft values (what the dashboard shows).
publishedFieldDataobject | nullrequiredWhat the Content Delivery API serves; null when never published or unpublished.
publishedSlugstring | nullrequiredpublishedAtstring | nullrequiredsortOrderintegerrequiredcreatedAtstringrequiredupdatedAtstringrequiredarchivedAtstring | nullrequiredSet when the item is in the trash (soft-deleted by items.delete); null otherwise. Trashed items still count against the plan's item quota until purged.
reviewRequestedAtstring | nullrequiredSet by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.
reviewRequestedByUserIdstring | nullrequiredWho last requested review; kept after a rejection so items.request_review can be called again by the same person.
reviewNotestring | nullrequiredReason from the last items.reject_review call; cleared on the next request or successful publish.
scheduledAtstring | nullrequiredSet by items.publish with scheduledAt; non-null means it will be published at this future time from a frozen snapshot. Cleared on items.unschedule or when published.
Errors
FORBIDDEN403COLLECTION_NOT_FOUND404ITEM_NOT_FOUND404
MCP tool items_get
curl -X GET "https://app.kanorio.com/api/v1/sites/{id}/collections/{key}/items/{itemId}" \
-H "Authorization: Bearer $KANORIO_TOKEN"{
"id": "item_example01",
"collectionKey": "teachers",
"slug": "amy-chen",
"status": "published",
"title": "Amy Chen",
"fieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedFieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedSlug": "amy-chen",
"publishedAt": "2026-10-06T08:00:00.000Z",
"sortOrder": 0,
"createdAt": "2026-10-01T02:30:00.000Z",
"updatedAt": "2026-10-06T08:00:00.000Z",
"archivedAt": null,
"reviewRequestedAt": null,
"reviewRequestedByUserId": null,
"reviewNote": null,
"scheduledAt": null
}Update an item
/sites/{id}/collections/{key}/items/{itemId}Partially update an item: only the fieldIds you send change; send null to clear a field. publish=false keeps the public copy unchanged (status becomes changed). publish defaults to true, but is silently downgraded to false if the token/role has collections:manage without collections:publish (no error; check the returned status). Pass ifUnmodifiedSince (the updatedAt from items.get/items.list) to avoid silently overwriting a change made by someone else (or another agent run) since you last read it. If the item was submitted for review (items.request_review) and publish resolves to true, warning is set to REVIEW_CONTENT_CHANGED when the content differs from what was submitted (publish still proceeds). Errors: FORBIDDEN, COLLECTION_NOT_FOUND, ITEM_NOT_FOUND, CONFLICT (details.conflict.updatedAt: re-read and retry), VALIDATION (details.issues: fieldId, code, message, example), UNIQUE_CONFLICT, SLUG_TAKEN, PLAN_ITEM_LIMIT_REACHED (details.quota), COLLECTION_ITEM_LIMIT_REACHED, SYSTEM_COLLECTION (blog collections are read-only here; use blog.*).
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
keystring · pathrequiredCollection key (slug). Get it from collections.list.
itemIdstring · pathrequiredItem id. Get it from items.list.
Request body
fieldDataobjectField values keyed by fieldId. Call collections.get first to read the schema (types, required, options, aiHint). Image/gallery/file fields take assetIds from media.upload; reference fields take item ids from the target collection.
slugstringsortOrderintegerpublishbooleanDefault true: the write is published immediately. false keeps it as a draft (status draft or changed).
ifUnmodifiedSincestringISO-8601 timestamp with timezone, e.g. 2026-10-05T12:34:56.789Z.
Response 200
idstringrequiredcollectionKeystringrequiredslugstringrequiredstatus"draft" | "published" | "changed"requiredchanged = published, but the draft has unpublished edits.
titlestringrequiredfieldDataobjectrequiredDraft values (what the dashboard shows).
publishedFieldDataobject | nullrequiredWhat the Content Delivery API serves; null when never published or unpublished.
publishedSlugstring | nullrequiredpublishedAtstring | nullrequiredsortOrderintegerrequiredcreatedAtstringrequiredupdatedAtstringrequiredarchivedAtstring | nullrequiredSet when the item is in the trash (soft-deleted by items.delete); null otherwise. Trashed items still count against the plan's item quota until purged.
reviewRequestedAtstring | nullrequiredSet by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.
reviewRequestedByUserIdstring | nullrequiredWho last requested review; kept after a rejection so items.request_review can be called again by the same person.
reviewNotestring | nullrequiredReason from the last items.reject_review call; cleared on the next request or successful publish.
scheduledAtstring | nullrequiredSet by items.publish with scheduledAt; non-null means it will be published at this future time from a frozen snapshot. Cleared on items.unschedule or when published.
warningstring | nullrequired
Errors
FORBIDDEN403COLLECTION_NOT_FOUND404ITEM_NOT_FOUND404CONFLICT409 · details.conflict.updatedAt: re-read and retryVALIDATION400 · details.issues: fieldId, code, message, exampleUNIQUE_CONFLICT409SLUG_TAKEN409PLAN_ITEM_LIMIT_REACHED403 · details.quotaCOLLECTION_ITEM_LIMIT_REACHED403SYSTEM_COLLECTION409 · blog collections are read-only here; use blog.*
MCP tool items_update
curl -X PATCH "https://app.kanorio.com/api/v1/sites/{id}/collections/{key}/items/{itemId}" \
-H "Authorization: Bearer $KANORIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"fieldData":{"bio":"Updated bio, not yet published."},"publish":false}'{
"id": "item_example01",
"collectionKey": "teachers",
"slug": "amy-chen",
"status": "changed",
"title": "Amy Chen",
"fieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Updated bio, not yet published.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedFieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedSlug": "amy-chen",
"publishedAt": "2026-10-06T08:00:00.000Z",
"sortOrder": 0,
"createdAt": "2026-10-01T02:30:00.000Z",
"updatedAt": "2026-10-06T08:00:00.000Z",
"archivedAt": null,
"reviewRequestedAt": null,
"reviewRequestedByUserId": null,
"reviewNote": null,
"scheduledAt": null,
"warning": null
}Delete an item
/sites/{id}/collections/{key}/items/{itemId}Move one item to the trash (soft delete; it still counts against the plan's item quota). Use items.restore to bring it back or items.purge to permanently delete it and free its quota. Refused with REFERENCED (details.referencedBy) while other items reference it, unless force=true (readers then ignore the dangling id). Errors: FORBIDDEN, COLLECTION_NOT_FOUND, ITEM_NOT_FOUND, REFERENCED, SYSTEM_COLLECTION.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
keystring · pathrequiredCollection key (slug). Get it from collections.list.
itemIdstring · pathrequiredItem id. Get it from items.list.
forceboolean · query
Response 200
idstringrequired
Errors
FORBIDDEN403COLLECTION_NOT_FOUND404ITEM_NOT_FOUND404REFERENCED409SYSTEM_COLLECTION409
MCP tool items_delete
curl -X DELETE "https://app.kanorio.com/api/v1/sites/{id}/collections/{key}/items/{itemId}?force=false" \
-H "Authorization: Bearer $KANORIO_TOKEN"{
"id": "item_example01"
}Restore an item
/sites/{id}/collections/{key}/items/{itemId}/restoreRestore a trashed item back to its collection (status and content unchanged; still not re-published automatically if it was published before deletion but a draft-only edit happened — call items.publish if needed). Errors: FORBIDDEN, COLLECTION_NOT_FOUND, ITEM_NOT_FOUND, NOT_ARCHIVED.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
keystring · pathrequiredCollection key (slug). Get it from collections.list.
itemIdstring · pathrequiredItem id. Get it from items.list.
Response 200
idstringrequiredcollectionKeystringrequiredslugstringrequiredstatus"draft" | "published" | "changed"requiredchanged = published, but the draft has unpublished edits.
titlestringrequiredfieldDataobjectrequiredDraft values (what the dashboard shows).
publishedFieldDataobject | nullrequiredWhat the Content Delivery API serves; null when never published or unpublished.
publishedSlugstring | nullrequiredpublishedAtstring | nullrequiredsortOrderintegerrequiredcreatedAtstringrequiredupdatedAtstringrequiredarchivedAtstring | nullrequiredSet when the item is in the trash (soft-deleted by items.delete); null otherwise. Trashed items still count against the plan's item quota until purged.
reviewRequestedAtstring | nullrequiredSet by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.
reviewRequestedByUserIdstring | nullrequiredWho last requested review; kept after a rejection so items.request_review can be called again by the same person.
reviewNotestring | nullrequiredReason from the last items.reject_review call; cleared on the next request or successful publish.
scheduledAtstring | nullrequiredSet by items.publish with scheduledAt; non-null means it will be published at this future time from a frozen snapshot. Cleared on items.unschedule or when published.
Errors
FORBIDDEN403COLLECTION_NOT_FOUND404ITEM_NOT_FOUND404NOT_ARCHIVED422
MCP tool items_restore
curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/collections/{key}/items/{itemId}/restore" \
-H "Authorization: Bearer $KANORIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'{
"id": "item_example04",
"collectionKey": "teachers",
"slug": "ben-lin",
"status": "published",
"title": "Ben Lin",
"fieldData": {
"name": "Ben Lin",
"subjects": [
"english"
]
},
"publishedFieldData": null,
"publishedSlug": null,
"publishedAt": null,
"sortOrder": 0,
"createdAt": "2026-10-01T02:30:00.000Z",
"updatedAt": "2026-10-06T08:00:00.000Z",
"archivedAt": null,
"reviewRequestedAt": null,
"reviewRequestedByUserId": null,
"reviewNote": null,
"scheduledAt": null
}Item purge
/sites/{id}/collections/{key}/items/{itemId}/purgePermanently delete a trashed item (must already be in the trash via items.delete). This frees its plan item quota immediately and cannot be undone — the item's version history is deleted along with it. Errors: FORBIDDEN, COLLECTION_NOT_FOUND, ITEM_NOT_FOUND, NOT_ARCHIVED.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
keystring · pathrequiredCollection key (slug). Get it from collections.list.
itemIdstring · pathrequiredItem id. Get it from items.list.
Response 200
idstringrequired
Errors
FORBIDDEN403COLLECTION_NOT_FOUND404ITEM_NOT_FOUND404NOT_ARCHIVED422
MCP tool items_purge
curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/collections/{key}/items/{itemId}/purge" \
-H "Authorization: Bearer $KANORIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'{
"id": "item_example04"
}Request review
/sites/{id}/collections/{key}/items/{itemId}/request-reviewAsk someone with collections:publish to review and publish an item (for a token/role that has collections:manage but not collections:publish). Records the current content hash so items.publish can flag if it changed since review. Errors: FORBIDDEN, COLLECTION_NOT_FOUND, ITEM_NOT_FOUND.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
keystring · pathrequiredCollection key (slug). Get it from collections.list.
itemIdstring · pathrequiredItem id. Get it from items.list.
Response 200
idstringrequiredcollectionKeystringrequiredslugstringrequiredstatus"draft" | "published" | "changed"requiredchanged = published, but the draft has unpublished edits.
titlestringrequiredfieldDataobjectrequiredDraft values (what the dashboard shows).
publishedFieldDataobject | nullrequiredWhat the Content Delivery API serves; null when never published or unpublished.
publishedSlugstring | nullrequiredpublishedAtstring | nullrequiredsortOrderintegerrequiredcreatedAtstringrequiredupdatedAtstringrequiredarchivedAtstring | nullrequiredSet when the item is in the trash (soft-deleted by items.delete); null otherwise. Trashed items still count against the plan's item quota until purged.
reviewRequestedAtstring | nullrequiredSet by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.
reviewRequestedByUserIdstring | nullrequiredWho last requested review; kept after a rejection so items.request_review can be called again by the same person.
reviewNotestring | nullrequiredReason from the last items.reject_review call; cleared on the next request or successful publish.
scheduledAtstring | nullrequiredSet by items.publish with scheduledAt; non-null means it will be published at this future time from a frozen snapshot. Cleared on items.unschedule or when published.
Errors
FORBIDDEN403COLLECTION_NOT_FOUND404ITEM_NOT_FOUND404
MCP tool items_request_review
curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/collections/{key}/items/{itemId}/request-review" \
-H "Authorization: Bearer $KANORIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'{
"id": "item_example01",
"collectionKey": "teachers",
"slug": "amy-chen",
"status": "published",
"title": "Amy Chen",
"fieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedFieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedSlug": "amy-chen",
"publishedAt": "2026-10-06T08:00:00.000Z",
"sortOrder": 0,
"createdAt": "2026-10-01T02:30:00.000Z",
"updatedAt": "2026-10-06T08:00:00.000Z",
"archivedAt": null,
"reviewRequestedAt": "2026-10-06T08:00:00.000Z",
"reviewRequestedByUserId": "usr_example01",
"reviewNote": null,
"scheduledAt": null
}Reject review
/sites/{id}/collections/{key}/items/{itemId}/reject-reviewSend a reviewed item back for changes instead of publishing it, optionally with a note explaining why. Requires collections:publish (separate from collections:manage). Errors: FORBIDDEN, COLLECTION_NOT_FOUND, ITEM_NOT_FOUND, VALIDATION (not pending review).
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
keystring · pathrequiredCollection key (slug). Get it from collections.list.
itemIdstring · pathrequiredItem id. Get it from items.list.
Request body
notestring | null
Response 200
idstringrequiredcollectionKeystringrequiredslugstringrequiredstatus"draft" | "published" | "changed"requiredchanged = published, but the draft has unpublished edits.
titlestringrequiredfieldDataobjectrequiredDraft values (what the dashboard shows).
publishedFieldDataobject | nullrequiredWhat the Content Delivery API serves; null when never published or unpublished.
publishedSlugstring | nullrequiredpublishedAtstring | nullrequiredsortOrderintegerrequiredcreatedAtstringrequiredupdatedAtstringrequiredarchivedAtstring | nullrequiredSet when the item is in the trash (soft-deleted by items.delete); null otherwise. Trashed items still count against the plan's item quota until purged.
reviewRequestedAtstring | nullrequiredSet by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.
reviewRequestedByUserIdstring | nullrequiredWho last requested review; kept after a rejection so items.request_review can be called again by the same person.
reviewNotestring | nullrequiredReason from the last items.reject_review call; cleared on the next request or successful publish.
scheduledAtstring | nullrequiredSet by items.publish with scheduledAt; non-null means it will be published at this future time from a frozen snapshot. Cleared on items.unschedule or when published.
Errors
FORBIDDEN403COLLECTION_NOT_FOUND404ITEM_NOT_FOUND404VALIDATION400 · not pending review
MCP tool items_reject_review
curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/collections/{key}/items/{itemId}/reject-review" \
-H "Authorization: Bearer $KANORIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"note":"The bio needs a quick copyedit before this goes live."}'{
"id": "item_example01",
"collectionKey": "teachers",
"slug": "amy-chen",
"status": "published",
"title": "Amy Chen",
"fieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedFieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedSlug": "amy-chen",
"publishedAt": "2026-10-06T08:00:00.000Z",
"sortOrder": 0,
"createdAt": "2026-10-01T02:30:00.000Z",
"updatedAt": "2026-10-06T08:00:00.000Z",
"archivedAt": null,
"reviewRequestedAt": null,
"reviewRequestedByUserId": "usr_example01",
"reviewNote": "The bio needs a quick copyedit before this goes live.",
"scheduledAt": null
}Unschedule an item
/sites/{id}/collections/{key}/items/{itemId}/unscheduleCancel a scheduled publish (items.publish with scheduledAt) for one item. Leaves the draft and published states untouched. Errors: FORBIDDEN, COLLECTION_NOT_FOUND, ITEM_NOT_FOUND.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
keystring · pathrequiredCollection key (slug). Get it from collections.list.
itemIdstring · pathrequiredItem id. Get it from items.list.
Response 200
idstringrequiredcollectionKeystringrequiredslugstringrequiredstatus"draft" | "published" | "changed"requiredchanged = published, but the draft has unpublished edits.
titlestringrequiredfieldDataobjectrequiredDraft values (what the dashboard shows).
publishedFieldDataobject | nullrequiredWhat the Content Delivery API serves; null when never published or unpublished.
publishedSlugstring | nullrequiredpublishedAtstring | nullrequiredsortOrderintegerrequiredcreatedAtstringrequiredupdatedAtstringrequiredarchivedAtstring | nullrequiredSet when the item is in the trash (soft-deleted by items.delete); null otherwise. Trashed items still count against the plan's item quota until purged.
reviewRequestedAtstring | nullrequiredSet by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.
reviewRequestedByUserIdstring | nullrequiredWho last requested review; kept after a rejection so items.request_review can be called again by the same person.
reviewNotestring | nullrequiredReason from the last items.reject_review call; cleared on the next request or successful publish.
scheduledAtstring | nullrequiredSet by items.publish with scheduledAt; non-null means it will be published at this future time from a frozen snapshot. Cleared on items.unschedule or when published.
Errors
FORBIDDEN403COLLECTION_NOT_FOUND404ITEM_NOT_FOUND404
MCP tool items_unschedule
curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/collections/{key}/items/{itemId}/unschedule" \
-H "Authorization: Bearer $KANORIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'{
"id": "item_example01",
"collectionKey": "teachers",
"slug": "amy-chen",
"status": "published",
"title": "Amy Chen",
"fieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedFieldData": {
"name": "Amy Chen",
"avatar": "asset_example01",
"subjects": [
"math",
"physics"
],
"bio": "Ten years of teaching high-school math.",
"website": "https://amychen.example.com",
"course": "item_example02"
},
"publishedSlug": "amy-chen",
"publishedAt": "2026-10-06T08:00:00.000Z",
"sortOrder": 0,
"createdAt": "2026-10-01T02:30:00.000Z",
"updatedAt": "2026-10-06T08:00:00.000Z",
"archivedAt": null,
"reviewRequestedAt": null,
"reviewRequestedByUserId": null,
"reviewNote": null,
"scheduledAt": null
}