Kanorio

API リファレンス

Site

Management API: GET /sites/{id}/search, GET /sites/{id}/settings, PATCH /sites/{id}/settings, …

このページは英語のみです。API リファレンス、Webhook イベント、変更履歴は、コード内のフィールド名やエラーコードと揃えるため英語で提供しています。
Base URL https://app.kanorio.com/api/v1ErrorsPagination

Get settings

GET/sites/{id}/settings
betaconsole:viewdefault (120/minute per token)

Read the website's brand identity (brand colors, fonts, corner radius, color scheme), hosted layout design (density, text sizes), content language and website currency. Errors: FORBIDDEN (also when the website does not exist).

Parameters

  • idstring · pathrequired

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

Response 200

  • brandobjectrequired

    Brand identity (takes effect immediately on the live site, checkout, sign-in, customer account, emails, certificates and the Delivery API): displayName, logo?, brandColor { light, dark } (hex), brandForeground? { light?, dark? }, typography { bodyEnFontId, bodyZhHantFontId, bodyZhHansFontId, bodyJaFontId, bodyKoFontId }, cornerRadius (sharp|normal|soft), colorScheme (system|light|dark).

  • themeobjectrequired

    Layout design of the hosted site (draft until site.publish): sectionDensity (standard|compact), textSizeSettings?. Brand fields (brandColor, brandForeground, typography, cornerRadius, colorScheme) are not part of theme; read and write them in brand.

  • localestringrequired

    Content language (BCP 47).

  • currencystringrequired

    Website currency (ISO 4217, read-only here): product prices, checkout and every amount on the site use it. The owner changes it in website settings.

Errors

  • FORBIDDEN 403 · also when the website does not exist

MCP tool site_get_settings

curl -X GET "https://app.kanorio.com/api/v1/sites/{id}/settings" \
  -H "Authorization: Bearer $KANORIO_TOKEN"
Response
{
  "brand": {
    "displayName": "Sunny Bakery",
    "brandColor": {
      "light": "#D9822B",
      "dark": "#F0A55A"
    },
    "typography": {
      "bodyEnFontId": "ubuntu",
      "bodyZhHantFontId": "noto-sans-tc",
      "bodyZhHansFontId": "noto-sans-sc",
      "bodyJaFontId": "noto-sans-jp",
      "bodyKoFontId": "noto-sans-kr"
    },
    "cornerRadius": "soft",
    "colorScheme": "system"
  },
  "theme": {
    "sectionDensity": "standard"
  },
  "locale": "zh-Hant",
  "currency": "TWD"
}

Update settings

PATCH/sites/{id}/settings
betasite:manage_settingsdefault (120/minute per token)

Update the website's brand identity, hosted layout design and basic settings; only the fields you send change. brand (takes effect immediately everywhere the brand appears: site, checkout, sign-in, customer account, emails, certificates, Delivery API): brandColor { light, dark } hex colors for buttons, links and accents; brandForeground overrides the text color on brand-colored surfaces (null resets to automatic contrast); typography picks body font ids per script (bodyEnFontId, bodyZhHantFontId, bodyZhHansFontId, bodyJaFontId, bodyKoFontId); cornerRadius: sharp | normal | soft; colorScheme: system follows the visitor's device, light or dark fixes the site, checkout, sign-in and customer account to one mode. Logo and display name are managed in the website's brand settings page, not here. Layout (hosted site only, draft until site.publish): sectionDensity: standard | compact; textSizeSettings. locale changes the content language (fonts, HTML lang, legal pages). The website currency can't be changed here: it re-labels every price and is limited by the connected payment providers, so the owner changes it in website settings. Set brand before filling pages so the colors apply everywhere. Errors: FORBIDDEN (also when the website does not exist), VALIDATION (details lists the failing field), WRITE_FROZEN.

Parameters

  • idstring · pathrequired

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

