Content Delivery API Reference
BetaAnonymous, edge-cached read and form-submission API served directly from each Kanorio site (https://{site}/api/v1, including permanent system hosts https://s-xxx.kanorio.com/api/v1). Generated directly from packages/shared/openapi/delivery.json.
Before you start
- No API key is required for published content. Browser fetch is supported via CORS allowed origins (max 20 https origins; localhost and 127.0.0.1 are always allowed).
- Every response carries weak ETag, X-Kanorio-Cache-Tags, X-Request-Id, and X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset headers. Unknown query parameters are stripped before cache-key normalization (max 40 query parameters, each value <= 512 chars).
- Rate limits apply only on cache misses: 20 req/s per site (burst 100) and 10 req/s per IP (burst 30); draft preview: 2 req/s per IP (burst 20); Customer Bearer (knr_cat_) gated reads: 5 req/s (burst 30). Edge cache hits are unlimited.
- To read unpublished drafts on your server, send X-Kanorio-Preview: knr_pv_<token> (or ?preview=1 with a server-held PAT) or mount @kanorio/sdk/preview (createPreviewRouteHandler).
- Collections items and pages return a top-level assets map with CDN URL (replace trailing /public with /w=400|800|1200|1600,fit=scale-down,q=85), width, height, ALT, and 16px WebP LQIP placeholder (trashed, missing, or private-bucket assets are automatically filtered out).
- Guardrails: max 100 collections/site, 50 fields and 20,000 items/collection, 256 KB fieldData/item, 2 MB response payload, limit <= 100, <= 10 filter conditions, <= 3 sort fields, <= 100 values in in/nin, max 1 match filter (<= 8 words), relative dates now[+-]N<s|m|h|d|w|M|y>, and total=false to skip COUNT(*).
Endpoint descriptions match what AI assistants read.
Site Meta, Search & OpenAPI
/openapi.jsondelivery_openapi
BetaRead-onlyOpenAPI 3.1 specification for this site's Content Delivery API
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
curl -X GET "https://{site}/api/v1/openapi.json"/sitedelivery_site
BetaRead-onlyPublic site meta
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
curl -X GET "https://{site}/api/v1/site"/searchdelivery_search
BetaRead-onlySite search
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
Query parameters
qstringRequiredkindstringlimitinteger
curl -X GET "https://{site}/api/v1/search"Header & Footer Globals
/globals/headers/{key}delivery_globals_header_get
BetaRead-onlyGlobal header navigation by key ('primary' or secondary header key) with siteSettings and assets
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
Path parameters
keystringRequired
Query parameters
localestring
curl -X GET "https://{site}/api/v1/globals/headers/{key}"Pages & Redirects
/redirectsdelivery_redirects
BetaRead-onlyEnabled redirect rules (owner-defined and system 301s from page renames) for the external front end to apply
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
curl -X GET "https://{site}/api/v1/redirects"/pagesdelivery_pages_list
BetaRead-onlyPublished pages and hierarchy tree (paths, parentSlug, breadcrumbs, SEO)
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
Query parameters
localestring
curl -X GET "https://{site}/api/v1/pages"/pages/{slug}delivery_page_get
BetaRead-onlyOne published page by slug (supports 2-level path and 'home' alias) with sections and assets map
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
Path parameters
slugstringRequired
Query parameters
localestring
curl -X GET "https://{site}/api/v1/pages/{slug}"/seo/llms.txtdelivery_seo_llms_txt
BetaRead-onlyAI / LLM site index (llms.txt) using externalStorefrontUrl as the base URL
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
curl -X GET "https://{site}/api/v1/seo/llms.txt"/seo/llms-full.txtdelivery_seo_llms_full_txt
BetaRead-onlyFull site Markdown content (llms-full.txt) using externalStorefrontUrl as the base URL
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
curl -X GET "https://{site}/api/v1/seo/llms-full.txt"/seo/sitemap.xmldelivery_seo_sitemap_xml
BetaRead-onlyXML sitemap using externalStorefrontUrl as the base URL
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
curl -X GET "https://{site}/api/v1/seo/sitemap.xml"/seo/robots.txtdelivery_seo_robots_txt
BetaRead-onlyrobots.txt including AI crawler block rules and Sitemap pointing to externalStorefrontUrl
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
curl -X GET "https://{site}/api/v1/seo/robots.txt"/seo/indexnow-key.txtdelivery_seo_indexnow_key
BetaRead-onlyIndexNow key verification file content; external frontends rewrite `/<key>.txt` to this endpoint so Bing/Naver/Seznam/Yandex can verify ownership of the external storefront domain
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
curl -X GET "https://{site}/api/v1/seo/indexnow-key.txt"/seo/jsonlddelivery_seo_jsonld
BetaRead-onlySchema.org JSON-LD @graph for a given page path
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
Query parameters
pathstringRelative page path starting with / (e.g. /, /about, /blog, /blog/my-post)
curl -X GET "https://{site}/api/v1/seo/jsonld"Blog
/feeddelivery_blog_feed_rss
BetaRead-onlyBlog RSS 2.0 feed (respects blog collection accessPolicy)
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
Query parameters
tagstringFilter by blog_tags slug
authorstringFilter by blog_authors slug
limitinteger
curl -X GET "https://{site}/api/v1/feed"/feed.atomdelivery_blog_feed_atom
BetaRead-onlyBlog Atom 1.0 feed (respects blog collection accessPolicy)
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
Query parameters
tagstringFilter by blog_tags slug
authorstringFilter by blog_authors slug
limitinteger
curl -X GET "https://{site}/api/v1/feed.atom"Collections & Blog Items
/collectionsdelivery_collections_list
BetaRead-onlyCollections and their fields (self-describing). System collections also list virtualFields (projection-only fields such as blog segments/toc/contentHtml and taxonomy counts) with scope item|fieldData and a TypeScript type literal.
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
curl -X GET "https://{site}/api/v1/collections"/collections/{key}/itemsdelivery_collection_items
BetaRead-onlyPublished items of a collection
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
Path parameters
keystringRequired
Query parameters
filterobjectBracket-notation filter conditions (up to 10 conditions combined with AND, plus 2-level OR groups via filter[any][0][field][op]=value). Shorthand filter[field]=value equals filter[field][eq]=value. 15 operators by field type: eq, ne, in, nin (up to 100 comma-separated values), gt, gte, lt, lte, contains, ncontains, match (multi-word substring match on text/rich_text, max 1 per query and 8 words), exists (true|false), has (multi_select/multi_reference), eq_slug (reference), has_slug (multi_reference). Item-level attributes slug, publishedAt, createdAt, updatedAt are also filterable. Date/datetime fields accept relative expressions: now or now[+-]<N><s|m|h|d|w|M|y> (e.g. filter[publishedAt][gte]=now-30d).
sortstringComma-separated sort fields (up to 3 fields), prefix with `-` for descending (e.g. `sort=-publishedAt,title`), or bracket form `sort[field]=asc|desc`. Sortable: scalar fields and item attributes (`slug`, `publishedAt`, `createdAt`, `updatedAt`); `rich_text`, `json`, `image`, `gallery`, `file`, and `multi_*` are not sortable.
limitintegerPage size (1–100, default 20).
offsetintegerOffset pagination index (prefer `cursor` for deep pagination).
cursorstringOpaque `nextCursor` token from the previous response.
totalbooleanPass `total=false` to skip the `COUNT(*)` query and return `total: null` for faster cursor pagination.
fieldsstringComma-separated `fieldData` field IDs to project (top-level item metadata `id`, `slug`, `publishedAt`, `updatedAt` are always returned).
expandstringComma-separated `reference` or `multi_reference` field IDs (plus `primary_author`, `primary_category` on `blog`) to expand 1 layer into `item.expanded[fieldId]`. Referenced media assets are automatically included in the top-level `assets` map (trashed, missing, or private-bucket assets are filtered out).
formatsstringComma-separated blog content formats: markdown, html, plaintext
localestringOptional locale assertion; must match the site's configured `Website.locale` or returns 400 `UNSUPPORTED_LOCALE`.
previewstringPass `preview=1` with `X-Kanorio-Preview: knr_pv_<token>` (or a server-held PAT with `collections:view`) to read unpublished draft `fieldData` (`Cache-Control: no-store`).
curl -X GET "https://{site}/api/v1/collections/{key}/items"/collections/{key}/items/{slug}delivery_collection_item
BetaRead-onlyOne published item by slug
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
Path parameters
keystringRequiredslugstringRequired
Query parameters
fieldsstringexpandstringformatsstringComma-separated blog content formats: markdown, html, plaintext
previewstring
curl -X GET "https://{site}/api/v1/collections/{key}/items/{slug}"Forms & Anti-Abuse Challenge
/forms/{id}delivery_form_get
BetaRead-onlyPublic online form definition (fields, availability, consent)
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
Path parameters
idstringRequired
curl -X GET "https://{site}/api/v1/forms/{id}"/forms/{id}/challengedelivery_form_challenge
BetaRead-onlyFetch a server-signed anti-spam challenge for form submission
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
Path parameters
idstringRequired
curl -X GET "https://{site}/api/v1/forms/{id}/challenge"/forms/{id}/upload-requestdelivery_form_upload_request
BetaRequest a signed upload ticket for a form file attachment field
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
Path parameters
idstringRequired
curl -X POST "https://{site}/api/v1/forms/{id}/upload-request" \
-H "Content-Type: application/json" \
-d '{"fieldId":"string","fileName":"string","mimeType":"string","fileSize":1,"_hp":"string","_wp":"string","_co":"string","_ts":1}'/forms/{id}/submitdelivery_form_submit
BetaSubmit answers to an online form
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
Path parameters
idstringRequired
curl -X POST "https://{site}/api/v1/forms/{id}/submit" \
-H "Content-Type: application/json" \
-d '{"answers":null,"consent":true,"consentTextId":"string","locale":"string","pagePath":"string","_hp":"string","_challenge":{"nonce":"string","ts":1,"sig":"string"}}'Products & Catalog
/productsdelivery_products_list
BetaRead-onlyPublished products listed in the shop (no deliverable outline)
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
Query parameters
pageintegerlimitintegercategorystringlocalestring
curl -X GET "https://{site}/api/v1/products"/products/{slug}delivery_products_get
BetaRead-onlyOne product, including the public outline of its deliverables
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
Path parameters
slugstringRequired
Query parameters
localestring
curl -X GET "https://{site}/api/v1/products/{slug}"Free Preview Units
/units/{id}/opendelivery_units_open_preview
BetaOpen a free-preview unit anonymously (isPreview only)
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
Path parameters
idstringRequired
curl -X POST "https://{site}/api/v1/units/{id}/open" \
-H "Content-Type: application/json" \
-d '{"mode":"read"}'Analytics
/analytics/pageviewdelivery_analytics_pageview
BetaRecord an anonymous pageview from an external storefront (per-IP rate-limited)
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
curl -X POST "https://{site}/api/v1/analytics/pageview" \
-H "Content-Type: application/json" \
-d '{"path":"string","referrer":"string","title":"string","uaCategory":"desktop"}'/analytics/bot-hitdelivery_analytics_bot_hit
BetaRecord an AI crawler visit from an external storefront edge middleware (per-IP rate-limited)
- Permission
- none
- Rate limit
- 20 misses/s per site (burst 100), 10/s per IP (burst 30); preview 2/s (burst 20); customer token 5/s (burst 30); cache hits unlimited
curl -X POST "https://{site}/api/v1/analytics/bot-hit" \
-H "Content-Type: application/json" \
-d '{"botToken":"string","path":"string","userAgent":"string"}'Error codes
{
"error": {
"code": "ITEM_NOT_FOUND",
"message": "Item not found."
}
}| Code | HTTP |
|---|---|
| BAD_REQUEST / QUERY_INVALID / INVALID_BODY / INVALID_PATH / UNKNOWN_BOT | 400 |
| UNAUTHORIZED / PREVIEW_UNAUTHORIZED | 401 |
| FORBIDDEN / NO_ENTITLEMENT / NOT_YET_RELEASED | 403 |
| NOT_FOUND / COLLECTION_NOT_FOUND / ITEM_NOT_FOUND | 404 |
| RATE_LIMITED | 429 |
| UPSTREAM_UNAVAILABLE | 503 |