> ## Documentation Index
> Fetch the complete documentation index at: https://www.commercengine.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Catalog

> The Catalog module is the cornerstone of your Commerce Engine storefront. It defines everything you sell – products, their variations, how they're organized, priced, and described. Mastering these APIs allows you to build compelling product listings, detailed descriptions, category navigation, powerful search, customer reviews, and insightful recommendations.

**Key Features Covered:**

* **Flexible Product Modeling:** Handles simple products, products with options (variants), digital goods, and bundled items.
* **Products, Variants, and Items:** Clear structure distinguishing the core product concept from its specific sellable variations (Items).
* **Rich Attributes:** Define characteristics for filtering, display, and variant creation (Color, Size, Brand, etc.).
* **Hierarchical Categories:** Organize your catalog for easy navigation.
* **Engaging Content:** Support for multiple images, videos, detailed descriptions, and SEO metadata per product *and* variant.
* **Dynamic Pricing & B2B:** Define base prices, handle taxes, and set specific prices/promotions for different **Customer Groups**.
* **Inventory & Promotions:** Real-time stock availability and flags for active promotions/offers on specific Items.
* **Integrated Reviews:** List and capture customer reviews with ratings, text, images, and videos.
* **Product Recommendations:** APIs for similar, upsell, and cross-sell suggestions.
* **Faceted Search:** Robust search powered by product attributes.

## Core Concepts

Grasping these foundational models is essential for leveraging the Catalog API effectively.

<AccordionGroup>
  <Accordion title="The Product-Variant-Item Hierarchy">
    Commerce Engine uses a flexible structure to represent your offerings:

    1. **`Product (Product schema):`**
       * **Definition:** The core concept or base model of an item you sell (e.g., "Men's Cotton T-Shirt", "Espresso Machine", "Beginner's Yoga Course").
       * **Shared Data:** Holds information common across all its potential variations:
         * Base Name (`name`)
         * Product Type (`product_type`: physical, digital, bundle)
         * HSN Code (`hsn_code`)
         * Categories (`category_ids`)
         * Tags (`tags`)
         * Base Attributes (`attributes`): Characteristics shared by all variations (e.g., 'Brand', 'Material').
         * Base SEO (`seo`)
       * **Variant Indicator:** The `has_variant` flag (boolean) indicates if this product branches into different selectable options (like size or color).
    2. **`Variant (Variant schema):`**
       * **Definition:** A *specific version* of a Product, existing **only** if the Product's `has_variant` flag is `true`. It represents a unique combination of selected Variant Options (e.g., "Men's Cotton T-Shirt - Blue / Large").
       * **Specific Data:** While conceptually linked to the parent Product, a Variant holds its own specific details for:
         * SKU (`sku`) - The warehouse identifier for this specific variation.
         * Name (`name`) - Often includes option values (e.g., "T-Shirt - Red, Large").
         * Slug (`slug`)
         * Descriptions (`short_description`, `description`)
         * Images (`images`) - Can override or supplement Product images.
         * Videos (`videos`)
         * Pricing (`pricing`)
         * Subscription Pricing (`subscription`)
         * Promotions (`promotion`)
         * Inventory (Stock is tracked *per Variant*)
         * Shipping Details (`shipping`)
         * Packaging Details (Managed via Admin/other APIs)
         * Variant Attributes (`variant_attributes`) - Attributes specific *only* to this variant.
         * Associated Options (`associated_options`) - Links back to the specific option values (e.g., `{ "color": "Blue", "size": "Large" }`).
       * **Retrieval:** Variants are typically listed via `GET /products/{product_id}/variants` or retrieved individually via `GET /products/{product_id}/variants/{variant_id}`.
    3. ***`Item (Item/SKU schema - Note: To be renamed from SKU in future spec):`***
       * **Definition:** This represents the **uniquely identifiable, sellable unit** that a customer ultimately adds to their cart and purchases. It's the lowest level of granularity for a purchasable entity.
       * **Structure:** Contains `product_id`, `variant_id` (which is `null` if the product has no variants), and potentially a `sku` (which might be `null` for digital products or bundles). It aggregates relevant details needed for display and purchase (name, pricing, image, stock status, attributes, etc.) from either the Product (if no variants) or the specific Variant.
       * **Usage:** APIs like `GET /catalog/skus`, `POST /catalog/products/search`, and the related products endpoints (`similar`, `upsell`, `cross-sell`) return lists of these flattened **Item Objects**. This simplifies building listings (PLPs, search results) where you need a direct list of things to buy.
  </Accordion>

  <Accordion title="Attributes vs. Variant Options">
    This is a critical distinction in Commerce Engine:

    * **`Attributes (ProductAttribute schema & its types):`**
      * **Purpose:** Primarily used to **enrich** product or variant data, provide **filtering** capabilities (search facets), and display **specifications**.
      * **Types:** Color, Single-Select, Multi-Select, Text, Date, Number, Boolean.
      * **Behavior:** Generally, attributes *do not* create separate inventory tracking or fundamentally change the sellable item. They add metadata.
      * **Configuration:** Defined in the Admin UI with flags like `is_filterable`, `is_visible`.
    * **`Variant Options (VariantOption schema, associated_options in Variant):`**
      * **Purpose:** Used to **logically branch** a product into distinct, sellable Variants.
      * **Eligible Attribute Types:** Only `single-select` or `color` attributes can be designated for variant creation (by enabling the `can_be_used_to_create_variants` flag during attribute setup).
      * **Behavior:** Each unique combination of selected Variant Options results in a separate `Variant` record. This allows for **unique SKUs, inventory tracking, pricing, images, etc., per combination.**
      * **Example:** A "T-Shirt" Product might use "Size" (single-select) and "Color" (color) attributes as Variant Options. This creates Variants like "T-Shirt - Red, Small", "T-Shirt - Blue, Large", each potentially having its own stock level and image.

    <Tip>
      **Decision Guide: Variant Option vs. Attribute?**

      Ask these questions when defining a product characteristic:

      1. Does this characteristic combination need a **unique identifier (SKU)** in my warehouse or system?
      2. Do I need to track **inventory separately** for each specific combination (e.g., track stock of 'Red Large' shirts separately from 'Blue Medium')?
      3. Do I need to set **different prices, images, or descriptions** for specific combinations?
      4. Do customers need to **explicitly select** this characteristic combination to add the item to their cart?

      **`If YES to any of these, use a single-select or color attribute and enable can_be_used_to_create_variants to make it a Variant Option.`**

      **If NO, use a standard Attribute** for enrichment, filtering, or display purposes (e.g., 'Material', 'Brand', 'Country of Origin', 'Features').
    </Tip>
  </Accordion>

  <Accordion title="Product Types Explained">
    * **Physical:** Tangible goods needing shipping. Can have variants. Have SKUs, inventory tracking, shipping details.
    * **Digital:** Non-tangible goods (e-books, software, courses). Can have variants. `sku` is optional (can be `null`). No inventory tracking (`stock_available` might always be true or managed differently). No shipping/packaging details. Often use subscription pricing.
    * **Bundle:** A logical grouping of existing Items (defined by their `product_id` and `variant_id`/`sku`) sold as one unit (`bundle_items` array in Product schema).
      * **Cannot have variants.**
      * **No unique SKU or inventory:** Stock status depends entirely on the availability of *all* included items.
      * Has its own Product record for name, descriptions, pricing (often discounted), promotions, images, videos, SEO.
      * Shipping/packaging is implicitly derived from the constituent physical items.
  </Accordion>

  <Accordion title="Other Key Concepts">
    * **`Categories (ProductCategory, Category):`** Hierarchical (`parent_category_id`) organization. Fetched via `GET /catalog/categories`.
    * **`Pricing (ProductPricing):`** Defines `listing_price`, `selling_price`, currency, taxes, quantity limits. **Variant-specific**. Supports B2B `customer_group_id` overrides.
    * **`Promotions/Offers (on_promotion, on_offer, promotion object):`** Indicate automatic discounts or available coupons. **Variant-specific**.
    * **`Reviews (ProductReview, CreateReview):`** Managed per `product_id`. Includes ratings, text, images, videos. List via `GET /products/{id}/reviews`, submit via `POST /products/{id}/reviews`.
    * **`Related Products (similar, upsell, cross-sell):`** Endpoints return lists of relevant **Item Objects**.
  </Accordion>