Request body

  • settingsobjectrequired

    Fields to change; omitted fields keep their current value.

  • settings.sectionDensity"standard" | "compact"
  • settings.textSizeSettingsobject | null
  • settings.textSizeSettings.h1integer
  • settings.textSizeSettings.h2integer
  • settings.textSizeSettings.h3integer
  • settings.textSizeSettings.bodyinteger
  • settings.locale"ar" | "bn" | "bg" | "my" | "zh-CN" | "zh-HK" | "zh-Hant" | "cs" | "da" | "nl-BE" | "nl-NL" | "en-AU" | "en-CA" | "en-GB" | "en-US" | "tl" | "fi" | "fr-CA" | "fr-FR" | "de" | "el" | "gu" | "he" | "hi" | "hu" | "id" | "it" | "ja" | "kn" | "km" | "ko" | "lo" | "ms" | "ml" | "mr" | "ne" | "nb" | "nn" | "fa" | "pl" | "pt-BR" | "pt-PT" | "pa" | "ro" | "ru" | "si" | "es-419" | "es-ES" | "sw" | "sv" | "ta" | "te" | "th" | "tr" | "uk" | "ur" | "vi"
  • settings.brandobject
  • settings.brand.brandColorobject
  • settings.brand.brandForegroundobject | null
  • settings.brand.typographyobject
  • settings.brand.cornerRadius"sharp" | "normal" | "soft"
  • settings.brand.colorScheme"system" | "light" | "dark"

Response 200

  • brandobjectrequired

    Brand identity (takes effect immediately on the live site, checkout, sign-in, customer account, emails, certificates and the Delivery API): displayName, logo?, brandColor { light, dark } (hex), brandForeground? { light?, dark? }, typography { bodyEnFontId, bodyZhHantFontId, bodyZhHansFontId, bodyJaFontId, bodyKoFontId }, cornerRadius (sharp|normal|soft), colorScheme (system|light|dark).

  • themeobjectrequired

    Layout design of the hosted site (draft until site.publish): sectionDensity (standard|compact), textSizeSettings?. Brand fields (brandColor, brandForeground, typography, cornerRadius, colorScheme) are not part of theme; read and write them in brand.

  • localestringrequired

    Content language (BCP 47).

  • currencystringrequired

    Website currency (ISO 4217, read-only here): product prices, checkout and every amount on the site use it. The owner changes it in website settings.

Errors

  • FORBIDDEN 403 · also when the website does not exist
  • VALIDATION 400 · details lists the failing field
  • WRITE_FROZEN 503

MCP tool site_update_settings

curl -X PATCH "https://app.kanorio.com/api/v1/sites/{id}/settings" \
  -H "Authorization: Bearer $KANORIO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"settings":{"brand":{"brandColor":{"light":"#D9822B","dark":"#F0A55A"},"cornerRadius":"soft"}}}'
Response
{
  "brand": {
    "displayName": "Sunny Bakery",
    "brandColor": {
      "light": "#D9822B",
      "dark": "#F0A55A"
    },
    "typography": {
      "bodyEnFontId": "ubuntu",
      "bodyZhHantFontId": "noto-sans-tc",
      "bodyZhHansFontId": "noto-sans-sc",
      "bodyJaFontId": "noto-sans-jp",
      "bodyKoFontId": "noto-sans-kr"
    },
    "cornerRadius": "soft",
    "colorScheme": "system"
  },
  "theme": {
    "sectionDensity": "standard"
  },
  "locale": "zh-Hant",
  "currency": "TWD"
}

Publish a site

POST/sites/{id}/publish
betasite:publishpublish (30/hour per token)

