Use the Commerce API directly

This is for:

Developer

The Coveo Commerce API is a powerful choice for interacting with the Coveo Platform that offers more flexibility than building your Coveo for Commerce implementation using the Coveo Headless library. However, this flexibility brings complexity, and there are trades-offs when using the Commerce API to build your implementation.

Important

We recommend using the Headless library to implement your custom Coveo for Commerce solution. If you can’t use the Headless library, your implementation must use the Commerce API and Event API correctly (that is, in a similar fashion to what the Headless library does).

When interacting directly with the Commerce API, you must send requests to the following APIs and handle the responses yourself:

  • Commerce API:

    Provides endpoints to query the Coveo Platform for products to display on search result pages, product listing pages (PLPs), and recommendation slots. It also provides endpoints to manage product inventories and product discovery. See the Commerce API reference for the complete list of endpoints.

  • Event API:

    When implementing a solution using the Commerce API, you must follow the Event Protocol to ensure proper tracking of user interactions and commerce events.

    Note

    In the case of mobile or non-web implementations, you must leverage Event Protocol through the Event API directly.

    For web implementations, use the Event Protocol with Relay to send events. Using Coveo Relay library for sending events is highly recommended over direct interactions with the Event API, as the library handles many of the complexities that come with event transmission. Relay allows you to focus on core implementation aspects, ensuring events are triggered by the right user interactions and carry the correct payload.

You can use the Headless library as a reference implementation for how to use the Commerce and Event APIs. See commerce.index.ts.

Sample request for searching products:

Basic search query for kayak | Coveo for Commerce

During this end-user interaction, the commerce interface sends the following request to the Commerce API, retrieving products linked to the query "kayak."

Executing the query:

POST https://platform.cloud.coveo.com/rest/organizations/barcagroupproductionkwvdy6lp/commerce/v2/search HTTP/1.1 1

Content-Type: application/json
Authorization: Bearer **********-****-****-****-************ 2
1 The URL is the endpoint for the Commerce API, where barcagroupproductionkwvdy6lp is your organization ID.
2 For more information on how to authenticate requests, see authenticate commerce requests.

Payload:

{
  "trackingId": "sports",
  "clientId": "e73da3f1-5225-4528-85b4-60ba5b63f4aa",
  "context": {
    "user": {
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36"
    },
    "view": {
      "url": "https://sports.barca.group/search"
    },
    "capture": true,
    "cart": [],
    "source": [
      "@coveo/headless@3.12.0"
    ],
  },
  "language": "en",
  "country": "US",
  "currency": "USD",
  "page": 0,
  "perPage": 20,
  "facets": [],
  "sort": {
    "sortCriteria": "relevance"
  },
  "query": "kayak"
}

Make requests to the Commerce API

Important

Unlike Headless, the Commerce API direct implementation approach doesn’t do any of the heavy lifting. You need to handle everything yourself, including authentication, state management, context management, and client ID management.

This section provides an overview of how to make requests with the Commerce API. Samples are provided for the initial call of retrieving products from a query, products linked to a listing page, recommendations from a slot id, and query suggestions. You should also familiarize yourself with the interactions users can take on your Coveo for Commerce pages. For more information, see the Coveo Commerce API reference.

Authentication

The Coveo Commerce API requires authentication to access its endpoints, the most common approach of which is to use a private API key in your backend to generate search tokens. When beginning to explore authentication for your Coveo for Commerce implementation, you should first understand how to authenticate commerce requests.

State management

State management is crucial when building a Coveo for Commerce implementation. This is normally handled for you by the Headless library, but when using the Commerce API directly, you must manage state yourself. Commerce state management involves handling the user session and cart state effectively. Here are some key aspects to consider:

  • Context management

    The session state for a user includes details such as the current URL, selected currency, language, and country code. The context is initialized during engine startup and updated as users interact with the storefront, being passed as part of the request payload to the Commerce API.

    Warning

    It’s crucial to update the context to reflect the current URL when navigation occurs between pages to ensure accurate session management and user experience.

  • Cart state management

    The Commerce API does not manage cart state, so you must implement cart management. Include the cart as an array of product IDs and quantities in each request payload.

