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

# Storefront Catalog API

> Customer-facing product display, search, and navigation APIs

# Kibo Storefront Catalog API Developer Guide

<Card title="Catalog" icon="book-open" href="/concept-guides/catalog" horizontal data-rec="developer-backlink">
  Understand catalog architecture and concepts
</Card>

## Understanding Storefront Catalog in Kibo

The Kibo Storefront Catalog API is your primary tool for building customer-facing experiences. Unlike the Catalog Admin API, which is for managing product data, the **Storefront API is optimized for speed, security, and displaying product information to shoppers**. It's designed to be called directly from a browser or a front-end application. Kibo's philosophy here is to provide a performant, read-only view of your catalog that respects all merchandizing rules, such as active products, sale prices, and inventory visibility, without exposing sensitive administrative data.

***

## How This Domain Fits Into Kibo

The Storefront Catalog API is the bridge between your back-end product data and your live website. It's the engine that powers key e-commerce experiences:

* **Search**: When a shopper uses the search bar, the Storefront API's search endpoints are used to find relevant products.
* **Navigation**: When a shopper clicks on a category link, the Storefront API fetches the category details and the products within it.
* **Product Detail Pages (PDP)**: Viewing a specific product involves calling the Storefront API to get its details, including images, price, and options.
* **Cart & Checkout**: Before a product is added to the cart, the Storefront API is often used to validate its price and availability.

***

## Prerequisites

* Kibo Application Key (public key, safe for front-end use)
* Node.js 16+ with TypeScript
* Familiarity with REST APIs and front-end development concepts

***

## What You'll Learn

After completing this guide, you'll understand:

* How Kibo structures storefront-facing catalog data (based on official API specs)
* The key patterns Kibo uses across all Storefront Catalog APIs (verified from apidocs.kibocommerce.com)
* Common workflows for building a storefront experience, like searching and navigation
* How to avoid the most common beginner mistakes
* How to effectively use Kibo's powerful search and filtering capabilities

***

## Kibo Storefront Catalog Fundamentals

### How Kibo Organizes Storefront Data

The Storefront API presents a curated version of your catalog data. A `Product` object from this API will include shopper-centric information like its `priceRange`, `productImages`, and `options`, but will omit internal data like cost. It also returns a `productCode` which is the key identifier used to add an item to the cart.

### Key Kibo Patterns You'll See Everywhere

**Authentication Pattern:**
Storefront APIs use a simpler authentication method. You only need your public **Application Key**, which is passed in the `x-vol-app-claims` header. The Kibo SDK handles this header for you when you create your `Configuration` object, but it's important to know you're not using a shared secret on the front end.

**Request/Response Structure:**
Storefront API responses for product collections (`ProductSearchResult`) include not only the products (`items`) but also useful metadata for building a UI, such as `facets`, `totalCount`, and `pageSize`.

**Error Handling Approach:**
If a shopper tries to access a disabled product or a non-existent category, the API will return a standard `404 Not Found` error. The SDK will throw an error containing the response details.

**Pagination and Filtering:**
Pagination is important for storefront performance. You'll use `startIndex` and `pageSize` to load products on category and search pages. Filtering on the storefront is often done through **facets**, which are dynamically returned by the search API.

**API Documentation Reference:**
Throughout this guide, we'll reference specific endpoints. Find complete specs at:
`/api-overviews/openapi_catalog_storefront_overview`

***

### Common Storefront Catalog Workflows

1. **Building Navigation**: Fetching the category tree to create menus and navigation bars.
2. **Displaying Product Grids**: Getting a list of products for a specific category or search query.
3. **Powering Site Search**: Using the search endpoint with various parameters to handle user queries, filtering, and sorting.

Let's explore each pattern step by step.

***

## Getting a List of Products: The Kibo Way

### When You Need This

This is one of the most common operations. You need it whenever you want to display a grid of products, such as on a category page, a search results page, or a "New Arrivals" promotional page.

***

### API Documentation Reference

* **Endpoint:** `GET /api/commerce/catalog/storefront/products/`
* **Method:** `GET`
* **API Docs:** [`/api-reference/storefrontproducts/get-products`](/api-reference/storefrontproducts/get-products)

***

### Understanding the Kibo Approach