</AccordionGroup>

### Key Catalog Endpoints (Summary & Key Purpose)

* **`GET /catalog/products`**: List core products. Use `has_variant` to know if options exist. Good starting point for PLPs if you handle variant selection/flattening client-side. Contains base info and potentially variant summaries in `variants` array.
* **`GET /catalog/skus`**: List flattened, sellable **Items**. Ideal for PLPs or inventory checks where you need a direct list of purchasable units, bypassing product hierarchy.
* **`GET /catalog/products/{product_id}`**: Get full details for a single Product, including shared data, attributes, and variant options/summaries. Core for PDPs.
* **`GET /catalog/products/{product_id}/variants`**: List all specific Variants for a product (if `has_variant: true`). Provides variant-specific details (pricing, SKU, images).
* **`GET /catalog/products/{product_id}/variants/{variant_id}`**: Get full details for one specific Variant.
* **`GET /catalog/categories`**: Fetch category tree for navigation.
* **`GET /catalog/products/{product_id}/reviews`**: List reviews for a product.
* **`POST /catalog/products/{product_id}/reviews`**: Submit a review (requires logged-in user, order number).
* **`GET /catalog/products/similar`**: Get similar **Items**.
* **`GET /catalog/products/up-sell`**: Get upsell **Items**.
* **`GET /catalog/products/cross-sell`**: Get cross-sell **Items**.
* **`POST /catalog/products/search`**: Search returns a list of matching **Items**, plus facet data for filtering.

## Common Use Cases & Flows