Client ID management

Effective client ID management is essential for tracking user interactions and maintaining a consistent user experience across sessions.

There are two main scenarios for client ID management:

  1. New visitors

    • A unique client ID is generated for each new visitor.

    • This ID is sent to Coveo as part of the request payload, allowing Coveo to personalize responses and is stored in the browser as a cookie for future requests.

  2. Returning visitors

    • The server retrieves the an existing client ID from the cookies in the browser.

    • This ID is sent to Coveo as part of the request payload, facilitating continuity in user experience and personalization.

Generate the client ID using a UUID library, as shown in the following example, which uses the route-handler mechanism from Next.js to access cookies:

import { cookies } from 'next/headers';

const getOrCreateClientId = () => {
  const cookieStore = cookies();
  const existingClientId = cookieStore.get(COOKIE_NAME);
  return existingClientId ? existingClientId.value : crypto.randomUUID();
};

Interactions

Sorting, faceting and pagination are common interactive elements in a Coveo for Commerce implementation. They allow users to refine their search results, navigate through product listings, and explore product categories. These interactions are typically handled by the Headless library, but when using the Commerce API directly, you must embed them within the request payload.

Sorting

Sorting lets users order results based on specific criteria like relevance, popularity, or price.

Apply sorting to your search queries and product listings by including a sort object in the request payload as follows.

{
  //...
  "sort": { 1
    "sortCriteria": "fields",
    "fields": [
        {
            "field": "ec_promo_price",
            "direction": "desc",
            "displayName": "Price (High to Low)",
        }
    ]
  },
  //...
}
1 Requirements for the sort object depend on the type of sort you want to apply. See the Search API reference for more details.

Faceting

Facets let users refine their search results by selecting specific attributes or categories, making it easier to find relevant items.

There are four types of facets available in the Coveo for Commerce API:

  • Regular

    {
      //...
      "facets": [
        {
          "facetId": "ec_brand",
          "displayName": "Brand",
          "field": "ec_brand",
          "type": "regular",
          "values": [
            { "value": "Aqua Sports", "state": "selected" },
            { "value": "Air Head", "state": "idle" },
            { "value": "Barca Sports", "state": "idle" },
            { "value": "HO Sports", "state": "idle" }
          ],
        },
      ],
      //...
    }
  • Numerical range

    • Discrete

{
  //...
  "facets": [
    {
      "facetId": "ec_rating",
      "displayName": "Customer Rating",
      "numberOfValues": 5,
      "field": "ec_rating",
      "type": "numericalRange",
      "values": [
        {
          "state": "idle",
          "start": 1,
          "end": 5,
          "endInclusive": true
        },
        {
          "state": "idle",
          "start": 3,
          "end": 5,
          "endInclusive": true
        },
        {
          "state": "idle",
          "start": 4,
          "end": 5,
          "endInclusive": true
        },
        {
          "state": "idle",
          "start": 5,
          "end": 5,
          "endInclusive": true
        }
      ],
      "freezeCurrentValues": false,
      "preventAutoSelect": false,
      "interval": "discrete",
      "domain": {
        "min": 1,
        "max": 5,
        "increment": 0
      }
    }
  ],
  //...
}
  • Continuous

{
  //...
  "facets": [
    {
      "facetId": "custom_prd_width",
      "displayName": "Width",
      "numberOfValues": 50,
      "field": "custom_prd_width",
      "type": "numericalRange",
      "values": [
        {
          "state": "idle",
          "start": 1,
          "end": 931,
          "endInclusive": true
        }
      ],
      "freezeCurrentValues": false,
      "preventAutoSelect": false,
      "interval": "continuous",
      "domain": {
        "min": 1,
        "max": 931,
        "increment": 0
      }
    }
  ],
  //...
}
  • Hierarchical