Kibo's `storefrontGetProducts` endpoint is a powerful, multi-purpose tool. It's not just for fetching all products; it's designed to be filtered and sorted to meet various storefront needs. The key Kibo pattern here is the use of the `filter` parameter. Instead of having separate endpoints for "products in a category" vs. "products by brand," you use one endpoint and apply different filters. For example, `filter=categoryId eq 123` gets products for a specific category.

***

### Code Structure Walkthrough

```typescript theme={null}
// We'll build this step by step:
// 1. **Configuration**: Create a central Configuration instance with our storefront API credentials.
// 2. **API Client Instantiation**: Create a dedicated client for the Storefront Products API.
// 3. **Parameter Preparation**: Define the filter, page size, and other parameters for our query.
// 4. **API Call**: Use the client to call the `storefrontGetProducts` method.
```

***

#### Step-by-Step Implementation

**Step 1: Setting Up the Foundation**

```ts theme={null}
// Essential imports for Storefront Catalog operations.
// We import the Configuration class and the specific API client we need.
import { Configuration } from "@kibocommerce/rest-sdk";
import { ProductSearchApi } from "@kibocommerce/rest-sdk/clients/CatalogStorefront/apis/ProductSearchApi.js";

// Configuration setup for storefront. Note the absence of a sharedSecret.
// Your Application Key (also known as App ID) is used instead.
const configuration = new Configuration({
  tenantId: process.env.KIBO_TENANT_ID,
  siteId: process.env.KIBO_SITE_ID,
  clientId: process.env.KIBO_CLIENT_ID,
  sharedSecret: process.env.KIBO_SHARED_SECRET,
  authHost: process.env.KIBO_AUTH_HOST || "https://home.mozu.com",
});
```

**Step 2: Understanding the Data Flow**
The parameters for this request, such as `filter` and `pageSize`, are passed as arguments to the SDK method. The SDK constructs the final URL with these query parameters. The API responds with a `ProductSearchResult` object, which contains an `items` array of `Product` objects and pagination details.

**Step 3: The Core Implementation**

```ts theme={null}
// This example fetches the first 12 products from a specific category (ID: 4).
async function getCategoryProducts(categoryId: number) {
  const productSearchClient = new ProductSearchApi(configuration);

  try {
    console.log(`Fetching first 12 products for category ID: ${categoryId}...`);

    // storefrontSearch lets you query and filter product results
    const result = await productSearchClient.storefrontSearch({
      filter: `categoryId eq ${categoryId}`,
      pageSize: 12,
      startIndex: 0,
    });

    console.log(`Fetched ${result.items?.length || 0} products.`);
    console.log(`Total products available: ${result.totalCount}`);

    // Display product names
    result.items?.forEach((p, i) => {
      console.log(`${i + 1}. ${p.content?.productName}`);
    });

    return result;
  } catch (error) {
    console.error("API Error:", JSON.stringify(error, null, 2));
    throw error;
  }
}

// Step 3: Execute
getCategoryProducts(2);
```

***

### What Just Happened? (Code Explanation)

* The **setup phase** created a `Configuration` object using the public `appKey`. This is an important security distinction from the admin APIs.
* The **API call** was made using an instance of the storefront `ProductsApi`. We passed a configuration object to its `storefrontGetProducts` method containing a `filter` string. This demonstrates the Kibo pattern of using a single powerful endpoint for multiple use cases.
* The **response handling** shows how to access both the `items` array (the products themselves) and the `totalCount`, which is essential for building pagination controls in a UI.

***

### Common Beginner Mistakes

**Mistake 1:** Using admin credentials on the storefront.

```ts theme={null}
// Wrong - Never expose your clientId and sharedSecret in a front-end application.
const config = new Configuration({ clientId: '...', sharedSecret: '...' });

// Correct - Use your public appKey for all storefront API calls.
const config = new Configuration({ appKey: '...' });
```

**Mistake 2:** Not handling pagination.

```ts theme={null}
// Wrong - This only gets the first page of results (the default pageSize).
// If there are more products, the shopper will never see them.
const result = await client.storefrontGetProducts({ filter: 'categoryId eq 4' });

// Correct - Always use pageSize and startIndex to control which products you are displaying.
const result = await client.storefrontGetProducts({
    filter: 'categoryId eq 4',
    pageSize: 24, // The number of items you want per page
    startIndex: 48 // The starting index (e.g., for page 3, startIndex would be 48)
});
```