Publish the current draft (all visible pages) so it is live. On first publish you must choose a subdomain (lowercase letters, digits, hyphens; it becomes https://<subdomain>.kanorio.com). Afterwards omit subdomain to keep the current one. Do not use this to change custom domains; use domains.bind. Publishing is rate-limited per token (30/hour). Errors: FORBIDDEN, SUBDOMAIN_MISSING (first publish without subdomain), SUBDOMAIN_TAKEN, RESERVED_SUBDOMAIN, INVALID_SUBDOMAIN, SUBDOMAIN_CHANGE_FORBIDDEN, PLAN_CANNOT_PUBLISH, CONTENT_VALIDATION_FAILED (details.issues lists pages/fields to fix), MODERATION_LOCKED, EMPTY_CONTENT, HOSTNAME_CONFLICT.

Parameters

  • idstring · pathrequired

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

Request body

  • subdomainstring

    Required on first publish. Defaults to the site's current subdomain, else its suggestedSubdomain.

Response 200

  • publishedAtstringrequired
  • publicUrlstringrequired

    Live URL on kanorio.com.

  • subdomainstringrequired
  • customDomainStatus"ACTIVE" | "PENDING" | nullrequired
  • expectedVersionstring | nullrequired

    Opaque content version; the edge may take up to ~30s to serve it.

  • warningobject | nullrequired

    Set when publishing succeeded but Cloudflare sync reported a delay; nothing to retry.

  • warning.codestringrequired

    CONNECTION, DNS_DELAY, SYNC_DELAY, GENERIC_DELAY or GENERIC_SYNC.

  • warning.messagesstring[]required

Errors

  • FORBIDDEN 403
  • SUBDOMAIN_MISSING 422 · first publish without subdomain
  • SUBDOMAIN_TAKEN 409
  • RESERVED_SUBDOMAIN 422
  • INVALID_SUBDOMAIN 400
  • SUBDOMAIN_CHANGE_FORBIDDEN 403
  • PLAN_CANNOT_PUBLISH 403
  • CONTENT_VALIDATION_FAILED 422 · details.issues lists pages/fields to fix
  • MODERATION_LOCKED 403
  • EMPTY_CONTENT 422
  • HOSTNAME_CONFLICT 409

MCP tool site_publish

curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/publish" \
  -H "Authorization: Bearer $KANORIO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"subdomain":"sunny-bakery"}'
Response
{
  "publishedAt": "2026-10-06T08:00:00.000Z",
  "publicUrl": "https://sunny-bakery.kanorio.com",
  "subdomain": "sunny-bakery",
  "customDomainStatus": "ACTIVE",
  "expectedVersion": "v_example01",
  "warning": null
}

Unpublish a site

POST/sites/{id}/unpublish
betasite:lifecyclepublish (30/hour per token)

Take the website offline (content and settings are kept; publish again to restore). Only the website owner may do this. Errors: FORBIDDEN (also when the website does not exist), OWNER_REQUIRED, WEBSITE_NOT_FOUND.

Parameters

  • idstring · pathrequired

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

Response 200

  • unpublishedtruerequired

Errors

  • FORBIDDEN 403 · also when the website does not exist
  • OWNER_REQUIRED 403
  • WEBSITE_NOT_FOUND 404

MCP tool site_unpublish

curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/unpublish" \
  -H "Authorization: Bearer $KANORIO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
Response
{
  "unpublished": true
}

Get allowed origins

GET/sites/{id}/allowed-origins
betacollections:viewdefault (120/minute per token)

List the origins allowed to call the Content Delivery API cross-origin (CORS allowlist). Same-origin and localhost need no entry. Errors: FORBIDDEN.

Parameters

  • idstring · pathrequired

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

Response 200

  • originsstring[]required

Errors

  • FORBIDDEN 403

MCP tool site_get_allowed_origins

curl -X GET "https://app.kanorio.com/api/v1/sites/{id}/allowed-origins" \
  -H "Authorization: Bearer $KANORIO_TOKEN"
Response
{
  "origins": [
    "https://app.example.com"
  ]
}

Update allowed origins

PUT/sites/{id}/allowed-origins
betadeveloper:managedefault (120/minute per token)