{
  //...
  {
    "type": "hierarchical",
    "facetId": "ec_category",
    "field": "ec_category",
    "displayName": "Category",
    "values": [
      {
        "state": "idle",
        "value": "Sandals & Shoes",
        "children": []
      },
      {
        "state": "idle",
        "value": "Accessories",
        "children": []
      },
      {
        "state": "idle",
        "value": "Clothing",
        "children": []
      }
    ],
    "delimitingCharacter": "|",
    "isFieldExpanded": false
  }
  //...
}
  • Date range

Each facet type offers specific configurations and use cases, so you can tailor the user experience based on your products and the attributes you want to expose. Include the facets array in the request payload to apply facets, as shown in the following example. Refer to the Commerce API reference under the facets section of the request type you are using for more details on how to configure facets.

Pagination

Pagination breaks large sets of results into smaller, manageable pages, making it easier to navigate. Include the page and perPage parameters in the request payload to implement pagination, as shown below.

{
  // ...
  "page": 0, 1
  "perPage": 20, 2
  // ...
}
1 The page number to retrieve.
2 The perPage parameter is optional, and overrides the default number of products returned per page.

Sample requests

Retrieve products from search query

Use the search endpoint to get products for an end-user query.

Execute the query
POST https://platform.cloud.coveo.com/rest/organizations/barcagroupproductionkwvdy6lp/commerce/v2/search HTTP/1.1

Content-Type: application/json
Authorization: Bearer **********-****-****-****-************
Payload
{
  "trackingId": "sports",
  "clientId": "e73da3f1-5225-4528-85b4-60ba5b63f4aa",
  "context": {
    "view": {
      "url": "https://sports.barca.group/search"
    },
    "capture": true,
    "cart": [],
  },
  "language": "en",
  "country": "US",
  "currency": "USD",
  "query": "kayak"
}
200 OK response (excerpt)
{
  "responseId": "fbe0876f-3d35-4d17-9f0a-958de0dbe334",
  "products": [
    {
      "ec_name": "Kevlar Blue Kayak",
      "ec_description": "The Blue sport kayak is made of carbon-kevlar and is perfect for those who want a sturdy and durable kayak. It is also perfect for fishing, touring, or just cruising around.",
      "ec_brand": "Aqua Sports",
      "ec_category": [
        "Canoes & Kayaks",
        "Canoes & Kayaks|Kayaks",
        "Canoes & Kayaks|Kayaks|Sports Kayaks"
      ],
      "ec_thumbnails": [
        "https://images.barca.group/Sports/mj/Canoes%20and%20Kayaks/Kayaks/Sports%20Kayaks/38_Blue_Carbon-Kevlar/ed4707cdcd5c_top_left.webp"
      ],
      "ec_price": 3500.0,
      "ec_in_stock": true,
      "clickUri": "https://sports.barca.group/pdp/SP00940_00003"
    },
    {
      "ec_name": "Kevlar Sporty Kayak",
      "ec_description": "This kayak is made of tough Kevlar fabric and has a comfortable, padded cockpit. It is perfect for fishing or recreational paddling.",
      "ec_brand": "Aqua Sports",
      "ec_category": [
        "Canoes & Kayaks",
        "Canoes & Kayaks|Kayaks",
        "Canoes & Kayaks|Kayaks|Sports Kayaks"
      ],
      "ec_thumbnails": [
        "https://images.barca.group/Sports/mj/Canoes%20and%20Kayaks/Kayaks/Sports%20Kayaks/38_Blue_Kevlar/a6ec8798f47b_bottom_right.webp"
      ],
      "ec_price": 3850.0,
      "ec_in_stock": true,
      "clickUri": "https://sports.barca.group/pdp/SP00947_00003"
    }
    //...
  ],
  "facets": [
    {
      "type": "regular",
      "facetId": "ec_brand",
      "field": "ec_brand",
      "displayName": "Brand",
      "values": [
        {
          "state": "idle",
          "numberOfResults": 22,
          "value": "Aqua Sports"
        },
        //...
      ],
      "numberOfValues": 5,
      "moreValuesAvailable": true,
      "fromAutoSelect": false,
      "isFieldExpanded": false
    }
    //...
  ],
  "pagination": {
    "page": 0,
    "perPage": 20,
    "totalEntries": 22,
    "totalPages": 2
  },
  "sort": {
    "appliedSort": {},
    "availableSorts": [
      {
        "sortCriteria": "relevance"
      },
      {
        "sortCriteria": "fields",
        "fields": [
          {
            "field": "ec_promo_price",
            "direction": "desc",
            "displayName": "Price (High to Low)"
          }
        ]
      },
      {
        "sortCriteria": "fields",
        "fields": [
          {
            "field": "ec_promo_price",
            "direction": "asc",
            "displayName": "Price (Low to High)"
          }
        ]
      }
    ]
  },
  "triggers": [],
}