<AccordionGroup>
  <Accordion title="Displaying a Product Listing Page (PLP)">
    **`Option A: Using GET /catalog/products (Client-side Variant Handling)`**

    1. Call `GET /catalog/products` with filters (`category_id`, `customer_group_id`).
    2. Iterate through the `products` array.
    3. For each product:
       * Display common info: `name`, primary image (`images[0]`).
       * Check `has_variant`:
         * **`If false:`** Display price from `product.pricing`. The "Add to Cart" button uses `product_id` and `variant_id: null`.
         * **`If true:`**
           * Display a price range or the default variant's price (from `product.variants` array, find where `is_default: true`).
           * The "Add to Cart" button might need to direct to the PDP for option selection, OR you could potentially render simple variant selectors (e.g., color swatches) directly on the card using data from `product.variants` and add the selected `variant_id` to the cart.
       * Link to PDP using `product.slug` or `product_id`.

    **`Option B: Using GET /catalog/skus (Pre-flattened Items)`**

    1. Call `GET /catalog/skus` with filters (`category_id`, `customer_group_id`). This directly returns sellable **Items**.
    2. Iterate through the `items` (renamed from `skus`) array.
    3. For each item:
       * Display `item.product_name` and potentially `item.variant_name`.
       * Display image (`item.images[0]`).
       * Display price (`item.pricing.selling_price`).
       * The "Add to Cart" button uses `item.product_id` and `item.variant_id`.
       * Link to the PDP using `item.product_id` (and potentially pre-select the variant based on `item.variant_id`).
       * This approach is simpler if you don't need complex variant selection directly on the PLP card.
  </Accordion>

  <Accordion title="Displaying a Product Detail Page (PDP)">
    1. Call `GET /catalog/products/{product_id_or_slug}`. Pass `customer_group_id` if applicable.
    2. Render shared Product details: `name`, `description`, attributes (`attributes`), base images/videos, SEO.
    3. **`If product.has_variant is true:`**
       * Render selection controls (dropdowns, swatches) based on `product.variant_options`.
       * Call `GET /catalog/products/{product_id}/variants` to fetch all variant data upfront *or* implement logic to fetch/update details (price, image, SKU, stock status, variant-specific description/attributes) dynamically as the user selects options. Map selected options to the corresponding `Variant` using its `associated_options`.
       * Enable "Add to Cart" only when a valid variant combination is selected. Use the selected `variant_id`.
       * Display variant-specific pricing, images, stock status.
    4. **`If product.has_variant is false:`**
       * Display pricing, stock status, images directly from the `Product` object.
       * "Add to Cart" uses `product_id` and `variant_id: null`.
    5. Fetch and display reviews (`GET /products/{id}/reviews`).
    6. Fetch and display related products (`similar`, `upsell`, `cross-sell`), passing the current `product_id`.
  </Accordion>

  <Accordion title="Implementing Search with Facets">
    <Frame>
      <iframe title="Search with Facets Flow" allowfullscreen width="100%" height="500" src="https://mermaid.tarkai.dev/embed?definition=sequenceDiagram%0A%20%20%20%20participant%20ClientApp%20as%20Client%20Application%0A%20%20%20%20participant%20User%0A%20%20%20%20participant%20CE_API%20as%20CE%20API%0A%0A%20%20%20%20User-%3E%3EClientApp%3A%20Enters%20search%20query%20%22red%20shirt%22%0A%20%20%20%20ClientApp-%3E%3ECE_API%3A%20POST%20%2Fcatalog%2Fproducts%2Fsearch%20(Req%3A%20%7Bquery%3A%20%22red%20shirt%22%2C%20facets%3A%20%5B%22size%22%2C%20%22color%22%2C%20%22brand%22%5D%7D)%0A%20%20%20%20activate%20CE_API%0A%20%20%20%20CE_API--%3E%3EClientApp%3A%20200%20OK%20(Res%3A%20%7Bitems%5B%5D%2C%20facet_distribution%7B...%7D%2C%20pagination%7D)%0A%20%20%20%20deactivate%20CE_API%0A%0A%20%20%20%20ClientApp-%3E%3EClientApp%3A%20Render%20initial%20results%20(items)%20%26%20filters%20(facet_distribution)%0A%0A%20%20%20%20User-%3E%3EClientApp%3A%20Selects%20filter%20%22Size%3A%20M%22%0A%20%20%20%20ClientApp-%3E%3ECE_API%3A%20POST%20%2Fcatalog%2Fproducts%2Fsearch%20(Req%3A%20%7Bquery%3A%20%22red%20shirt%22%2C%20facets%3A%5B...%5D%2C%20filters%3A%20%7Bsize%3A%20%22M%22%7D%7D)%0A%20%20%20%20activate%20CE_API%0A%20%20%20%20CE_API--%3E%3EClientApp%3A%20200%20OK%20(Res%3A%20%7Bfiltered%20items%5B%5D%2C%20updated%20facet_distribution%7B...%7D%2C%20pagination%7D)%0A%20%20%20%20deactivate%20CE_API%0A%0A%20%20%20%20ClientApp-%3E%3EClientApp%3A%20Render%20updated%20results%20and%20filters" />
    </Frame>
  </Accordion>
</AccordionGroup>
