Catalogue
Browse products, variants, categories, collections, bundles, composites, deals, and price quotes. Read-only on the public client; safe to call from any environment.
List products
const r = await client.catalogue.getProducts({
limit: 24,
page: 1,
category: 'cat_beverages',
search: 'latte',
featured: true,
in_stock: true,
sort_by: 'price',
sort_order: 'asc',
})
if (!r.ok) {
console.error(r.error.code, r.error.message)
return
}
console.log(r.value.items) // Product[]
console.log(r.value.is_complete) // boolean: true when fully paginated
console.log(r.value.pagination) // { total_count, current_page, page_size, total_pages, has_more }Single product
Both getProductById and getProductBySlug resolve to the same endpoint; the server accepts either a UUID or a slug.
const byId = await client.catalogue.getProductById('prod_xxx')
const bySlug = await client.catalogue.getProductBySlug('studio-tee-natural')
if (bySlug.ok) {
const product = bySlug.value // ProductWithDetails
console.log(product.id, product.name)
console.log(product.variants)
console.log(product.add_ons)
console.log(product.images)
}Variants
const variants = await client.catalogue.getVariants('prod_xxx')
const single = await client.catalogue.getVariantById('prod_xxx', 'var_yyy')
// Find a variant by axis selections (size: M, color: blue)
const found = await client.catalogue.getVariantByAxisSelections('prod_xxx', {
size: 'M',
color: 'blue',
})
if (found.ok && found.value) {
console.log(found.value.id, found.value.default_price)
}Categories and collections
const categories = await client.catalogue.getCategories()
const collections = await client.catalogue.getCollections()
// Pull products under a category
const drinks = await client.catalogue.getCategoryProducts('cat_beverages', { limit: 50 })
// Or under a collection
const summer = await client.catalogue.getCollectionProducts('col_summer', { limit: 50 })Bundles and composites
Bundles are fixed product groupings with a single combined price. Composites are build-your-own: the customer picks one option per component and the price is computed from those selections.
// Bundles
const bundles = await client.catalogue.getBundles()
const bundle = await client.catalogue.getBundleById('bun_xxx')
// Composites
const composites = await client.catalogue.getComposites()
const composite = await client.catalogue.getCompositeById('comp_xxx')
// Price a composite from a set of selections
const price = await client.catalogue.calculateCompositePrice(
'comp_xxx',
[
{ component_id: 'comp_base', selected_option_id: 'opt_classic' },
{ component_id: 'comp_milk', selected_option_id: 'opt_oat' },
],
'loc_main',
)Add-ons
const addOns = await client.catalogue.getAddOns('prod_xxx')
if (addOns.ok) {
for (const group of addOns.value) {
console.log(group.name, group.options)
}
}Price quotes
Whenever variants, add-ons, bundle picks, or composite picks affect price, fetch a quote first and pass quote_id to cart.addItem. Quotes have an expires_at; refresh if the user dwells.
const quote = await client.catalogue.fetchQuote({
product_id: 'prod_xxx',
variant_id: 'var_yyy',
quantity: 2,
add_on_option_ids: ['addopt_oat_milk'],
location_id: 'loc_main',
})
if (!quote.ok) {
console.error(quote.error.code, quote.error.message)
return
}
await client.cart.addItem({
item_id: 'prod_xxx',
quantity: 2,
variant_id: 'var_yyy',
add_on_options: ['addopt_oat_milk'],
quote_id: quote.value.quote_id,
})
// Refresh an aging quote
const refreshed = await client.catalogue.refreshQuote({
quote_id: quote.value.quote_id,
quantity: 3,
})
if (refreshed.ok) {
console.log(refreshed.value.quote.quote_id)
}Discounts
Validate a code at the line / subtotal level before applying it to the cart. Order subtotal is passed as a Money string.
const r = await client.catalogue.validateDiscountCode('WELCOME10', '49.99', 'loc_main')
if (r.ok) {
console.log(r.value.is_valid, r.value.discount_amount)
}Taxonomy
const tree = await client.catalogue.getTaxonomies() // top-level
const subtree = await client.catalogue.getTaxonomies('tax_root') // children of a node
const node = await client.catalogue.getTaxonomy('tax_xxx') // node + children
const path = await client.catalogue.getTaxonomyPath('tax_xxx') // ancestor chain
const matches = await client.catalogue.searchTaxonomies('coffee', 10)Method reference
| Method | Returns |
|---|---|
getProducts(opts?) | Result<CatalogueResult<Product>> |
getProductById(id) | Result<ProductWithDetails> |
getProductBySlug(slug) | Result<ProductWithDetails> |
getVariants(productId) | Result<ProductVariant[]> |
getVariantById(productId, variantId) | Result<ProductVariant> |
getVariantByAxisSelections(productId, axes) | Result<ProductVariant | null> |
getAddOns(productId) | Result<AddOn[]> |
getCategories() | Result<Category[]> |
getCategoryProducts(id, opts?) | Result<Product[]> |
getCollections() | Result<Collection[]> |
getCollectionProducts(id, opts?) | Result<Product[]> |
getBundles() | Result<BundleSummary[]> |
getBundleById(id) | Result<Bundle> |
getComposites() | Result<Composite[]> |
getCompositeById(id) | Result<Composite> |
calculateCompositePrice(id, sels, locId?) | Result<CompositePriceResult> |
fetchQuote(input, opts?) | Result<PriceQuote> |
getQuote(id) | Result<PriceQuote> |
refreshQuote(input) | Result<RefreshQuoteResult> |
validateDiscountCode(code, subtotal, locId?) | Result<DiscountValidation> |
getTaxonomies(parentId?) | Result<ProductTaxonomy[]> |
searchTaxonomies(q, limit?) | Result<ProductTaxonomy[]> |
search(query, opts?) | Result<Product[]> |
Related
-
Cart Add quoted items to a session cart
-
Scheduling Variant-aware availability for service products
-
Money type Why prices are strings and how to render them
-
Server-rendered pages Cache catalogue reads with tags + revalidate
Element events
Cimplify Elements communicate with the parent page via `window.postMessage`. Below is the full event union sent _from_ the iframe, defined as `IframeToParentMessage` in `@cimplify/sdk`. The parent-side controller in the SDK already validates and dispatches these for you; this page is for when you want to wire them up directly.
Cart
Session-bound cart. Add items with a flat payload, apply coupons, and read totals as branded ` Money` strings. The SDK returns `Result<T>` on every method and never throws.