Retrieve products for a listing page

Use the listing endpoint to get products for a particular product listing page (PLP). All listing configurations are linked to a specific URL, passed as content.view.url in the request body.

Execute the query
POST https://platform.cloud.coveo.com/rest/organizations/barcagroupproductionkwvdy6lp/commerce/v2/listing HTTP/1.1

Content-Type: application/json
Authorization: Bearer **********-****-****-****-************
Payload
{
  "trackingId": "sports",
  "clientId": "e73da3f1-5225-4528-85b4-60ba5b63f4aa",
  "context": {
    "capture": true,
    "view": {
      "url": "https://sports.barca.group/plp/canoes-kayaks/kayaks/folding-kayaks"
    },
    "cart": [],
  },
  "language": "en",
  "country": "US",
  "currency": "USD",
}
200 OK response (excerpt)
{
  "responseId": "cc5be4bf-4a56-488f-8260-45904eb5a6ae",
  "products": [
    {
      "ec_name": "Ripkin Kayak",
      "ec_description": "This is a foldable kayak made from durable red plastic that is perfect for commuting, recreational use or fishing. It has a comfortable and sturdy design that is perfect for taking on your next adventure.",
      "ec_brand": "HO Sports",
      "ec_price": 1500.0,
      "ec_in_stock": true,
      "ec_category": [
        "Canoes & Kayaks",
        "Canoes & Kayaks|Kayaks",
        "Canoes & Kayaks|Kayaks|Folding Kayaks"
      ],
      "ec_thumbnails": [
        "https://images.barca.group/Sports/mj/Canoes%20and%20Kayaks/Kayaks/Folding%20Kayaks/39_Red/b4778cffbce7_top_left.jpg"
      ],
      "clickUri": "https://sports.barca.group/pdp/SP00952_00002"
    }
  ],
  "facets": [
    {
      "type": "regular",
      "facetId": "ec_brand",
      "field": "ec_brand",
      "displayName": "Brand",
      "values": [
        {
          "state": "idle",
          "numberOfResults": 22,
          "value": "Aqua Sports"
        },
        //...
      ],
      "numberOfValues": 5,
      "moreValuesAvailable": true,
      "fromAutoSelect": false,
      "isFieldExpanded": false
    }
    //...
  ],
  "pagination": {
    "page": 0,
    "perPage": 20,
    "totalEntries": 22,
    "totalPages": 2
  },
  "sort": {
    "appliedSort": {},
    "availableSorts": [
      {
        "sortCriteria": "relevance"
      },
      {
        "sortCriteria": "fields",
        "fields": [
          {
            "field": "ec_promo_price",
            "direction": "desc",
            "displayName": "Price (High to Low)"
          }
        ]
      },
      {
        "sortCriteria": "fields",
        "fields": [
          {
            "field": "ec_promo_price",
            "direction": "asc",
            "displayName": "Price (Low to High)"
          }
        ]
      }
    ]
  },
  "triggers": [],
}

Retrieve product recommendations

Returns products linked to a given recommendations slot.

Execute the query
POST https://platform.cloud.coveo.com/rest/organizations/barcagroupproductionkwvdy6lp/commerce/v2/search/recommendations HTTP/1.1

