API reference
Products
Content Delivery API: GET /products, GET /products/{slug}
Parameters
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.
categorystring · queryauthorstring · queryAuthor/instructor slug (system collection authors). Returns only products linked to an active deliverable this person teaches; use it to list a person's courses on an instructor page.
localestring · queryLocale for product names, descriptions, options and the category record, and for promotion badge text. One of the site's locales from /site (a code such as `en-US` or the URL prefix such as `en`); omit it for the primary locale. Other values, including locales that are still translating, return 400 UNSUPPORTED_LOCALE. Untranslated fields fall back to the primary locale.
Response 200
dataobject[]requireddata[].resolvedLocalestringMultilingual sites only: the locale this product was delivered in (the requested locale when it has a published translation, otherwise the primary locale).
data[].availableLocalesstring[]Multilingual sites only: locales with a published translation of this product (the primary locale is not listed). Use it for hreflang and canonical.
data[].localePathsobjectMultilingual sites only: this product's path in every live locale, keyed by locale code, without the locale prefix (each locale can have its own translated slug). Use it for hreflang, a language switcher and sitemap alternates.
data[].idstringrequireddata[].slugstringrequireddata[].titlestringrequireddata[].descriptionstring | nulldata[].typestringdata[].currencystringrequireddata[].imagesobject[]data[].optionsobject[]Option dimensions (0–3). Each pricing tier's `optionValues` lists one value per option, in this order. With `locale`, `name` and `values` are translated and tier `optionValues` use the same translated strings.
data[].options[].idstringStable option id (the key for option translations)
data[].options[].namestringrequireddata[].options[].valuesstring[]requireddata[].pricingTiersobject[]requireddata[].allowCustomAmountbooleandata[].canPurchasebooleanrequireddata[].deliverablesobject[]data[].deliverables[].idstringrequiredDeliverable id. Pass it to <kanorio-curriculum deliverable> or the Customer API.
data[].deliverables[].titlestringrequireddata[].deliverables[].descriptionstring | nullrequireddata[].deliverables[].structure"COURSE" | "DOWNLOAD"requireddata[].deliverables[].coverAssetIdstring | nullrequireddata[].deliverables[].coverobject | nullCover image of the deliverable (null when unset or the image is in the trash).
data[].deliverables[].authorsobject[]Authors/instructors in the owner's order (shared site author list). Older servers omit it.
data[].deliverables[].unitCountintegerrequireddata[].deliverables[].totalDurationSecondsnumber | nullrequireddata[].deliverables[].unitsobject[]requireddata[].updatedAtstringdata[].seoobject | nullProduct SEO (title, description, Open Graph, robots). Null when unset.
data[].pageSeoobject | nullAlias of seo, kept for the hosted storefront.
hasMorebooleanrequiredTrue when another page exists; pass nextCursor to fetch it.
nextCursorstring | nullrequiredCursor for the next page, or null on the last page.
Errors
UNSUPPORTED_LOCALE400INVALID_CURSOR400
curl -X GET "https://{site}/api/v1/products"Parameters
slugstring · pathrequiredlocalestring · queryLocale for the product name, description, SEO fields, options and deliverable outline, and for promotion badge text. One of the site's locales from /site (a code such as `en-US` or the URL prefix such as `en`); omit it for the primary locale. Other values, including locales that are still translating, return 400 UNSUPPORTED_LOCALE. Untranslated fields fall back to the primary locale. On multilingual sites the product carries resolvedLocale and availableLocales.
Response 200
productobjectrequiredproduct.resolvedLocalestringMultilingual sites only: the locale this product was delivered in (the requested locale when it has a published translation, otherwise the primary locale).
product.availableLocalesstring[]Multilingual sites only: locales with a published translation of this product (the primary locale is not listed). Use it for hreflang and canonical.
product.localePathsobjectMultilingual sites only: this product's path in every live locale, keyed by locale code, without the locale prefix (each locale can have its own translated slug). Use it for hreflang, a language switcher and sitemap alternates.
product.idstringrequiredproduct.slugstringrequiredproduct.titlestringrequiredproduct.descriptionstring | nullproduct.typestringproduct.currencystringrequiredproduct.imagesobject[]product.optionsobject[]Option dimensions (0–3). Each pricing tier's `optionValues` lists one value per option, in this order. With `locale`, `name` and `values` are translated and tier `optionValues` use the same translated strings.
product.options[].idstringStable option id (the key for option translations)
product.options[].namestringrequiredproduct.options[].valuesstring[]requiredproduct.pricingTiersobject[]requiredproduct.allowCustomAmountbooleanproduct.canPurchasebooleanrequiredproduct.deliverablesobject[]product.deliverables[].idstringrequiredDeliverable id. Pass it to <kanorio-curriculum deliverable> or the Customer API.
product.deliverables[].titlestringrequiredproduct.deliverables[].descriptionstring | nullrequiredproduct.deliverables[].structure"COURSE" | "DOWNLOAD"requiredproduct.deliverables[].coverAssetIdstring | nullrequiredproduct.deliverables[].coverobject | nullCover image of the deliverable (null when unset or the image is in the trash).
product.deliverables[].authorsobject[]Authors/instructors in the owner's order (shared site author list). Older servers omit it.
product.deliverables[].unitCountintegerrequiredproduct.deliverables[].totalDurationSecondsnumber | nullrequiredproduct.deliverables[].unitsobject[]requiredproduct.updatedAtstringproduct.seoobject | nullProduct SEO (title, description, Open Graph, robots). Null when unset.
product.pageSeoobject | nullAlias of seo, kept for the hosted storefront.
Errors
PRODUCT_NOT_FOUND404UNSUPPORTED_LOCALE400
curl -X GET "https://{site}/api/v1/products/{slug}"