API リファレンス
Pages
Management API: GET /sites/{id}/pages, POST /sites/{id}/pages, PUT /sites/{id}/pages/order, …
List the pages of a website (home page first), with slug, visibility, SEO fields, systemManaged, lockedCoreSectionTypes and the revision marker updatedAt. Sections are not included; use pages.get. Per-product pages are not included; product copy, SEO and publish state live on products.*. For the whole page tree in one call use sites.structure. Errors: FORBIDDEN, INVALID_CURSOR.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
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[].slugstringrequiredURL path, "/" for the home page.
data[].pathstring[]requiredPath segments (e.g. ["services", "haircut"] for "/services/haircut"; [] for "/").
data[].parentSlugstring | nullrequiredImmediate parent page slug for generic nested pages (e.g. "/services" for "/services/haircut"; null for "/", top-level pages, and system pages such as blog/shop/product/legal).
data[].isDirectorybooleanrequiredTrue when this is a hidden folder page that exists to group subpage URLs.
data[].depthintegerrequiredHierarchy depth: 0 for home page, 1 for top-level pages, up to 3.
data[].ancestorsobject[]requiredVisible ancestor pages from root to immediate parent (only generic pages participate; system pages such as blog, shop, product, and legal always return []).
data[].ancestors[].idstringrequireddata[].ancestors[].slugstringrequireddata[].ancestors[].titlestringrequireddata[].breadcrumbsobject[]requiredVisible breadcrumb trail shown on the page and in BreadcrumbList JSON-LD (up to 4 items; empty when the page has no visible ancestors or is a system page).
data[].breadcrumbs[].namestringrequireddata[].breadcrumbs[].urlstringrequireddata[].breadcrumbSource"url" | "custom"requiredWhether breadcrumbs follow the URL hierarchy ("url") or a custom breadcrumbParentSlug override ("custom").
data[].breadcrumbParentSlugstring | nullrequiredOptional parent page slug override for breadcrumbs and structured data only.
data[].titlestringrequireddata[].pageTypestringrequireddata[].isHomePagebooleanrequireddata[].isVisiblebooleanrequiredHidden pages are not published or linked from navigation.
data[].orderintegerrequireddata[].globalHeaderIdstring | nullrequireddata[].globalFooterIdstring | nullrequireddata[].updatedAtstringrequiredRevision marker. Pass it back as ifUnmodifiedSince when replacing sections.
data[].seoobjectrequireddata[].seo.seoTitlestring | nullrequireddata[].seo.seoDescriptionstring | nullrequireddata[].seo.seoKeywordsstring[] | nullrequireddata[].seo.ogTitlestring | nullrequireddata[].seo.ogDescriptionstring | nullrequireddata[].seo.ogImagestring | nullrequiredShare image display URL (changes with versions; do not store it).
data[].seo.ogImageAssetIdstring | nullrequiredassetId of the share image when it is in the media library.
data[].seo.ogImageFramingobject | nulldata[].seo.canonicalUrlstring | nullrequireddata[].seo.robotsIndexstring | nullrequireddata[].seo.robotsFollowstring | nullrequireddata[].seo.excludeFromSiteSearchbooleanrequiredWhen true, this page is excluded from visitor site search (independent of robotsIndex).
data[].systemManagedbooleanrequiredTrue when Kanorio owns this page (shop index, blog index, taxonomy templates). Those pages cannot be created or deleted.
data[].lockedCoreSectionTypesstring[]requiredSection types locked at index 0. pages.replace_sections must keep exactly one of each, with its locked source. Empty for ordinary pages.
hasMorebooleanrequiredTrue when another page exists; pass nextCursor to fetch it.
nextCursorstring | nullrequiredCursor for the next page, or null on the last page.
Errors
FORBIDDEN403INVALID_CURSOR400
MCP tool pages_list
curl -X GET "https://app.kanorio.com/api/v1/sites/{id}/pages" \
-H "Authorization: Bearer $KANORIO_TOKEN"{
"data": [
{
"id": "pg_example456",
"slug": "/",
"path": [],
"parentSlug": null,
"isDirectory": false,
"depth": 0,
"ancestors": [],
"breadcrumbs": [],
"breadcrumbSource": "url",
"breadcrumbParentSlug": null,
"title": "Home",
"pageType": "generic",
"isHomePage": true,
"isVisible": true,
"order": 0,
"globalHeaderId": "sec_header01",
"globalFooterId": "sec_footer01",
"updatedAt": "2026-10-06T08:00:00.000Z",
"seo": {
"seoTitle": "Sunny Bakery",
"seoDescription": "Artisan sourdough bakery in Taipei.",
"seoKeywords": [
"sourdough",
"artisan bakery"
],
"ogTitle": null,
"ogDescription": null,
"ogImage": null,
"ogImageAssetId": null,
"ogImageFraming": null,
"canonicalUrl": null,
"robotsIndex": null,
"robotsFollow": null,
"excludeFromSiteSearch": false
},
"systemManaged": false,
"lockedCoreSectionTypes": []
},
{
"id": "pg_example789",
"slug": "/about",
"path": [
"about"
],
"parentSlug": null,
"isDirectory": false,
"depth": 1,
"ancestors": [],
"breadcrumbs": [],
"breadcrumbSource": "url",
"breadcrumbParentSlug": null,
"title": "About Us",
"pageType": "generic",
"isHomePage": false,
"isVisible": true,
"order": 1,
"globalHeaderId": "sec_header01",
"globalFooterId": "sec_footer01",
"updatedAt": "2026-10-06T08:00:00.000Z",
"seo": {
"seoTitle": "About Us | Sunny Bakery",
"seoDescription": "Naturally leavened sourdough baked fresh every morning.",
"seoKeywords": [
"sourdough",
"artisan bakery"
],
"ogTitle": null,
"ogDescription": null,
"ogImage": null,
"ogImageAssetId": null,
"ogImageFraming": null,
"canonicalUrl": null,
"robotsIndex": null,
"robotsFollow": null,
"excludeFromSiteSearch": false
},
"systemManaged": false,
"lockedCoreSectionTypes": []
}
],
"hasMore": false,
"nextCursor": null
}Create an empty page (up to 3 levels deep). Pass parentSlug (e.g. "/services") plus the last segment in slug (e.g. "/haircut") rather than concatenating multi-segment paths yourself; if the parent page does not exist yet, a hidden folder page is created automatically. Omit slug to have one generated from the title. The home page ("/") already exists and cannot be created; link-in-bio pages have a dedicated flow. The new page uses the home page's header and footer unless you pass globalHeaderId/globalFooterId. It is not added to the navigation automatically: after creating pages, call globals.replace_header with a navItem per visible page (use a short label, not the page title). pageType cannot be a system page (shop, blog, taxonomy templates) or link-in-bio; Kanorio creates those. Passing one returns SYSTEM_PAGE_LOCKED. Fill the page afterwards with pages.replace_sections. Errors: FORBIDDEN, VALIDATION, SLUG_TAKEN, RESERVED_SLUG, RESERVED_SEGMENT, SEGMENT_TOO_LONG, DEPTH_EXCEEDED, PARENT_NOT_ALLOWED, BREADCRUMB_PARENT_INVALID, HOME_NOT_CREATABLE, LINK_IN_BIO_DEDICATED_ENTRY, SYSTEM_PAGE_LOCKED, PAGE_LIMIT_REACHED.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
Request body
titlestringrequiredPage title; also used for navigation labels.
slugstringLast URL segment starting with "/" (e.g. "/haircut" when parentSlug is "/services"), or full path (e.g. "/about"). Generated from title when omitted.
parentSlugstring | nullOptional parent page slug (e.g. "/services"). Pass parentSlug + last segment instead of concatenating "/a/b" yourself.
breadcrumbParentSlugstring | nullOptional parent page slug override for breadcrumbs and BreadcrumbList JSON-LD only (use only when the typical user trail differs from the URL path; does not change the URL).
pageType"generic" | "article" | "legal-cookie-policy" | "legal-privacy-policy" | "legal-terms-of-service" | "legal-purchase-terms" | "legal-return-policy" | "legal-disclaimer"Defaults to generic. System pages (shop, blog, taxonomy templates) and link-in-bio cannot be created here.
isVisiblebooleanDefaults to true. Hidden pages are not published.
globalHeaderIdstring | nullHeader from globalSections. Defaults to the home page's header; pass null for a page without a header.
globalFooterIdstring | nullFooter from globalSections. Defaults to the home page's footer; pass null for a page without a footer.
seoTitlestringseoDescriptionstring
Response 201
idstringrequiredslugstringrequiredURL path, "/" for the home page.
pathstring[]requiredPath segments (e.g. ["services", "haircut"] for "/services/haircut"; [] for "/").
parentSlugstring | nullrequiredImmediate parent page slug for generic nested pages (e.g. "/services" for "/services/haircut"; null for "/", top-level pages, and system pages such as blog/shop/product/legal).
isDirectorybooleanrequiredTrue when this is a hidden folder page that exists to group subpage URLs.
depthintegerrequiredHierarchy depth: 0 for home page, 1 for top-level pages, up to 3.
ancestorsobject[]requiredVisible ancestor pages from root to immediate parent (only generic pages participate; system pages such as blog, shop, product, and legal always return []).
ancestors[].idstringrequiredancestors[].slugstringrequiredancestors[].titlestringrequiredbreadcrumbsobject[]requiredVisible breadcrumb trail shown on the page and in BreadcrumbList JSON-LD (up to 4 items; empty when the page has no visible ancestors or is a system page).
breadcrumbs[].namestringrequiredbreadcrumbs[].urlstringrequiredbreadcrumbSource"url" | "custom"requiredWhether breadcrumbs follow the URL hierarchy ("url") or a custom breadcrumbParentSlug override ("custom").
breadcrumbParentSlugstring | nullrequiredOptional parent page slug override for breadcrumbs and structured data only.
titlestringrequiredpageTypestringrequiredisHomePagebooleanrequiredisVisiblebooleanrequiredHidden pages are not published or linked from navigation.
orderintegerrequiredglobalHeaderIdstring | nullrequiredglobalFooterIdstring | nullrequiredupdatedAtstringrequiredRevision marker. Pass it back as ifUnmodifiedSince when replacing sections.
seoobjectrequiredseo.seoTitlestring | nullrequiredseo.seoDescriptionstring | nullrequiredseo.seoKeywordsstring[] | nullrequiredseo.ogTitlestring | nullrequiredseo.ogDescriptionstring | nullrequiredseo.ogImagestring | nullrequiredShare image display URL (changes with versions; do not store it).
seo.ogImageAssetIdstring | nullrequiredassetId of the share image when it is in the media library.
seo.ogImageFramingobject | nullseo.ogImageFraming.focusobjectseo.ogImageFraming.screensobjectseo.ogImageFraming.fitMode"contain" | "cover"seo.ogImageFraming.padColorstringseo.canonicalUrlstring | nullrequiredseo.robotsIndexstring | nullrequiredseo.robotsFollowstring | nullrequiredseo.excludeFromSiteSearchbooleanrequiredWhen true, this page is excluded from visitor site search (independent of robotsIndex).
systemManagedbooleanrequiredTrue when Kanorio owns this page (shop index, blog index, taxonomy templates). Those pages cannot be created or deleted.
lockedCoreSectionTypesstring[]requiredSection types locked at index 0. pages.replace_sections must keep exactly one of each, with its locked source. Empty for ordinary pages.
warningsstring[]Non-fatal warnings from this write (e.g. REDIRECT_SHADOWS_PAGE when a manual redirect intercepts this URL).
Errors
FORBIDDEN403VALIDATION400SLUG_TAKEN409RESERVED_SLUG422RESERVED_SEGMENT422SEGMENT_TOO_LONG422DEPTH_EXCEEDED422PARENT_NOT_ALLOWED422BREADCRUMB_PARENT_INVALID422HOME_NOT_CREATABLE422LINK_IN_BIO_DEDICATED_ENTRY422SYSTEM_PAGE_LOCKED422PAGE_LIMIT_REACHED422
MCP tool pages_create
curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/pages" \
-H "Authorization: Bearer $KANORIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"About Us","slug":"/about","isVisible":true}'{
"id": "pg_example789",
"slug": "/about",
"path": [
"about"
],
"parentSlug": null,
"isDirectory": false,
"depth": 1,
"ancestors": [],
"breadcrumbs": [],
"breadcrumbSource": "url",
"breadcrumbParentSlug": null,
"title": "About Us",
"pageType": "generic",
"isHomePage": false,
"isVisible": true,
"order": 1,
"globalHeaderId": "sec_header01",
"globalFooterId": "sec_footer01",
"updatedAt": "2026-10-06T08:00:00.000Z",
"seo": {
"seoTitle": "About Us | Sunny Bakery",
"seoDescription": "Naturally leavened sourdough baked fresh every morning.",
"seoKeywords": [
"sourdough",
"artisan bakery"
],
"ogTitle": null,
"ogDescription": null,
"ogImage": null,
"ogImageAssetId": null,
"ogImageFraming": null,
"canonicalUrl": null,
"robotsIndex": null,
"robotsFollow": null,
"excludeFromSiteSearch": false
},
"systemManaged": false,
"lockedCoreSectionTypes": []
}Set the order of all non-home pages (the home page is always first). Order drives the page list in the console; navigation links come from the header's navItems, which you manage with globals.replace_header. pageIds must list every non-home page from pages.list exactly once; legal pages created with the site count too. Legacy per-product pages are omitted and keep their current position. Errors: FORBIDDEN, FOREIGN_PAGE (an id is not a page of this site), HOME_NOT_SORTABLE (home page included), INCOMPLETE_ORDER (some pages missing or duplicated).
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
Request body
pageIdsstring[]requiredAll non-home page ids in the desired order.
Response 200
pagesobject[]requiredpages[].idstringrequiredpages[].slugstringrequiredURL path, "/" for the home page.
pages[].pathstring[]requiredPath segments (e.g. ["services", "haircut"] for "/services/haircut"; [] for "/").
pages[].parentSlugstring | nullrequiredImmediate parent page slug for generic nested pages (e.g. "/services" for "/services/haircut"; null for "/", top-level pages, and system pages such as blog/shop/product/legal).
pages[].isDirectorybooleanrequiredTrue when this is a hidden folder page that exists to group subpage URLs.
pages[].depthintegerrequiredHierarchy depth: 0 for home page, 1 for top-level pages, up to 3.
pages[].ancestorsobject[]requiredVisible ancestor pages from root to immediate parent (only generic pages participate; system pages such as blog, shop, product, and legal always return []).
pages[].ancestors[].idstringrequiredpages[].ancestors[].slugstringrequiredpages[].ancestors[].titlestringrequiredpages[].breadcrumbsobject[]requiredVisible breadcrumb trail shown on the page and in BreadcrumbList JSON-LD (up to 4 items; empty when the page has no visible ancestors or is a system page).
pages[].breadcrumbs[].namestringrequiredpages[].breadcrumbs[].urlstringrequiredpages[].breadcrumbSource"url" | "custom"requiredWhether breadcrumbs follow the URL hierarchy ("url") or a custom breadcrumbParentSlug override ("custom").
pages[].breadcrumbParentSlugstring | nullrequiredOptional parent page slug override for breadcrumbs and structured data only.
pages[].titlestringrequiredpages[].pageTypestringrequiredpages[].isHomePagebooleanrequiredpages[].isVisiblebooleanrequiredHidden pages are not published or linked from navigation.
pages[].orderintegerrequiredpages[].globalHeaderIdstring | nullrequiredpages[].globalFooterIdstring | nullrequiredpages[].updatedAtstringrequiredRevision marker. Pass it back as ifUnmodifiedSince when replacing sections.
pages[].seoobjectrequiredpages[].seo.seoTitlestring | nullrequiredpages[].seo.seoDescriptionstring | nullrequiredpages[].seo.seoKeywordsstring[] | nullrequiredpages[].seo.ogTitlestring | nullrequiredpages[].seo.ogDescriptionstring | nullrequiredpages[].seo.ogImagestring | nullrequiredShare image display URL (changes with versions; do not store it).
pages[].seo.ogImageAssetIdstring | nullrequiredassetId of the share image when it is in the media library.
pages[].seo.ogImageFramingobject | nullpages[].seo.canonicalUrlstring | nullrequiredpages[].seo.robotsIndexstring | nullrequiredpages[].seo.robotsFollowstring | nullrequiredpages[].seo.excludeFromSiteSearchbooleanrequiredWhen true, this page is excluded from visitor site search (independent of robotsIndex).
pages[].systemManagedbooleanrequiredTrue when Kanorio owns this page (shop index, blog index, taxonomy templates). Those pages cannot be created or deleted.
pages[].lockedCoreSectionTypesstring[]requiredSection types locked at index 0. pages.replace_sections must keep exactly one of each, with its locked source. Empty for ordinary pages.
Errors
FORBIDDEN403FOREIGN_PAGE422 · an id is not a page of this siteHOME_NOT_SORTABLE422 · home page includedINCOMPLETE_ORDER400 · some pages missing or duplicated
MCP tool pages_reorder
curl -X PUT "https://app.kanorio.com/api/v1/sites/{id}/pages/order" \
-H "Authorization: Bearer $KANORIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"pageIds":["pg_example789"]}'{
"pages": [
{
"id": "pg_example456",
"slug": "/",
"path": [],
"parentSlug": null,
"isDirectory": false,
"depth": 0,
"ancestors": [],
"breadcrumbs": [],
"breadcrumbSource": "url",
"breadcrumbParentSlug": null,
"title": "Home",
"pageType": "generic",
"isHomePage": true,
"isVisible": true,
"order": 0,
"globalHeaderId": "sec_header01",
"globalFooterId": "sec_footer01",
"updatedAt": "2026-10-06T08:00:00.000Z",
"seo": {
"seoTitle": "Sunny Bakery",
"seoDescription": "Artisan sourdough bakery in Taipei.",
"seoKeywords": [
"sourdough",
"artisan bakery"
],
"ogTitle": null,
"ogDescription": null,
"ogImage": null,
"ogImageAssetId": null,
"ogImageFraming": null,
"canonicalUrl": null,
"robotsIndex": null,
"robotsFollow": null,
"excludeFromSiteSearch": false
},
"systemManaged": false,
"lockedCoreSectionTypes": []
},
{
"id": "pg_example789",
"slug": "/about",
"path": [
"about"
],
"parentSlug": null,
"isDirectory": false,
"depth": 1,
"ancestors": [],
"breadcrumbs": [],
"breadcrumbSource": "url",
"breadcrumbParentSlug": null,
"title": "About Us",
"pageType": "generic",
"isHomePage": false,
"isVisible": true,
"order": 1,
"globalHeaderId": "sec_header01",
"globalFooterId": "sec_footer01",
"updatedAt": "2026-10-06T08:00:00.000Z",
"seo": {
"seoTitle": "About Us | Sunny Bakery",
"seoDescription": "Naturally leavened sourdough baked fresh every morning.",
"seoKeywords": [
"sourdough",
"artisan bakery"
],
"ogTitle": null,
"ogDescription": null,
"ogImage": null,
"ogImageAssetId": null,
"ogImageFraming": null,
"canonicalUrl": null,
"robotsIndex": null,
"robotsFollow": null,
"excludeFromSiteSearch": false
},
"systemManaged": false,
"lockedCoreSectionTypes": []
}
]
}Get one page including its current draft sections, hierarchy metadata (path, parentSlug, isDirectory, depth, ancestors, breadcrumbs, breadcrumbSource), systemManaged, lockedCoreSectionTypes and updatedAt. Always read the page right before pages.replace_sections and pass updatedAt back as ifUnmodifiedSince. Images and files of the site's media library appear as asset:<assetId> in sections; assets holds them (with display URLs). Per-product pages return PAGE_NOT_FOUND; use products.get. On a system page, keep the locked core section at index 0 and do not change its source. Errors: FORBIDDEN, PAGE_NOT_FOUND.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
pageIdstring · pathrequiredPage id. Get it from pages.list.
Response 200
idstringrequiredslugstringrequiredURL path, "/" for the home page.
pathstring[]requiredPath segments (e.g. ["services", "haircut"] for "/services/haircut"; [] for "/").
parentSlugstring | nullrequiredImmediate parent page slug for generic nested pages (e.g. "/services" for "/services/haircut"; null for "/", top-level pages, and system pages such as blog/shop/product/legal).
isDirectorybooleanrequiredTrue when this is a hidden folder page that exists to group subpage URLs.
depthintegerrequiredHierarchy depth: 0 for home page, 1 for top-level pages, up to 3.
ancestorsobject[]requiredVisible ancestor pages from root to immediate parent (only generic pages participate; system pages such as blog, shop, product, and legal always return []).
ancestors[].idstringrequiredancestors[].slugstringrequiredancestors[].titlestringrequiredbreadcrumbsobject[]requiredVisible breadcrumb trail shown on the page and in BreadcrumbList JSON-LD (up to 4 items; empty when the page has no visible ancestors or is a system page).
breadcrumbs[].namestringrequiredbreadcrumbs[].urlstringrequiredbreadcrumbSource"url" | "custom"requiredWhether breadcrumbs follow the URL hierarchy ("url") or a custom breadcrumbParentSlug override ("custom").
breadcrumbParentSlugstring | nullrequiredOptional parent page slug override for breadcrumbs and structured data only.
titlestringrequiredpageTypestringrequiredisHomePagebooleanrequiredisVisiblebooleanrequiredHidden pages are not published or linked from navigation.
orderintegerrequiredglobalHeaderIdstring | nullrequiredglobalFooterIdstring | nullrequiredupdatedAtstringrequiredRevision marker. Pass it back as ifUnmodifiedSince when replacing sections.
seoobjectrequiredseo.seoTitlestring | nullrequiredseo.seoDescriptionstring | nullrequiredseo.seoKeywordsstring[] | nullrequiredseo.ogTitlestring | nullrequiredseo.ogDescriptionstring | nullrequiredseo.ogImagestring | nullrequiredShare image display URL (changes with versions; do not store it).
seo.ogImageAssetIdstring | nullrequiredassetId of the share image when it is in the media library.
seo.ogImageFramingobject | nullseo.ogImageFraming.focusobjectseo.ogImageFraming.screensobjectseo.ogImageFraming.fitMode"contain" | "cover"seo.ogImageFraming.padColorstringseo.canonicalUrlstring | nullrequiredseo.robotsIndexstring | nullrequiredseo.robotsFollowstring | nullrequiredseo.excludeFromSiteSearchbooleanrequiredWhen true, this page is excluded from visitor site search (independent of robotsIndex).
sectionsobject[]requiredCurrent draft sections (what the editor shows), not the published copy. Media-library files appear as asset:<assetId>.
assetsobjectrequiredThe media-library files the sections use, by assetId.
systemManagedbooleanrequiredTrue when Kanorio owns this page (shop index, blog index, taxonomy templates). Those pages cannot be created or deleted.
lockedCoreSectionTypesstring[]requiredSection types locked at index 0. pages.replace_sections must keep exactly one of each, with its locked source. Empty for ordinary pages.
Errors
FORBIDDEN403PAGE_NOT_FOUND404
MCP tool pages_get
curl -X GET "https://app.kanorio.com/api/v1/sites/{id}/pages/{pageId}" \
-H "Authorization: Bearer $KANORIO_TOKEN"{
"id": "pg_example456",
"slug": "/",
"path": [],
"parentSlug": null,
"isDirectory": false,
"depth": 0,
"ancestors": [],
"breadcrumbs": [],
"breadcrumbSource": "url",
"breadcrumbParentSlug": null,
"title": "Home",
"pageType": "generic",
"isHomePage": true,
"isVisible": true,
"order": 0,
"globalHeaderId": "sec_header01",
"globalFooterId": "sec_footer01",
"updatedAt": "2026-10-06T08:00:00.000Z",
"seo": {
"seoTitle": "Sunny Bakery",
"seoDescription": "Artisan sourdough bakery in Taipei.",
"seoKeywords": [
"sourdough",
"artisan bakery"
],
"ogTitle": null,
"ogDescription": null,
"ogImage": null,
"ogImageAssetId": null,
"ogImageFraming": null,
"canonicalUrl": null,
"robotsIndex": null,
"robotsFollow": null,
"excludeFromSiteSearch": false
},
"systemManaged": false,
"lockedCoreSectionTypes": [],
"sections": [
{
"id": "sec_hero01",
"type": "hero",
"title": "Freshly baked sourdough every morning",
"subtitle": "Natural starter, local grain. Doors open at 7 a.m.",
"image": "asset:asset_example01",
"ctaIds": [
"btn_order"
]
},
{
"id": "sec_faq01",
"type": "faq",
"title": "Frequently Asked Questions",
"items": [
{
"question": "Can I pre-order loaves?",
"answer": "Yes, place pre-orders by 5 p.m. the day before."
}
]
}
],
"assets": {
"asset_example01": {
"assetId": "asset_example01",
"kind": "image",
"visibility": "public",
"tags": [],
"processing": null,
"status": "active",
"missing": false,
"version": 1,
"url": "https://media.kanorio.com/example/sunny-bakery-hero.jpg",
"thumbnailUrl": null,
"fileName": "sunny-bakery-hero.jpg",
"mimeType": "image/jpeg",
"bytes": 482133,
"streaming": "none",
"billableBytes": 482133,
"width": 2400,
"height": 1600,
"durationSeconds": null,
"pageCount": null,
"source": "IMAGE_CONTENT",
"inUse": true,
"focus": null,
"edgeColor": null,
"altText": null,
"watermarkExempt": false,
"createdAt": "2026-10-01T02:30:00.000Z"
}
}
}Update a page's properties: title, slug, parentSlug, createRedirect, breadcrumbParentSlug, visibility, header/footer reference, SEO fields (seoTitle, seoDescription, seoKeywords, og*, canonicalUrl, robots*) and excludeFromSiteSearch. Only the fields you send change; sections are untouched (use pages.replace_sections). Nullable fields (parentSlug, breadcrumbParentSlug, globalHeaderId, globalFooterId, ogImageAssetId) can be cleared by passing null; all other fields can only be replaced, not cleared. Slug, parentSlug and visibility changes take effect on the published site immediately; renaming automatically updates descendant subpages and creates 301 redirects for previously published pages unless createRedirect is false. Errors: FORBIDDEN, PAGE_NOT_FOUND, PARENT_NOT_FOUND, PARENT_NOT_ALLOWED, DEPTH_EXCEEDED, SEGMENT_TOO_LONG, RESERVED_SLUG, RESERVED_SEGMENT, BREADCRUMB_PARENT_INVALID, REDIRECT_CONFLICT, REDIRECT_LIMIT, VALIDATION, SLUG_TAKEN, HOME_SLUG_IMMUTABLE, HOME_NOT_HIDEABLE, ASSET_NOT_FOUND, ASSET_NOT_ALLOWED.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
pageIdstring · pathrequiredPage id. Get it from pages.list.
Request body
titlestringPage title; also the default navigation label.
slugstringNew URL path (or last segment when parentSlug is provided), e.g. "/about". Renaming a page also renames all its descendant subpages and creates 301 redirects for previously published pages. The home page slug cannot change.
parentSlugstring | nullMove this page (and its subpages) under a new parent page slug (e.g. "/services"), or pass null to move it to the top level. Pass parentSlug + last segment rather than concatenating "/a/b" yourself.
createRedirectbooleanWhether to create 301 permanent redirects for previously published pages when renaming or moving (defaults to true).
breadcrumbParentSlugstring | nullOverride the parent page shown in breadcrumbs and BreadcrumbList JSON-LD (pass null to reset to URL hierarchy). Use only when the page's logical category differs from its URL; does not change the URL or create redirects. Renaming or deleting the target page updates or clears this override automatically.
isVisiblebooleanHidden pages are not published. The home page cannot be hidden.
globalHeaderIdstring | nullHeader from globalSections to show on this page; null removes it.
globalFooterIdstring | nullseoTitlestringseoDescriptionstringseoKeywordsstring[]ogTitlestringogDescriptionstringogImageAssetIdstring | nullShare image: assetId of an image in the media library (media.list, media.upload). null removes it; without a share image a title card is generated automatically.
ogImageFramingobject | nullogImageFraming.focusobjectogImageFraming.focus.xnumberrequiredogImageFraming.focus.ynumberrequiredogImageFraming.screensobjectogImageFraming.screens.desktopobjectogImageFraming.screens.tabletobjectogImageFraming.screens.mobileobjectogImageFraming.fitMode"contain" | "cover"ogImageFraming.padColorstringcanonicalUrlstringrobotsIndex"index" | "noindex"robotsFollow"follow" | "nofollow"excludeFromSiteSearchbooleanExclude this page from visitor site search (/api/v1/search and the /search page); does not affect search engine indexing (robotsIndex).
ifUnmodifiedSincestringOptional optimistic-concurrency marker: the page's updatedAt from pages.get. If the page changed since, the call fails with CONFLICT (details.conflict.updatedAt) instead of silently overwriting.
Response 200
idstringrequiredslugstringrequiredURL path, "/" for the home page.
pathstring[]requiredPath segments (e.g. ["services", "haircut"] for "/services/haircut"; [] for "/").
parentSlugstring | nullrequiredImmediate parent page slug for generic nested pages (e.g. "/services" for "/services/haircut"; null for "/", top-level pages, and system pages such as blog/shop/product/legal).
isDirectorybooleanrequiredTrue when this is a hidden folder page that exists to group subpage URLs.
depthintegerrequiredHierarchy depth: 0 for home page, 1 for top-level pages, up to 3.
ancestorsobject[]requiredVisible ancestor pages from root to immediate parent (only generic pages participate; system pages such as blog, shop, product, and legal always return []).
ancestors[].idstringrequiredancestors[].slugstringrequiredancestors[].titlestringrequiredbreadcrumbsobject[]requiredVisible breadcrumb trail shown on the page and in BreadcrumbList JSON-LD (up to 4 items; empty when the page has no visible ancestors or is a system page).
breadcrumbs[].namestringrequiredbreadcrumbs[].urlstringrequiredbreadcrumbSource"url" | "custom"requiredWhether breadcrumbs follow the URL hierarchy ("url") or a custom breadcrumbParentSlug override ("custom").
breadcrumbParentSlugstring | nullrequiredOptional parent page slug override for breadcrumbs and structured data only.
titlestringrequiredpageTypestringrequiredisHomePagebooleanrequiredisVisiblebooleanrequiredHidden pages are not published or linked from navigation.
orderintegerrequiredglobalHeaderIdstring | nullrequiredglobalFooterIdstring | nullrequiredupdatedAtstringrequiredRevision marker. Pass it back as ifUnmodifiedSince when replacing sections.
seoobjectrequiredseo.seoTitlestring | nullrequiredseo.seoDescriptionstring | nullrequiredseo.seoKeywordsstring[] | nullrequiredseo.ogTitlestring | nullrequiredseo.ogDescriptionstring | nullrequiredseo.ogImagestring | nullrequiredShare image display URL (changes with versions; do not store it).
seo.ogImageAssetIdstring | nullrequiredassetId of the share image when it is in the media library.
seo.ogImageFramingobject | nullseo.ogImageFraming.focusobjectseo.ogImageFraming.screensobjectseo.ogImageFraming.fitMode"contain" | "cover"seo.ogImageFraming.padColorstringseo.canonicalUrlstring | nullrequiredseo.robotsIndexstring | nullrequiredseo.robotsFollowstring | nullrequiredseo.excludeFromSiteSearchbooleanrequiredWhen true, this page is excluded from visitor site search (independent of robotsIndex).
systemManagedbooleanrequiredTrue when Kanorio owns this page (shop index, blog index, taxonomy templates). Those pages cannot be created or deleted.
lockedCoreSectionTypesstring[]requiredSection types locked at index 0. pages.replace_sections must keep exactly one of each, with its locked source. Empty for ordinary pages.
warningsstring[]Non-fatal warnings from this write (e.g. REDIRECT_SHADOWS_PAGE when a manual redirect intercepts this URL).
Errors
FORBIDDEN403PAGE_NOT_FOUND404PARENT_NOT_FOUND404PARENT_NOT_ALLOWED422DEPTH_EXCEEDED422SEGMENT_TOO_LONG422RESERVED_SLUG422RESERVED_SEGMENT422BREADCRUMB_PARENT_INVALID422REDIRECT_CONFLICT409REDIRECT_LIMIT403VALIDATION400SLUG_TAKEN409HOME_SLUG_IMMUTABLE422HOME_NOT_HIDEABLE422ASSET_NOT_FOUND404ASSET_NOT_ALLOWED422
MCP tool pages_update
curl -X PATCH "https://app.kanorio.com/api/v1/sites/{id}/pages/{pageId}" \
-H "Authorization: Bearer $KANORIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"seoTitle":"About Us | Sunny Bakery","seoDescription":"Naturally leavened sourdough baked fresh every morning.","ogImageAssetId":"asset_example01"}'{
"id": "pg_example789",
"slug": "/about",
"path": [
"about"
],
"parentSlug": null,
"isDirectory": false,
"depth": 1,
"ancestors": [],
"breadcrumbs": [],
"breadcrumbSource": "url",
"breadcrumbParentSlug": null,
"title": "About Us",
"pageType": "generic",
"isHomePage": false,
"isVisible": true,
"order": 1,
"globalHeaderId": "sec_header01",
"globalFooterId": "sec_footer01",
"updatedAt": "2026-10-06T08:00:00.000Z",
"seo": {
"seoTitle": "About Us | Sunny Bakery",
"seoDescription": "Naturally leavened sourdough baked fresh every morning.",
"seoKeywords": [
"sourdough",
"artisan bakery"
],
"ogTitle": null,
"ogDescription": null,
"ogImage": null,
"ogImageAssetId": null,
"ogImageFraming": null,
"canonicalUrl": null,
"robotsIndex": null,
"robotsFollow": null,
"excludeFromSiteSearch": false
},
"systemManaged": false,
"lockedCoreSectionTypes": []
}Delete a page and its draft content. The home page and system pages (shop, blog, taxonomy templates) cannot be deleted; system pages return SYSTEM_PAGE_LOCKED. When the page has subpages, you must pass mode: "subtree" (delete the page and all its subpages) or "lift-children" (move subpages up one level with 301 redirects before deleting the parent); omitting mode returns HAS_CHILDREN with details.children. Errors: FORBIDDEN, PAGE_NOT_FOUND, HOME_NOT_DELETABLE, SYSTEM_PAGE_LOCKED, HAS_CHILDREN, SLUG_TAKEN, REDIRECT_CONFLICT, REDIRECT_LIMIT.
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
pageIdstring · pathrequiredPage id. Get it from pages.list.
mode"subtree" | "lift-children" · queryRequired when deleting a parent page that has subpages: "subtree" deletes all descendants; "lift-children" moves subpages up one level first.
createRedirectboolean · queryWith mode "lift-children": whether to create 301 redirects from the old subpage URLs for previously published subpages (defaults to true). Ignored otherwise.
Response 200
idstringrequireddeletedtruerequireddeletedCountintegerliftedCountinteger
Errors
FORBIDDEN403PAGE_NOT_FOUND404HOME_NOT_DELETABLE422SYSTEM_PAGE_LOCKED422HAS_CHILDREN409SLUG_TAKEN409REDIRECT_CONFLICT409REDIRECT_LIMIT403
MCP tool pages_delete
curl -X DELETE "https://app.kanorio.com/api/v1/sites/{id}/pages/{pageId}" \
-H "Authorization: Bearer $KANORIO_TOKEN"{
"id": "pg_example789",
"deleted": true,
"deletedCount": 1
}Replace sections
/sites/{id}/pages/{pageId}/sectionsReplace the whole draft section list of a page (optimistic concurrency). Get the shapes from sections.describe; read the page with pages.get and pass its updatedAt as ifUnmodifiedSince. If someone else (another agent or a person in the editor) changed the page since, the call fails with CONFLICT and details.updatedAt holds the current revision: re-read the page, merge, retry. Changes are saved as draft only; call site.publish to go live. Reference images and files as asset:<assetId> (from media.list, media.upload, media.import_stock, media.upload_link_status); values you read with pages.get can be sent back unchanged. Text fields are normalized to the format that field supports (see sections.describe conventions.textFormat), not rejected; check `formatNotes` in the response for fields that were reformatted. On a system page the locked core section stays at index 0 with its locked source; removing it, duplicating it, or changing that source returns CORE_SECTION_VIOLATION. Errors: FORBIDDEN, PAGE_NOT_FOUND, VALIDATION (details lists the failing section index and field), CONFLICT, CORE_SECTION_VIOLATION, ASSET_NOT_FOUND (details.assetIds: not in this site's media library), ASSET_NOT_ALLOWED (product files cannot be shown on pages).
Parameters
idstring · pathrequiredWebsite id. Get it from sites.list or from sites.create.
pageIdstring · pathrequiredPage id. Get it from pages.list.
Request body
ifUnmodifiedSincestringrequiredThe page's updatedAt from pages.get/pages.list. Required: the write is rejected with CONFLICT when it no longer matches.
sectionsobject[]requiredComplete ordered list of section objects, each with `type` and a unique `id`.
Response 200
idstringrequiredsectionsobject[]requiredSections as stored after sanitization (media as asset:<assetId>).
assetsobjectrequiredThe media-library files the sections use, by assetId.
updatedAtstringrequiredNew revision marker; use it for the next replace.
formatNotesstring[]Field paths whose text was reformatted to the field's supported Markdown syntax (e.g. a heading became bold text).
Errors
FORBIDDEN403PAGE_NOT_FOUND404VALIDATION400 · details lists the failing section index and fieldCONFLICT409CORE_SECTION_VIOLATION422ASSET_NOT_FOUND404 · details.assetIds: not in this site's media libraryASSET_NOT_ALLOWED422 · product files cannot be shown on pages
MCP tool pages_replace_sections
curl -X PUT "https://app.kanorio.com/api/v1/sites/{id}/pages/{pageId}/sections" \
-H "Authorization: Bearer $KANORIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"ifUnmodifiedSince":"2026-10-06T08:00:00.000Z","sections":[{"id":"sec_hero01","type":"hero","title":"Freshly baked sourdough every morning","subtitle":"Natural starter, local grain. Doors open at 7 a.m.","image":"asset:asset_example01","ctaIds":["btn_order"]},{"id":"sec_faq01","type":"faq","title":"Frequently Asked Questions","items":[{"question":"Can I pre-order loaves?","answer":"Yes, place pre-orders by 5 p.m. the day before."}]}]}'{
"id": "pg_example456",
"sections": [
{
"id": "sec_hero01",
"type": "hero",
"title": "Freshly baked sourdough every morning",
"subtitle": "Natural starter, local grain. Doors open at 7 a.m.",
"image": "asset:asset_example01",
"ctaIds": [
"btn_order"
]
},
{
"id": "sec_faq01",
"type": "faq",
"title": "Frequently Asked Questions",
"items": [
{
"question": "Can I pre-order loaves?",
"answer": "Yes, place pre-orders by 5 p.m. the day before."
}
]
}
],
"assets": {
"asset_example01": {
"assetId": "asset_example01",
"kind": "image",
"visibility": "public",
"tags": [],
"processing": null,
"status": "active",
"missing": false,
"version": 1,
"url": "https://media.kanorio.com/example/sunny-bakery-hero.jpg",
"thumbnailUrl": null,
"fileName": "sunny-bakery-hero.jpg",
"mimeType": "image/jpeg",
"bytes": 482133,
"streaming": "none",
"billableBytes": 482133,
"width": 2400,
"height": 1600,
"durationSeconds": null,
"pageCount": null,
"source": "IMAGE_CONTENT",
"inUse": true,
"focus": null,
"edgeColor": null,
"altText": null,
"watermarkExempt": false,
"createdAt": "2026-10-01T02:30:00.000Z"
}
},
"updatedAt": "2026-10-06T08:01:30.000Z"
}