Content-Type: application/json
Authorization: Bearer **********-****-****-****-************
Payload
{
  "slotId": "7b506e3f-c0c3-411d-b771-161ee3305798",
  "trackingId": "sports",
  "clientId": "e73da3f1-5225-4528-85b4-60ba5b63f4aa",
  "context": {
    "user": {
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36"
    },
    "view": {
      "url": "https://sports.barca.group/search"
    },
    "capture": true,
    "cart": [],
    "source": [
      "@coveo/headless@3.12.0"
    ],
    "product": {
      "productId": "SP01007_00003"
    },
    "purchased": [],
  },
  "language": "en",
  "country": "US",
  "currency": "USD"
}
200 OK response (excerpt)
{
  "responseId": "b4c095d6-97d5-4b5d-b3b9-be7b8fdeeae8",
  "headline": "You may also like",
  "products": [
    {
      "additionalFields": {
        "ec_colors": ["Black"]
      },
      "ec_name": "Kyanite Kayak",
      "ec_description": "The Black tandem kayak is perfect for those who want to enjoy the outdoors in a comfortable and safe manner. This kayak is made from durable materials and features a stylish design that will make you look great while you're out on the water.",
      "ec_shortdesc": "The Black tandem kayak is perfect for those who want to enjoy the outdoors in a comfortable and safe manner. This kayak is made from durable materials and features a stylish design that will make you look great while you're out on the water.",
      "ec_brand": "Aqua Sports",
      "ec_category": [
        "Canoes & Kayaks",
        "Canoes & Kayaks|Kayaks",
        "Canoes & Kayaks|Kayaks|Tandem Kayaks"
      ],
      "ec_thumbnails": [
        "https://images.barca.group/Sports/mj/Canoes%20and%20Kayaks/Kayaks/Tandem%20Kayaks/40_Black/39c192024ef7_bottom_right.webp"
      ],
      "ec_images": [
        "https://images.barca.group/Sports/mj/Canoes%20and%20Kayaks/Kayaks/Tandem%20Kayaks/40_Black/39c192024ef7_bottom_right.webp"
      ],
      "ec_price": 2000.0,
      "ec_promo_price": 1800.0,
      "ec_in_stock": true,
      "ec_item_group_id": "SP01007",
      "ec_rating": 3.0,
      "ec_product_id": "SP01007_00001",
      "ec_gender": null,
      "ec_color": null,
      "ec_listing": "/Canoes_Kayaks/Kayaks/Tandem_Kayaks",
      "clickUri": "https://sports.barca.group/pdp/SP01007_00001",
      "permanentid": "SP01007_00001",
      "children": [],
      "totalNumberOfChildren": 0
    },
    {
      "additionalFields": {
        "ec_colors": ["Yellow"]
      },
      "ec_name": "Gulp! Kayak",
      "ec_description": "This kayak is perfect for beginner kayakers and is a great choice for fishing. The tandem kayak is easy to paddle and has a carrying capacity of 220lbs.",
      "ec_shortdesc": "This kayak is perfect for beginner kayakers and is a great choice for fishing. The tandem kayak is easy to paddle and has a carrying capacity of 220lbs.",
      "ec_brand": "Aqua Sports",
      "ec_category": [
        "Canoes & Kayaks",
        "Canoes & Kayaks|Kayaks",
        "Canoes & Kayaks|Kayaks|Tandem Kayaks"
      ],
      "ec_thumbnails": [
        "https://images.barca.group/Sports/mj/Canoes%20and%20Kayaks/Kayaks/Tandem%20Kayaks/40_Yellow/c49f4f4f9346_top_left.webp"
      ],
      "ec_images": [
        "https://images.barca.group/Sports/mj/Canoes%20and%20Kayaks/Kayaks/Tandem%20Kayaks/40_Yellow/c49f4f4f9346_top_left.webp"
      ],
      "ec_price": 2400.0,
      "ec_promo_price": 2400.0,
      "ec_in_stock": true,
      "ec_item_group_id": "SP01008",
      "ec_rating": 3.0,
      "ec_product_id": "SP01008_00004",
      "ec_gender": null,
      "ec_color": null,
      "ec_listing": "/Canoes_Kayaks/Kayaks/Tandem_Kayaks",
      "clickUri": "https://sports.barca.group/pdp/SP01008_00004",
      "permanentid": "SP01008_00004",
      "children": [],
      "totalNumberOfChildren": 0
    }
    //...
  ],
  "triggers": [],
}