***

### How This Connects to Other Kibo Operations

* **Site Search**: The `storefrontGetProducts` endpoint is also the engine behind search. You simply change the `filter` parameter to a `query` parameter.
* **Cart**: Once a user selects a product from the list you fetched, you'll use its `productCode` to add it to the cart using the Cart API.

***

## Advanced Storefront Patterns

### Pattern 1: Implementing Faceted Search

**Business Scenario:**
A shopper searches for "hiking boots." You need to display the search results and also show a list of filters (facets) like "Brand," "Color," and "Price" so the shopper can narrow down the results. When the shopper checks the "Waterproof" box, the search results must update accordingly.

**Kibo's Architecture Consideration:**
Kibo's search is designed to be efficient and powerful. The key is that the same API call that gets the product results **also returns the available facets**. You don't need to make a separate API call to figure out what filters to show. You simply include the `facet` parameter in your request, and the response will contain a `facets` array, perfectly structured for building a filtering UI.

**API Endpoints Used:**

* `GET /api/commerce/catalog/storefront/products/`
* **Full API Reference:** [`/api-reference/storefrontproducts/get-products`](/api-reference/storefrontproducts/get-products)

**Implementation Strategy:**

1. **Initial Search**: Make a `storefrontGetProducts` call with the user's `query` and a list of fields you want to `facet` on (e.g., `brand`, `color`).
2. **Render UI**: Use the `items` from the response to display the products. Use the `facets` array from the same response to build the filtering sidebar.
3. **Refine Search**: When a user selects a facet value (e.g., clicks the "Brand: Kibo Hikers" checkbox), you modify the `filter` parameter in your next API call to include this selection (e.g., `filter=brand eq "Kibo Hikers"`) and re-run the search.

```typescript theme={null}
import { Configuration } from "@kibocommerce/rest-sdk";
import { ProductsApi, ProductSearchResult } from "@kibocommerce/rest-sdk/clients/Commerce";

// Use the same storefront configuration from the previous example
const configuration = new Configuration({ /* ... your credentials ... */ });

async function performFacetedSearch(query: string, categoryCode?: string) {
  const productSearchClient = new ProductSearchApi(configuration);

  // Define which fields to use as facets
  const facetFields = "categoryCode"; // use correct field names defined in catalog

  // Build a filter dynamically
  let facetTemplate = "";
  if (categoryCode) {
    facetTemplate = `categoryCode:"${categoryCode}"`;
  }

  try {
    console.log(`Searching for "${query}" with filter "${facetTemplate || "none"}"...`);

    // The core search call
    const result = await productSearchClient.storefrontSearch({
      query,
      facet: facetFields,
      facetTemplate,
      pageSize: 12,
      startIndex: 0,
    });

    console.log(`Found ${result.totalCount} products.`);
    console.log("Available Facets:");
    console.log(JSON.stringify(result.facets, null, 2));

    // Show a few sample product names
    result.items?.slice(0, 5).forEach((item, i) => {
      console.log(`${i + 1}. ${item.content?.productName}`);
    });

    return result;
  } catch (error) {
    console.error("Search Error:", JSON.stringify(error, null, 2));
    throw error;
  }
}

// Step 3: Execute
performFacetedSearch("", "11111");

```

***

### Multiple Real-World Examples

**Example 1: Get the Storefront Category Tree**
This is essential for building your site's main navigation menu.

```ts theme={null}
import { Configuration } from "@kibocommerce/rest-sdk";
import { CategoriesApi, CategoryCollection } from "@kibocommerce/rest-sdk/clients/CatalogAdministration";

async function getNavigationMenu() {
  const categoryClient = new CategoriesApi(configuration);
  try {
    console.log("Fetching category tree...");
    const categoryTree = await categoryClient.storefrontGetCategoryTree({
      includeAttributes: false, // optional
    });

    console.log(`Found ${categoryTree.items?.length || 0} top-level categories.`);
    console.log(JSON.stringify(categoryTree.items, null, 2));
  } catch (error) {
    console.error("Error fetching category tree:", error);
  }
}

getNavigationMenu();
```

**Example 2: Site Search with Sorting**