Replace the CORS allowlist for the Content Delivery API (up to 20 https origins such as https://app.example.com; no paths or wildcards). Errors: FORBIDDEN, VALIDATION (details.issues).

Parameters

  • idstring · pathrequired

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

Request body

  • originsstring[]required

Response 200

  • originsstring[]required

Errors

  • FORBIDDEN 403
  • VALIDATION 400 · details.issues

MCP tool site_update_allowed_origins

curl -X PUT "https://app.kanorio.com/api/v1/sites/{id}/allowed-origins" \
  -H "Authorization: Bearer $KANORIO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"origins":["https://app.example.com","https://preview.example.com"]}'
Response
{
  "origins": [
    "https://app.example.com",
    "https://preview.example.com"
  ]
}

Update developer settings

PATCH/sites/{id}/developer-settings
betadeveloper:managedefault (120/minute per token)

Update frontend mode and headless developer settings for the website: set frontendMode (HOSTED or HEADLESS; HEADLESS enables the Content Delivery API and blog publishing without publishing the hosted template site and switches the backoffice to the backend-only view) and/or set the external storefront URL (so visitor traffic on the hosted site 302-redirects to your external frontend while /api/v1/*, /checkout and /account stay active). Pass null to externalStorefrontUrl to clear it. Returns the site's permanent systemHost (s-xxx.kanorio.com). Setting or changing externalStorefrontUrl also prepares the IndexNow key (served by the SDK edge middleware or seoRewrites at /<key>.txt), re-aligns the Search Console property when Search Console is connected (see seo.search_console.status), and restarts the post-launch SEO reminders from that moment. Pass externalListings (HEADLESS only; replaces the whole set) to declare which listing pages your frontend implements: blogIndex, blogCategory, blogTag, blogAuthor, shopIndex, productCategory. Undeclared listings are left out of sitemap.xml, IndexNow and llms.txt so crawlers are never sent to pages your frontend does not serve; none are declared by default, and switching back to HOSTED clears them. Setting frontendMode to HEADLESS (or sending externalStorefrontUrl, which implies HEADLESS) is rejected with HEADLESS_ACCESS_REQUIRED until this website's headless access is approved in the dashboard. Switching back to HOSTED, and updating the external URL while already HEADLESS, does not require approval. Errors: FORBIDDEN, VALIDATION (details.issues), HEADLESS_ACCESS_REQUIRED.

Parameters

  • idstring · pathrequired

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

Request body

  • frontendMode"HOSTED" | "HEADLESS"

    Frontend mode: HOSTED (Kanorio-hosted pages) or HEADLESS (custom frontend; service availability is always on).

  • externalStorefrontUrlstring | null
  • externalListings"blogIndex" | "blogCategory" | "blogTag" | "blogAuthor" | "shopIndex" | "productCategory"[]

    Listing pages your external frontend implements (replaces the whole set; pass [] to declare none). HEADLESS only.

Response 200

  • systemHandlestringrequired

    Permanent system handle (s-<base32>) assigned to the website.

  • systemHoststringrequired

    System hostname (s-<base32>.kanorio.com) that always serves the Content Delivery API, /checkout and /account.

  • frontendMode"HOSTED" | "HEADLESS"required

    Frontend mode of the website: HOSTED (Kanorio renders pages) or HEADLESS (custom frontend; backoffice hides hosted-only surfaces and service endpoints are always active).

  • externalStorefrontUrlstring | nullrequired

    External frontend origin (e.g. https://www.example.com). When set, hosted pages 302-redirect there while /api/v1/*, /checkout and /account stay served.

  • externalListings"blogIndex" | "blogCategory" | "blogTag" | "blogAuthor" | "shopIndex" | "productCategory"[]required

    Kanorio-managed listing pages your external frontend implements (at the paths from the site's permalink settings). Only declared listings appear in sitemap.xml, IndexNow notifications and llms.txt; individual posts and products are always included. Only applies when frontendMode is HEADLESS.

  • allowedOriginsstring[]required

Errors

  • FORBIDDEN 403
  • VALIDATION 400 · details.issues
  • HEADLESS_ACCESS_REQUIRED 403

MCP tool site_update_developer_settings

curl -X PATCH "https://app.kanorio.com/api/v1/sites/{id}/developer-settings" \
  -H "Authorization: Bearer $KANORIO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"frontendMode":"HEADLESS","externalStorefrontUrl":"https://www.sunnybakery.example","externalListings":["blogIndex","blogCategory"]}'
Response
{
  "systemHandle": "s-k4m9x2p7q8w3",
  "systemHost": "s-k4m9x2p7q8w3.kanorio.com",
  "frontendMode": "HEADLESS",
  "externalStorefrontUrl": "https://www.sunnybakery.example",
  "externalListings": [
    "blogIndex",
    "blogCategory"
  ],
  "allowedOrigins": [
    "https://www.sunnybakery.example"
  ]
}

Update brand profile

PATCH/sites/{id}/brand-profile
Deprecated, sunset 2027-04-26site:manage_settingsdefault (120/minute per token)

Use site.report_brand_memory_issue instead.

[Deprecated, removed after 2027-04-26; use site.report_brand_memory_issue instead. Direct edits overwrite brand memory. Report what is wrong and Kanorio rewrites it from the site.] Deprecated. Use site.report_brand_memory_issue. Store a declared brand profile (positioning, targetAudience, toneAndStyle, keyOfferings, valueProposition). Declared fields only fill gaps the model left empty; they no longer overwrite generated brand memory. Errors: FORBIDDEN, VALIDATION.

Parameters

  • idstring · pathrequired

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

Request body

  • positioningstring

    Brand positioning and differentiator.

  • targetAudiencestring

    Primary target audience and use case.

  • toneAndStylestring

    Voice, tone, and writing style.

  • keyOfferingsstring[]

    Up to 8 core products, services, or content topics.

  • valuePropositionstring

    One-sentence value proposition.

Response 200

  • positioningstring
  • targetAudiencestring
  • toneAndStylestring
  • keyOfferingsstring[]
  • valuePropositionstring
  • updatedAtstringrequired

Errors

  • FORBIDDEN 403
  • VALIDATION 400

MCP tool site_update_brand_profile

curl -X PATCH "https://app.kanorio.com/api/v1/sites/{id}/brand-profile" \
  -H "Authorization: Bearer $KANORIO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"positioning":"Artisanal sourdough bakery using local heritage grains","targetAudience":"Neighborhood families and specialty coffee lovers","toneAndStyle":"Warm, craft-focused, concise","keyOfferings":["Country sourdough loaves","Seasonal fruit danishes","Weekend baking workshops"]}'
Response
{
  "positioning": "Artisanal sourdough bakery using local heritage grains",
  "targetAudience": "Neighborhood families and specialty coffee lovers",
  "toneAndStyle": "Warm, craft-focused, concise",
  "keyOfferings": [
    "Country sourdough loaves",
    "Seasonal fruit danishes",
    "Weekend baking workshops"
  ],
  "updatedAt": "2026-10-06T08:00:00.000Z"
}

Report brand memory issue

POST/sites/{id}/brand-memory/feedback
betasite:manage_settingsdefault (120/minute per token)

Tell Kanorio that one part of the brand memory is wrong. The note is stored as data, not pasted into the memory. Kanorio rewrites that part from the website. field is one of positioning, targetAudience, toneAndStyle, keyOfferings, valueProposition. Errors: FORBIDDEN, VALIDATION.

Parameters

  • idstring · pathrequired

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

Request body

  • field"positioning" | "targetAudience" | "toneAndStyle" | "keyOfferings" | "valueProposition"required
  • notestringrequired

    What is inaccurate. Not executed as an instruction.

Response 201

  • fieldstringrequired
  • appliedbooleanrequired

    True when the memory was rewritten immediately.

  • createdAtstringrequired

Errors

  • FORBIDDEN 403
  • VALIDATION 400

MCP tool site_report_brand_memory_issue

curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/brand-memory/feedback" \
  -H "Authorization: Bearer $KANORIO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"field":"keyOfferings","note":"We do not run workshops. The main product is country sourdough loaves."}'
Response
{
  "field": "keyOfferings",
  "applied": true,
  "createdAt": "2026-10-06T08:00:00.000Z"
}

Create preview token

POST/sites/{id}/preview-tokens
betadeveloper:managepublish (30/hour per token)

Mint a read-only headless preview token (knr_pv_…) for reading unpublished drafts via the Content Delivery API (send X-Kanorio-Preview: knr_pv_… or Authorization: Bearer knr_pv_… with ?preview=1). Unlike a PAT, a preview token can only read drafts of this website and expires automatically. Errors: FORBIDDEN, VALIDATION.

Parameters

  • idstring · pathrequired

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

Request body

  • labelstring | null

    Optional label (e.g. 'Next.js Draft Mode').

  • ttlSecondsinteger

    Token lifetime in seconds (60 to 2592000 = 30 days; default 604800 = 7 days).

Response 200

  • idstringrequired
  • tokenstringrequired

    Read-only preview token (knr_pv_…). Shown only once.

  • labelstring | nullrequired
  • createdAtstringrequired
  • expiresAtstringrequired

Errors

  • FORBIDDEN 403
  • VALIDATION 400

MCP tool site_create_preview_token

curl -X POST "https://app.kanorio.com/api/v1/sites/{id}/preview-tokens" \
  -H "Authorization: Bearer $KANORIO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"label":"Next.js Draft Mode","ttlSeconds":604800}'
Response
{
  "id": "pv_01j8x9k2",
  "token": "knr_pv_cm9example0001website.1761652800.pv_01j8x9k2.sig_example",
  "label": "Next.js Draft Mode",
  "createdAt": "2026-10-06T08:00:00.000Z",
  "expiresAt": "2026-10-06T08:00:00.000Z"
}

Check external frontend

GET/sites/{id}/external-frontend/check
betaconsole:viewdefault (120/minute per token)

Run the External Frontend Doctor against the website's externalStorefrontUrl: probes /sitemap.xml, /robots.txt (including AI crawler rules), /llms.txt, /feed.xml, Schema.org JSON-LD @graph, published page content sync, 24h pageview reporting, and active webhook revalidation endpoints. Pass switching: true to also evaluate pre-/post-switch cutover checks (hosted 302 redirect, /api/v1/redirects rules, Search Console property alignment, Customer API CORS allowlist, and payment return URLs). Call this after deploying or updating an external Next.js / Astro frontend to verify that every integration is green. Errors: FORBIDDEN.

Parameters

  • idstring · pathrequired

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

  • switchingboolean · queryrequired

    When true, include switching cutover checks (hosted 302 redirect, redirects, GSC, customer auth CORS, payment return URLs).

Response 200

  • externalStorefrontUrlstring | nullrequired
  • overallStatus"pass" | "warn" | "fail" | "not_configured"required
  • checkedAtstringrequired
  • checksobject[]required
  • checks[].id"derivatives" | "jsonld" | "content" | "analytics" | "revalidate" | "indexnow" | "i18n_pages" | "i18n_alternates" | "i18n_files"required

    i18n_* checks appear only on multilingual sites: secondary-locale pages under their URL prefix, hreflang alternates, and per-locale llms.txt.

  • checks[].titlestringrequired
  • checks[].status"pass" | "warn" | "fail"required
  • checks[].summarystringrequired
  • checks[].remediationstringrequired
  • checks[].detailsobject
  • switchingChecksobject[]
  • switchingChecks[].id"hosted_redirect" | "redirects" | "gsc" | "customer_auth" | "payment_return"required
  • switchingChecks[].titlestringrequired
  • switchingChecks[].status"pass" | "warn" | "fail"required
  • switchingChecks[].summarystringrequired
  • switchingChecks[].remediationstringrequired
  • switchingChecks[].detailsobject

Errors

  • FORBIDDEN 403

MCP tool site_check_external_frontend

curl -X GET "https://app.kanorio.com/api/v1/sites/{id}/external-frontend/check" \
  -H "Authorization: Bearer $KANORIO_TOKEN"
Response
{
  "externalStorefrontUrl": "https://www.sunnybakery.example",
  "overallStatus": "pass",
  "checkedAt": "2026-10-06T08:00:00.000Z",
  "checks": [
    {
      "id": "derivatives",
      "title": "SEO & AEO derivative files (sitemap, robots, llms, feed)",
      "status": "pass",
      "summary": "sitemap.xml, robots.txt, llms.txt and feed.xml are live and signed by Kanorio.",
      "remediation": "Add seoRewrites({ siteUrl, framework: \"next\" | \"astro\" }) from @kanorio/sdk."
    },
    {
      "id": "jsonld",
      "title": "Schema.org JSON-LD structured data",
      "status": "pass",
      "summary": "JSON-LD @graph matched on all 3 sampled page(s).",
      "remediation": "Fetch GET /api/v1/seo/jsonld?path=... and render it inside <script type=\"application/ld+json\">."
    },
    {
      "id": "content",
      "title": "Published page content sync",
      "status": "pass",
      "summary": "All 3 sampled page(s) match published titles and content.",
      "remediation": "Ensure your frontend reads GET /api/v1/pages/:slug."
    },
    {
      "id": "analytics",
      "title": "Visitor pageview reporting (last 24h)",
      "status": "pass",
      "summary": "Received 42 pageview(s) from the external storefront in the last 24 hours.",
      "remediation": "Mount <KanorioAnalytics /> from @kanorio/elements."
    },
    {
      "id": "revalidate",
      "title": "On-demand ISR cache revalidation webhook",
      "status": "pass",
      "summary": "1 active webhook endpoint(s) subscribed for cache invalidation.",
      "remediation": "Register a webhook endpoint in Settings → Webhooks."
    },
    {
      "id": "indexnow",
      "title": "IndexNow key verification file (/<key>.txt)",
      "status": "pass",
      "summary": "The IndexNow key file is reachable and matches, so search engines can verify new or updated content.",
      "remediation": "Add createKanorioMiddleware({ siteUrl }) from @kanorio/sdk/edge."
    }
  ]
}

Site activity

GET/sites/{id}/activity
betaconsole:viewdefault (120/minute per token)

List recent tenant operational audit log activity on the website (dashboard actions, Management API/MCP writes, page edits, publishes, product updates, domain bindings, and site automations; platform database migrations and initial template seeding are not logged here). Filter by tokenId to inspect what a specific API token or authorized app changed. Newest first. Errors: FORBIDDEN, INVALID_CURSOR.

Parameters

  • idstring · pathrequired

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

  • tokenIdstring · query

    Only return actions performed by this API token id.

  • 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

    Audit log entry id.

  • data[].actionstringrequired

    Audit action identifier (e.g. page.sections_replace, website.publish).

  • data[].resourceTypestringrequired

    Affected resource type.

  • data[].resourceIdstring | nullrequired

    Affected resource id.

  • data[].actorTokenIdstring | nullrequired

    API token id when performed via MCP or REST API; null for dashboard actions.

  • data[].summaryobject | nullrequired

    Structured non-PII action metadata.

  • data[].createdAtstringrequired

    ISO timestamp.

  • 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
  • INVALID_CURSOR 400

MCP tool site_activity

curl -X GET "https://app.kanorio.com/api/v1/sites/{id}/activity?limit=20" \
  -H "Authorization: Bearer $KANORIO_TOKEN"
Response
{
  "data": [
    {
      "id": "aud_example01",
      "action": "page.sections_replace",
      "resourceType": "page",
      "resourceId": "pg_example456",
      "actorTokenId": "tok_example01",
      "summary": {
        "channel": "mcp"
      },
      "createdAt": "2026-10-06T08:00:00.000Z"
    }
  ],
  "hasMore": false,
  "nextCursor": null
}