Retrieve query suggestions

Returns a list of query suggestions based on user input. Coveo Machine Learning (Coveo ML) QS models recommend relevant queries to users as they type in the search box.

Executing the query
POST https://platform.cloud.coveo.com/rest/organizations/barcagroupproductionkwvdy6lp/commerce/v2/search/querySuggest HTTP/1.1

Content-Type: application/json
Authorization: Bearer **********-****-****-****-************
Payload
{
  "trackingId": "sports",
  "query": "wa",
  "clientId": "e73da3f1-5225-4528-85b4-60ba5b63f4aa",
  "context": {
    "user": {
      //...
    },
    "view": {
      "url": "https://sports.barca.group/search"
    },
    "capture": true,
    "cart": [],
    "source": [
      "@coveo/headless@3.12.0"
    ],
  },
  "language": "en",
  "country": "US",
  "currency": "USD"
}
200 OK response (excerpt)
{
  "responseId": "fbe0876f-3d35-4d17-9f0a-958de0dbe334",
  "completions": [
    {
      "expression": "wakeboard",
      "highlighted": "{wa}[keboard]"
    },
    {
      "expression": "surf wax",
      "highlighted": "[surf] {wa}[x]"
    },
    {
      "expression": "water bottle",
      "highlighted": "{wa}[ter] [bottle]"
    },
    //...
  ],
  "fieldSuggestionsFacets": []
}

Make requests to the Event API

When working with a Commerce implementation using the Commerce API, you must use the Event Protocol to track user interactions with your product discovery solution. If you can’t use the Event Protocol directly, you can leverage it through the Coveo Event API. A typical Event API implementation uses Relay to send events to Coveo Usage Analytics (Coveo UA).

Important

If you can’t use Relay, you can use the Event API directly to log the events yourself.

Event type How-to link

Click event

Capture click events

Product view event

Capture product view events

Cart event

Capture cart events

Purchase event

Capture purchase events

Client-side vs server-side initial calls

NOTE

Server-to-server implementations can obscure query visibility and traceability for support teams. The best practice is to embed the responseId within the page source or in an API gateway response.

When building a product discovery solution using the Coveo Commerce API, you can choose to make initial calls from either the client-side or server-side. Much like the choice of the implementation approach, the choice of where to make the initial calls also has trade-offs to consider:

Category Client-side Server-side

SEO


Content loaded via JavaScript may not be indexed by search engines.

⭐⭐⭐⭐⭐
Content is pre-rendered and can be indexed by search engines.

Initial content display

⭐⭐
May see a loading spinner or empty state while waiting for API responses.

⭐⭐⭐⭐⭐
See content immediately, as it’s pre-rendered on the server.

Interactivity

⭐⭐⭐⭐
The browser can start rendering the page while waiting for API responses.

⭐⭐⭐
May require additional client-side logic for dynamic updates.

Server load

⭐⭐⭐⭐⭐
Browser handles API requests, reducing load on your server.

⭐⭐
Server must handle all API requests and render content for users.

Security

⭐⭐
Authentication tokens or sensitive information in client-side requests are visible to users and can be misused if not secured.

⭐⭐⭐⭐⭐
API keys and sensitive information are kept on the server and not exposed to users.

Implementation complexity

⭐⭐⭐⭐⭐
Easier to implement and iterate on UI changes.

⭐⭐
Requires backend development and infrastructure.

Warning

You must know how to find your organization ID and authenticate commerce requests. Never expose sensitive information, such as API keys or secrets, in client-side code. The initial call to generate a token using your API key should always be performed on the server side.