Kanorio

API 参考

Items

Management API: GET /sites/{id}/collections/{key}/items, POST /sites/{id}/collections/{key}/items, POST /sites/{id}/collections/{key}/items/bulk, …

本页只有英文版。API 参考、Webhook 事件和更新日志保持英文,与代码中的字段名称、错误码一致。
Base URL https://app.kanorio.com/api/v1ErrorsPagination

List items

GET/sites/{id}/collections/{key}/items
betacollections:viewdefault (120/minute per token)

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 · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • keystring · pathrequired

    Collection key (slug). Get it from collections.list.

  • source"draft" | "published" · query
  • status"draft" | "published" | "changed" · query

    Only with source=draft.

  • pendingReviewboolean · query

    Only with source=draft: true returns only items awaiting review.

  • filterobject | string · query
  • sortstring | object[] · query

    Array of { field, direction } or a comma-separated shorthand, e.g. "-publishedAt,name".

  • limitinteger · query

    Maximum number of items to return, 1–100. Defaults to 20.

  • cursorstring · query

    Opaque cursor from the previous page's nextCursor. Omit for the first page.

  • fieldsstring[] · query

    Only return these fieldIds.

  • expandstring[] · query

    Reference fields to expand one level (id, slug, title).

Response 200

  • dataobject[]required
  • data[].idstringrequired
  • data[].collectionKeystringrequired
  • data[].slugstringrequired
  • data[].status"draft" | "published" | "changed"required

    changed = published, but the draft has unpublished edits.

  • data[].titlestringrequired
  • data[].fieldDataobjectrequired

    Draft values (what the dashboard shows).

  • data[].publishedFieldDataobject | nullrequired

    What the Content Delivery API serves; null when never published or unpublished.

  • data[].publishedSlugstring | nullrequired
  • data[].publishedAtstring | nullrequired
  • data[].sortOrderintegerrequired
  • data[].createdAtstringrequired
  • data[].updatedAtstringrequired
  • data[].archivedAtstring | nullrequired

    Set 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 | nullrequired

    Set by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.

  • data[].reviewRequestedByUserIdstring | nullrequired

    Who last requested review; kept after a rejection so items.request_review can be called again by the same person.

  • data[].reviewNotestring | nullrequired

    Reason from the last items.reject_review call; cleared on the next request or successful publish.

  • data[].scheduledAtstring | nullrequired

    Set 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.

  • hasMorebooleanrequired

    True when another page exists; pass nextCursor to fetch it.

  • nextCursorstring | nullrequired

    Cursor for the next page, or null on the last page.

Errors

  • FORBIDDEN 403
  • COLLECTION_NOT_FOUND 404
  • VALIDATION 400 · details.queryIssues: unknown field, op not allowed for the type, invalid value
  • INVALID_CURSOR 400

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"
Response
{
  "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

POST/sites/{id}/collections/{key}/items
betacollections:managedefault (120/minute per token)Idempotency-Key

Create 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 · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • keystring · pathrequired

    Collection key (slug). Get it from collections.list.

  • Idempotency-Keystring · header

    Client-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

  • fieldDataobjectrequired

    Field 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.

  • slugstring
  • publishboolean

    Default true: the write is published immediately. false keeps it as a draft (status draft or changed).

Response 201

  • idstringrequired
  • collectionKeystringrequired
  • slugstringrequired
  • status"draft" | "published" | "changed"required

    changed = published, but the draft has unpublished edits.

  • titlestringrequired
  • fieldDataobjectrequired

    Draft values (what the dashboard shows).

  • publishedFieldDataobject | nullrequired

    What the Content Delivery API serves; null when never published or unpublished.

  • publishedSlugstring | nullrequired
  • publishedAtstring | nullrequired
  • sortOrderintegerrequired
  • createdAtstringrequired
  • updatedAtstringrequired
  • archivedAtstring | nullrequired

    Set 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 | nullrequired

    Set by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.

  • reviewRequestedByUserIdstring | nullrequired

    Who last requested review; kept after a rejection so items.request_review can be called again by the same person.

  • reviewNotestring | nullrequired

    Reason from the last items.reject_review call; cleared on the next request or successful publish.

  • scheduledAtstring | nullrequired

    Set 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

  • FORBIDDEN 403
  • COLLECTION_NOT_FOUND 404
  • VALIDATION 400 · details.issues: fieldId, code, message, example
  • UNIQUE_CONFLICT 409
  • SLUG_TAKEN 409
  • PLAN_ITEM_LIMIT_REACHED 403 · details.quota
  • COLLECTION_ITEM_LIMIT_REACHED 403
  • SYSTEM_COLLECTION 409 · 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}'