```ts theme={null}
import { Configuration } from "@kibocommerce/rest-sdk";
import { ProductsApi, ProductSearchResult } from "@kibocommerce/rest-sdk/clients/Commerce";

async function searchAndSort(query: string, sortBy: string = "price asc") {
  const searchClient = new ProductSearchApi(configuration);

  try {
    console.log(`Searching for "${query}" sorted by "${sortBy}"...`);

    const searchResult = await searchClient.storefrontSearch({
      query,
      sortBy,
      pageSize: 12,
    });

    console.log(`Found ${searchResult.totalCount} results.\n`);
    console.log(
      searchResult.items?.map((p) => ({
        code: p.productCode,
        name: p.content?.productName,
        price: p.price?.price,
      }))
    );

    return searchResult;
  } catch (error) {
    console.error("Search Error:", JSON.stringify(error, null, 2));
    throw error;
  }
}

searchAndSort("Apple"); // Default sort: price asc
```

**Example 3: Powering a Search Autocomplete Feature**

```ts theme={null}
import { Configuration } from "@kibocommerce/rest-sdk";
import { ProductSearchApi, SearchSuggestionResult } from "@kibocommerce/rest-sdk/clients/Commerce";

const productSearchApi = new ProductSearchApi(configuration);

export async function searchAndSort(query: string) {
  try {
    const response = await productSearchApi.storefrontSuggest({
      query, // ← dynamic input
      groups: "products,categories",
      pageSize: 10,
    });

    console.log("Search Suggestions:", response);
    return response;
  } catch (err) {
    console.error("Error fetching suggestions:", err);
  }
}

searchAndSort("Samsung");

```

***

## Integrating Storefront Catalog with Other Kibo Domains

### Storefront Catalog + Cart Integration

The entire shopping journey starts with the catalog. A shopper finds a product using the `ProductsApi`, and then you use that product's `productCode` and selected `options` to add it to their cart using the `CartApi`.

### Storefront Catalog + Customer Data Integration

When a logged-in shopper views a product, you can use their customer ID to call the Customer API to see if that product is on their wishlist, enabling you to render a "Saved to Wishlist" state on the product page.

***

## Troubleshooting Your Storefront Implementation

### Reading Kibo Error Messages

```typescript theme={null}
// Actual error structure from Kibo API
interface KiboApiError {
  message: string;         // Error description
  correlationId: string;   // For support tracking
  // ... other properties may be present
}
```

**Common Error Codes for Storefront Catalog:**

* **404 Not Found**: The most common error. This means the `productCode` or `categoryId` you requested does not exist, is not active, or is not part of the current site's catalog.
* **400 Bad Request**: Your `filter` or `sortBy` parameter has a syntax error. Check the API documentation for the correct syntax.
* **401 Unauthorized**: Your `appKey` is invalid or missing from the header.

***

### Common Development Issues

**Issue 1:** My products are showing the wrong price (or no price).

* **Why it happens:** The Storefront API respects all pricing rules. A product might not have a price if no price list is configured for the current site or if the customer doesn't belong to a group with a special price list.
* **How to fix it:** In the Kibo Admin, verify that your product has a price in a price list that is active and assigned to your storefront's customer segment.
* **API Reference:** The pricing information is returned directly on the `Product` object from the Storefront API.

**Issue 2:** My search for a specific term returns no results, but I know the product exists.

* **Why it happens:** Kibo's search indexing takes a few moments to update after a product is created or changed. Additionally, the fields you are searching against must be configured as searchable in the catalog settings.
* **How to fix it:** Wait a few minutes after creating a product. In Kibo Admin, go to **System > Settings > Search** and ensure the attributes you want to search by (e.g., product name, description) are enabled in the search tuning settings.
* **API Reference:** [`/api-reference/storefrontproducts/get-products`](/api-reference/storefrontproducts/get-products)

***

### Debugging Checklist

When your Storefront Catalog implementation isn't working:

1. Verify your `Configuration` object is using the public `appKey` and **not** your `sharedSecret`.
2. Check the browser's network tab to inspect the exact URL being called. Ensure the `filter` and `query` parameters are correctly formatted.
3. Make sure the product or category you are requesting is **Active** and assigned to the **Catalog** of the `siteId` you are using.
4. For search issues, check your site's search settings in Kibo Admin to ensure the relevant attributes are indexed.
5. Use the `correlationId` from any error message when contacting Kibo support.