Response
{
  "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

POST/sites/{id}/collections/{key}/items/bulk
betacollections:managedefault (120/minute per token)

Create 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 · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • keystring · pathrequired

    Collection key (slug). Get it from collections.list.

Request body

  • itemsobject[]required
  • items[].fieldDataobjectrequired

    Field 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[].slugstring
  • publishboolean

    Default true: the write is published immediately. false keeps it as a draft (status draft or changed).

Response 201

  • createdobject[]required
  • created[].idstringrequired
  • created[].collectionKeystringrequired
  • created[].slugstringrequired
  • created[].status"draft" | "published" | "changed"required

    changed = published, but the draft has unpublished edits.

  • created[].titlestringrequired
  • created[].fieldDataobjectrequired

    Draft values (what the dashboard shows).

  • created[].publishedFieldDataobject | nullrequired

    What the Content Delivery API serves; null when never published or unpublished.

  • created[].publishedSlugstring | nullrequired
  • created[].publishedAtstring | nullrequired
  • created[].sortOrderintegerrequired
  • created[].createdAtstringrequired
  • created[].updatedAtstringrequired
  • created[].archivedAtstring | nullrequired

    Set 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 | nullrequired

    Set by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.

  • created[].reviewRequestedByUserIdstring | nullrequired

    Who last requested review; kept after a rejection so items.request_review can be called again by the same person.

  • created[].reviewNotestring | nullrequired

    Reason from the last items.reject_review call; cleared on the next request or successful publish.

  • created[].scheduledAtstring | nullrequired

    Set 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[]required
  • failed[].indexintegerrequired
  • failed[].errorobjectrequired
  • failed[].error.codestringrequired
  • failed[].error.messagestringrequired
  • failed[].error.issuesany[]
  • failed[].error.conflictobject

    Present when code is CONFLICT: the item's current updatedAt to re-read and retry with.

Errors

  • FORBIDDEN 403
  • COLLECTION_NOT_FOUND 404
  • VALIDATION 400
  • UNIQUE_CONFLICT 409
  • SLUG_TAKEN 409
  • PLAN_ITEM_LIMIT_REACHED 403 · details.quota
  • COLLECTION_ITEM_LIMIT_REACHED 403
  • SYSTEM_COLLECTION 409

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}'
Response
{
  "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

PATCH/sites/{id}/collections/{key}/items/bulk
betacollections:managedefault (120/minute per token)

Update 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 · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • keystring · pathrequired

    Collection key (slug). Get it from collections.list.

Request body

  • itemsobject[]required
  • items[].itemIdstringrequired

    Item id. Get it from items.list.

  • items[].fieldDataobjectrequired

    Field 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[].slugstring
  • items[].ifUnmodifiedSincestring

    ISO-8601 timestamp with timezone, e.g. 2026-10-05T12:34:56.789Z.

  • publishboolean

    Default true: the write is published immediately. false keeps it as a draft (status draft or changed).

Response 200

  • updatedobject[]required
  • updated[].idstringrequired
  • updated[].collectionKeystringrequired
  • updated[].slugstringrequired
  • updated[].status"draft" | "published" | "changed"required

    changed = published, but the draft has unpublished edits.

  • updated[].titlestringrequired
  • updated[].fieldDataobjectrequired

    Draft values (what the dashboard shows).

  • updated[].publishedFieldDataobject | nullrequired

    What the Content Delivery API serves; null when never published or unpublished.

  • updated[].publishedSlugstring | nullrequired
  • updated[].publishedAtstring | nullrequired
  • updated[].sortOrderintegerrequired
  • updated[].createdAtstringrequired
  • updated[].updatedAtstringrequired
  • updated[].archivedAtstring | nullrequired

    Set 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 | nullrequired

    Set by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.

  • updated[].reviewRequestedByUserIdstring | nullrequired

    Who last requested review; kept after a rejection so items.request_review can be called again by the same person.

  • updated[].reviewNotestring | nullrequired

    Reason from the last items.reject_review call; cleared on the next request or successful publish.

  • updated[].scheduledAtstring | nullrequired

    Set 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[]required
  • failed[].indexintegerrequired
  • failed[].errorobjectrequired
  • failed[].error.codestringrequired
  • failed[].error.messagestringrequired
  • failed[].error.issuesany[]
  • failed[].error.conflictobject

    Present when code is CONFLICT: the item's current updatedAt to re-read and retry with.

  • warningstring | nullrequired

Errors

  • FORBIDDEN 403
  • COLLECTION_NOT_FOUND 404
  • ITEM_NOT_FOUND 404
  • VALIDATION 400
  • UNIQUE_CONFLICT 409
  • SLUG_TAKEN 409
  • CONFLICT 409
  • SYSTEM_COLLECTION 409

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}'
Response
{
  "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

POST/sites/{id}/collections/{key}/items/publish
betacollections:publishdefault (120/minute per token)

Publish 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 · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • keystring · pathrequired

    Collection key (slug). Get it from collections.list.

Request body

  • itemIdsstring[]required
  • scheduledAtstring

    Future ISO timestamp. When set, schedules instead of publishing immediately.

Response 200

  • itemsobject[]required
  • items[].idstringrequired
  • items[].collectionKeystringrequired
  • items[].slugstringrequired
  • items[].status"draft" | "published" | "changed"required

    changed = published, but the draft has unpublished edits.

  • items[].titlestringrequired
  • items[].fieldDataobjectrequired

    Draft values (what the dashboard shows).

  • items[].publishedFieldDataobject | nullrequired

    What the Content Delivery API serves; null when never published or unpublished.

  • items[].publishedSlugstring | nullrequired
  • items[].publishedAtstring | nullrequired
  • items[].sortOrderintegerrequired
  • items[].createdAtstringrequired
  • items[].updatedAtstringrequired
  • items[].archivedAtstring | nullrequired

    Set 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 | nullrequired

    Set by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.

  • items[].reviewRequestedByUserIdstring | nullrequired

    Who last requested review; kept after a rejection so items.request_review can be called again by the same person.

  • items[].reviewNotestring | nullrequired

    Reason from the last items.reject_review call; cleared on the next request or successful publish.

  • items[].scheduledAtstring | nullrequired

    Set 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
  • warningstring | nullrequired

    REVIEW_CONTENT_CHANGED when any item in this batch was edited after being submitted for review. Always null when scheduling (scheduledAt set).

Errors

  • FORBIDDEN 403
  • COLLECTION_NOT_FOUND 404
  • VALIDATION 400 · scheduledAt not in the future, or an item is already scheduled: items.unschedule it first to change the time
  • SYSTEM_COLLECTION 409

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"]}'
Response
{
  "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

POST/sites/{id}/collections/{key}/items/unpublish
betacollections:publishdefault (120/minute per token)

Unpublish 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 · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • keystring · pathrequired

    Collection key (slug). Get it from collections.list.

Request body

  • itemIdsstring[]required

Response 200

  • itemsobject[]required
  • items[].idstringrequired
  • items[].collectionKeystringrequired
  • items[].slugstringrequired
  • items[].status"draft" | "published" | "changed"required

    changed = published, but the draft has unpublished edits.

  • items[].titlestringrequired
  • items[].fieldDataobjectrequired

    Draft values (what the dashboard shows).

  • items[].publishedFieldDataobject | nullrequired

    What the Content Delivery API serves; null when never published or unpublished.

  • items[].publishedSlugstring | nullrequired
  • items[].publishedAtstring | nullrequired
  • items[].sortOrderintegerrequired
  • items[].createdAtstringrequired
  • items[].updatedAtstringrequired
  • items[].archivedAtstring | nullrequired

    Set 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 | nullrequired

    Set by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.

  • items[].reviewRequestedByUserIdstring | nullrequired

    Who last requested review; kept after a rejection so items.request_review can be called again by the same person.

  • items[].reviewNotestring | nullrequired

    Reason from the last items.reject_review call; cleared on the next request or successful publish.

  • items[].scheduledAtstring | nullrequired

    Set 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

  • FORBIDDEN 403
  • COLLECTION_NOT_FOUND 404
  • VALIDATION 400
  • SYSTEM_COLLECTION 409

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"]}'
Response
{
  "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

GET/sites/{id}/collections/{key}/items/trash
betacollections:viewdefault (120/minute per token)

List 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 · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • keystring · pathrequired

    Collection key (slug). Get it from collections.list.

  • limitinteger · query

    Maximum number of items to return, 1–100. Defaults to 20.

  • cursorstring · query

    Opaque cursor from the previous page's nextCursor. Omit for the first page.

Response 200

  • dataobject[]required
  • data[].idstringrequired
  • data[].collectionKeystringrequired
  • data[].slugstringrequired
  • data[].status"draft" | "published" | "changed"required

    changed = published, but the draft has unpublished edits.

  • data[].titlestringrequired
  • data[].fieldDataobjectrequired

    Draft values (what the dashboard shows).

  • data[].publishedFieldDataobject | nullrequired

    What the Content Delivery API serves; null when never published or unpublished.

  • data[].publishedSlugstring | nullrequired
  • data[].publishedAtstring | nullrequired
  • data[].sortOrderintegerrequired
  • data[].createdAtstringrequired
  • data[].updatedAtstringrequired
  • data[].archivedAtstring | nullrequired

    Set 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 | nullrequired

    Set by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.

  • data[].reviewRequestedByUserIdstring | nullrequired

    Who last requested review; kept after a rejection so items.request_review can be called again by the same person.

  • data[].reviewNotestring | nullrequired

    Reason from the last items.reject_review call; cleared on the next request or successful publish.

  • data[].scheduledAtstring | nullrequired

    Set 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.

  • hasMorebooleanrequired

    True when another page exists; pass nextCursor to fetch it.

  • nextCursorstring | nullrequired

    Cursor for the next page, or null on the last page.

Errors

  • FORBIDDEN 403
  • COLLECTION_NOT_FOUND 404
  • INVALID_CURSOR 400

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"
Response
{
  "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

GET/sites/{id}/collections/{key}/items/{itemId}
betacollections:viewdefault (120/minute per token)

Get one item by id or slug, with draft and published values. Errors: FORBIDDEN, COLLECTION_NOT_FOUND, ITEM_NOT_FOUND.

Parameters

  • idstring · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • keystring · pathrequired

    Collection key (slug). Get it from collections.list.

  • itemIdstring · pathrequired

    Item id or slug.

Response 200

  • idstringrequired
  • collectionKeystringrequired
  • slugstringrequired
  • status"draft" | "published" | "changed"required

    changed = published, but the draft has unpublished edits.

  • titlestringrequired
  • fieldDataobjectrequired

    Draft values (what the dashboard shows).

  • publishedFieldDataobject | nullrequired

    What the Content Delivery API serves; null when never published or unpublished.

  • publishedSlugstring | nullrequired
  • publishedAtstring | nullrequired
  • sortOrderintegerrequired
  • createdAtstringrequired
  • updatedAtstringrequired
  • archivedAtstring | nullrequired

    Set 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 | nullrequired

    Set by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.

  • reviewRequestedByUserIdstring | nullrequired

    Who last requested review; kept after a rejection so items.request_review can be called again by the same person.

  • reviewNotestring | nullrequired

    Reason from the last items.reject_review call; cleared on the next request or successful publish.

  • scheduledAtstring | nullrequired

    Set 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

  • FORBIDDEN 403
  • COLLECTION_NOT_FOUND 404
  • ITEM_NOT_FOUND 404

MCP tool items_get

curl -X GET "https://app.kanorio.com/api/v1/sites/{id}/collections/{key}/items/{itemId}" \
  -H "Authorization: Bearer $KANORIO_TOKEN"
Response
{
  "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

PATCH/sites/{id}/collections/{key}/items/{itemId}
betacollections:managedefault (120/minute per token)

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 · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • keystring · pathrequired

    Collection key (slug). Get it from collections.list.

  • itemIdstring · pathrequired

    Item id. Get it from items.list.

Request body

  • fieldDataobject

    Field 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.

  • slugstring
  • sortOrderinteger
  • publishboolean

    Default true: the write is published immediately. false keeps it as a draft (status draft or changed).

  • ifUnmodifiedSincestring

    ISO-8601 timestamp with timezone, e.g. 2026-10-05T12:34:56.789Z.

Response 200

  • idstringrequired
  • collectionKeystringrequired
  • slugstringrequired
  • status"draft" | "published" | "changed"required

    changed = published, but the draft has unpublished edits.

  • titlestringrequired
  • fieldDataobjectrequired

    Draft values (what the dashboard shows).

  • publishedFieldDataobject | nullrequired

    What the Content Delivery API serves; null when never published or unpublished.

  • publishedSlugstring | nullrequired
  • publishedAtstring | nullrequired
  • sortOrderintegerrequired
  • createdAtstringrequired
  • updatedAtstringrequired
  • archivedAtstring | nullrequired

    Set 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 | nullrequired

    Set by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.

  • reviewRequestedByUserIdstring | nullrequired

    Who last requested review; kept after a rejection so items.request_review can be called again by the same person.

  • reviewNotestring | nullrequired

    Reason from the last items.reject_review call; cleared on the next request or successful publish.

  • scheduledAtstring | nullrequired

    Set 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

  • FORBIDDEN 403
  • COLLECTION_NOT_FOUND 404
  • ITEM_NOT_FOUND 404
  • CONFLICT 409 · details.conflict.updatedAt: re-read and retry
  • VALIDATION 400 · details.issues: fieldId, code, message, example
  • UNIQUE_CONFLICT 409
  • SLUG_TAKEN 409
  • PLAN_ITEM_LIMIT_REACHED 403 · details.quota
  • COLLECTION_ITEM_LIMIT_REACHED 403
  • SYSTEM_COLLECTION 409 · 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}'
Response
{
  "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

DELETE/sites/{id}/collections/{key}/items/{itemId}
betacollections:managedefault (120/minute per token)

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 · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • keystring · pathrequired

    Collection key (slug). Get it from collections.list.

  • itemIdstring · pathrequired

    Item id. Get it from items.list.

  • forceboolean · query

Response 200

  • idstringrequired

Errors

  • FORBIDDEN 403
  • COLLECTION_NOT_FOUND 404
  • ITEM_NOT_FOUND 404
  • REFERENCED 409
  • SYSTEM_COLLECTION 409

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"
Response
{
  "id": "item_example01"
}

Restore an item

POST/sites/{id}/collections/{key}/items/{itemId}/restore
betacollections:managedefault (120/minute per token)

Restore 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 · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • keystring · pathrequired

    Collection key (slug). Get it from collections.list.

  • itemIdstring · pathrequired

    Item id. Get it from items.list.

Response 200

  • idstringrequired
  • collectionKeystringrequired
  • slugstringrequired
  • status"draft" | "published" | "changed"required

    changed = published, but the draft has unpublished edits.

  • titlestringrequired
  • fieldDataobjectrequired

    Draft values (what the dashboard shows).

  • publishedFieldDataobject | nullrequired

    What the Content Delivery API serves; null when never published or unpublished.

  • publishedSlugstring | nullrequired
  • publishedAtstring | nullrequired
  • sortOrderintegerrequired
  • createdAtstringrequired
  • updatedAtstringrequired
  • archivedAtstring | nullrequired

    Set 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 | nullrequired

    Set by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.

  • reviewRequestedByUserIdstring | nullrequired

    Who last requested review; kept after a rejection so items.request_review can be called again by the same person.

  • reviewNotestring | nullrequired

    Reason from the last items.reject_review call; cleared on the next request or successful publish.

  • scheduledAtstring | nullrequired

    Set 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

  • FORBIDDEN 403
  • COLLECTION_NOT_FOUND 404
  • ITEM_NOT_FOUND 404
  • NOT_ARCHIVED 422

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 '{}'
Response
{
  "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

POST/sites/{id}/collections/{key}/items/{itemId}/purge
betacollections:managedefault (120/minute per token)

Permanently 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 · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • keystring · pathrequired

    Collection key (slug). Get it from collections.list.

  • itemIdstring · pathrequired

    Item id. Get it from items.list.

Response 200

  • idstringrequired

Errors

  • FORBIDDEN 403
  • COLLECTION_NOT_FOUND 404
  • ITEM_NOT_FOUND 404
  • NOT_ARCHIVED 422

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 '{}'
Response
{
  "id": "item_example04"
}

Request review

POST/sites/{id}/collections/{key}/items/{itemId}/request-review
betacollections:managedefault (120/minute per token)

Ask 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 · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • keystring · pathrequired

    Collection key (slug). Get it from collections.list.

  • itemIdstring · pathrequired

    Item id. Get it from items.list.

Response 200

  • idstringrequired
  • collectionKeystringrequired
  • slugstringrequired
  • status"draft" | "published" | "changed"required

    changed = published, but the draft has unpublished edits.

  • titlestringrequired
  • fieldDataobjectrequired

    Draft values (what the dashboard shows).

  • publishedFieldDataobject | nullrequired

    What the Content Delivery API serves; null when never published or unpublished.

  • publishedSlugstring | nullrequired
  • publishedAtstring | nullrequired
  • sortOrderintegerrequired
  • createdAtstringrequired
  • updatedAtstringrequired
  • archivedAtstring | nullrequired

    Set 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 | nullrequired

    Set by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.

  • reviewRequestedByUserIdstring | nullrequired

    Who last requested review; kept after a rejection so items.request_review can be called again by the same person.

  • reviewNotestring | nullrequired

    Reason from the last items.reject_review call; cleared on the next request or successful publish.

  • scheduledAtstring | nullrequired

    Set 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

  • FORBIDDEN 403
  • COLLECTION_NOT_FOUND 404
  • ITEM_NOT_FOUND 404

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 '{}'
Response
{
  "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

POST/sites/{id}/collections/{key}/items/{itemId}/reject-review
betacollections:publishdefault (120/minute per token)

Send 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 · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • keystring · pathrequired

    Collection key (slug). Get it from collections.list.

  • itemIdstring · pathrequired

    Item id. Get it from items.list.

Request body

  • notestring | null

Response 200

  • idstringrequired
  • collectionKeystringrequired
  • slugstringrequired
  • status"draft" | "published" | "changed"required

    changed = published, but the draft has unpublished edits.

  • titlestringrequired
  • fieldDataobjectrequired

    Draft values (what the dashboard shows).

  • publishedFieldDataobject | nullrequired

    What the Content Delivery API serves; null when never published or unpublished.

  • publishedSlugstring | nullrequired
  • publishedAtstring | nullrequired
  • sortOrderintegerrequired
  • createdAtstringrequired
  • updatedAtstringrequired
  • archivedAtstring | nullrequired

    Set 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 | nullrequired

    Set by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.

  • reviewRequestedByUserIdstring | nullrequired

    Who last requested review; kept after a rejection so items.request_review can be called again by the same person.

  • reviewNotestring | nullrequired

    Reason from the last items.reject_review call; cleared on the next request or successful publish.

  • scheduledAtstring | nullrequired

    Set 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

  • FORBIDDEN 403
  • COLLECTION_NOT_FOUND 404
  • ITEM_NOT_FOUND 404
  • VALIDATION 400 · 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."}'
Response
{
  "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

POST/sites/{id}/collections/{key}/items/{itemId}/unschedule
betacollections:publishdefault (120/minute per token)

Cancel 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 · pathrequired

    Website id. Get it from sites.list or from sites.create.

  • keystring · pathrequired

    Collection key (slug). Get it from collections.list.

  • itemIdstring · pathrequired

    Item id. Get it from items.list.

Response 200

  • idstringrequired
  • collectionKeystringrequired
  • slugstringrequired
  • status"draft" | "published" | "changed"required

    changed = published, but the draft has unpublished edits.

  • titlestringrequired
  • fieldDataobjectrequired

    Draft values (what the dashboard shows).

  • publishedFieldDataobject | nullrequired

    What the Content Delivery API serves; null when never published or unpublished.

  • publishedSlugstring | nullrequired
  • publishedAtstring | nullrequired
  • sortOrderintegerrequired
  • createdAtstringrequired
  • updatedAtstringrequired
  • archivedAtstring | nullrequired

    Set 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 | nullrequired

    Set by items.request_review; non-null means it is waiting for someone with collections:publish. Cleared on items.publish/items.reject_review.

  • reviewRequestedByUserIdstring | nullrequired

    Who last requested review; kept after a rejection so items.request_review can be called again by the same person.

  • reviewNotestring | nullrequired

    Reason from the last items.reject_review call; cleared on the next request or successful publish.

  • scheduledAtstring | nullrequired

    Set 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

  • FORBIDDEN 403
  • COLLECTION_NOT_FOUND 404
  • ITEM_NOT_FOUND 404

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 '{}'
Response
{
  "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
}