Build the Products catalog
Build the Products catalog
This is for:
DeveloperIn this article, we’ll discuss the product catalog that feeds product recommendations, how it’s built, and what you can do to get greater product coverage.
You can use the Products catalog for product recommendations in Coveo Experience Hub. See Product recommendations. |
Product coverage
In our experience, few clients have obtained complete product coverage by only collecting QProtocol events. For this reason, we recommend providing an alternative source of product data such as a Google product feed.
For an alternative source to function correctly, the product IDs used must match the IDs that we collect from the |
The product catalog from QProtocol is produced from events collected over the last 14 days (rolling window). Products that don’t appear in the last fourteen days are automatically removed. For alternative sources, products disappear from the catalog immediately after they have been removed from the source. We refresh any source every 4 hours.
Where the available products are populated by an alternative source, data from QProtocol is automatically mixed with data from the alternative source.
For example, if name
is not provided in the alternative source but is provided within QProtocol, that field will be available in the catalog.
However, it will only be available for products that appeared within the last 14 days and hence has to be treated as optional.
Note
Marking a product |
When an alternative source URL is configured, the target server has to respond within 60s (time to first byte) and complete a read within 60s (time to read after first byte). We support the following protocols: HTTP, HTTPS, SFTP, FTP, and FTPS. Simple authentication via username and password can be provided.
Locales
A product catalog can exist in multiple languages and currencies.
We build a product catalog for every combination of ecView.language
and ecProduct.product.price.currency
, sent to us via QProtocol.
Refer to the following restrictions:
-
Language must be an IETF tag, for example, en (ISO 639) or en-us (ISO 639 - ISO 3166-1)
-
Currency must be an ISO 4217 currency code (for example, GBP, USD)
-
The locale must be in the format
<language>-<currency>
(for example,en-GB-GBP
)
When QProtocol is the only source of product catalog data, we only consider additional locales that have a product catalog coverage of 25% in comparison to the largest locale on the site.
For example, if a website with a locale “en-US-USD” has 2000 products, we would need to see 500 products over the past two weeks before the additional locale is available.
Note
If a locale has not reached sufficient product coverage, it will not be available for selection when adding a new product feed. |
Note
Coverage can change over time based on your user’s behavior. We therefore recommend providing an alternative source of product information. You can provide up to 10 different sources for locales. |
Once a locale is available, it can be utilized in a call to the Recommendations API.
When using the Qubit recommendation package, this is automatically done by introspecting the last ecView
event.
https://recs.qubit.com/vc/recommend/2.1/TID?strategy=XXX&locale=en-USD
For sites without multiple languages and currencies, or where a client does not wish to show recommendations to other locales, it’s not necessary to provide a locale. The default behavior when no locale is provided is to return the most common language/currency combination.
Limitations
A product within the catalog needs to conform to certain rules:
-
A product can’t be part of more than 10 category hierarchies
-
A product can’t be part of more than 25 categories irrespective of the hierarchy (for example, [“Sale > Shoes”, “Fall Promotion”] is 3 categories)
-
A product image URL can’t exceed 4000 characters
-
A product ID can’t exceed 60 characters
-
The product data overall can’t exceed 5KB - this means you can’t embed images
QProtocol setup
In this setup, Recommendations will automatically get product information from the QProtocol events generated on your site.
Refer to the following table for details of which events and event fields are required to run recommendations in the ecommerce vertical. We also identify fields that we recommend you implement for data completeness but are optional.
ecView
Field (implementation) | Description |
---|---|
type (required) |
Reports the page type (for example, home, category, search, product, basket, checkout, confirmation, help, contact, registration, content, account, or other) |
subtypes (recommended) |
An unordered list of subtypes to describe the view |
language (recommended) |
The language used to render the page in this view, which must be an IETF language tag |
country (recommended) |
The selected country for the view, which must be an ISO 3166-1 alpha-2 code (for example, GB, FR, US) |
currency (recommended) |
The ISO 4217 currency for the user (for example, |
ecProduct
Field (implementation) | Description |
---|---|
eventType (required) |
The type of product event (for example, ‘listing’, ‘detail’, or ‘linked_product’) |
product.sku (required) |
Unique product identifier |
product.productId (required) |
A unique ID to identify a product and all of its size, color, pattern, material, age, group, gender variants |
product.name (required) |
The product’s name, which should match the name shown on the product page |
product.stock (recommended) |
The number of available units in stock |
product.color (recommended) |
The product’s color |
product.size (recommended) |
The product’s size |
product.price.value (required) |
The price of the product after discounts, promotions, etc, rounded to 2 decimal places |
product.price.currency (required) |
The ISO 4217 currency code (for example, |
product.url (required) |
The URL of the product’s page |
product.description (recommended) |
An accurate description of the product, which should match the description on the product page |
product.categories (required) |
A list of one or more product categories the product belongs to. Each category is a full category path, with each level separated by > |
product.category (required) |
An array of categories, highest level first, defining the product. Recommended to not exceed 4 items long |
product.images (required) |
An array containing the URLs of the product’s images. The main image you want to use to display the product must be the first element in the array |
product.originalPrice.value (required) |
The price the product was originally sold at before any promotions or discounts |
product.originalPrice.currency (required) |
The ISO 4217 currency code (for example, |
product.manufacturer (recommended) |
The product’s manufacturer |
ecBasketTransactionSummary
Field (implementation) | Description |
---|---|
transaction.id (required) |
A unique transaction ID |
basket.subtotalIncludingTax.value (recommended) |
The basket subtotal, including tax, but before the application of discounts, promotions, shipping costs, etc, rounded to 2 decimal places |
basket.subtotalIncludingTax.currency (recommended) |
The ISO 4217 currency code (for example, |
basket.total.value (required) |
The basket total after the application of discounts, promotions, shipping costs, etc, rounded to 2 decimal places |
basket.total.currency (required) |
The ISO 4217 currency code (for example, |
ecBasketItemTransaction
Field (implementation) | Description |
---|---|
transaction.id (required) |
A unique transaction ID |
basket.subtotalIncludingTax.value (recommended) |
The basket subtotal, including tax, but before the application of discounts, promotions, shipping costs, etc, rounded to 2 decimal places |
basket.subtotalIncludingTax.currency (recommended) |
The ISO 4217 currency code (for example, |
basket.total.value (recommended) |
The basket total after the application of discounts, promotions, shipping costs, etc, rounded to 2 decimal places |
basket.total.currency (recommended) |
The ISO 4217 currency code (for example, |
product.sku (required) |
Unique product identifier |
product.productId (required) |
A unique ID to identify a product and all of its size, color, pattern, material, age, group, gender variants |
product.name (recommended) |
The product’s name, which should match the name shown on the product page |
product.stock (recommended) |
The number of available units in stock |
product.price.value (recommended) |
The price of the product after discounts, promotions, etc, rounded to 2 decimal places |
product.price.currency (recommended) |
The ISO 4217 currency code (for example, |
product.url (recommended) |
The URL of the product’s landing page |
product.description (recommended) |
An accurate description of the product, which should match the description on the product page |
product.categories (recommended) |
A list of one or more product categories the product belongs to. Each category is a full category path, with each level separated by > |
product.category (recommended) |
An array of categories, highest level first, defining the product. Recommended to not exceed 4 items long |
product.images (recommended) |
An array containing the URLs of the product’s images |
quantity (recommended) |
The number of products described by the line item |
subtotal.value (recommended) |
The subtotal for the current items taking into account the current price and quantity, rounded to 2 decimal places |
subtotal.currency (recommended) |
The ISO 4217 currency code (for example, |
Note
For other verticals, such as eGaming, it’s necessary to emit other events. |
Google product feed setup
In this setup, Recommendations uses a server-side integration with a Google product feed to get product information. You can import a Google product feed into Qubit by following the steps outlined in importing a Google Product Feed.
The following information needs to be available in the product feed:
Attribute | Description | Example |
---|---|---|
id |
Your product’s unique identifier. Use the product’s SKU where possible |
A2B4 |
title |
Your product’s name that matches the title from your landing page |
Men Pique Polo Shirt |
description |
Your product’s description that matches the description from your landing page |
Red, 100% cotton, large men’s t-shirt |
link |
Your product’s landing page, starting with http or https |
|
image_link |
The URL of your product’s main image |
|
availability |
Your product’s availability |
in stock |
price |
Your product’s price in the format |
15.00 USD |
product_type |
The full path of the category or the numerical category ID |
Apparel & Accessories > Clothing > Outerwear > Coats & Jackets or 371 |
Refer to the Products data specification for details of optional attributes and full specifications.
Refer to the following examples:
<?xml version="1.0"?>
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
<channel>
<title>Dummy Client - Online Store</title>
<link>`+http://dummy-client.qubitproducts.com+`</link>
<description>This is a sample feed containing the required and recommended attributes for a variety of different products</description>
<item>
<g:id>UNIQUE_ID_00001</g:id>
<g:title>Two tone dress</g:title>
<g:description>Two tone dress</g:description>
<g:link>`+http://dummt-client.qubitproducts.com/dresses/two-tone-dress.html+`</g:link>
<g:image_link>`+http://dummy-client.qubitproducts.com/media/catalog/product/cache/1/image/800x800/9df78eab33525d08d6e5fb8d27136e95/d/r/dress_1.jpg+`</g:image_link>
<g:availability>in stock</g:availability>
<g:price>159.00 USD</g:price>
<g:product_type>Women's clothing > Dresses</g:product_type>
</item>
<item>
<g:id>UNIQUE_ID_00002</g:id>
<g:title>Two tone shirt</g:title>
<g:description>Two tone shirt</g:description>
<g:link>`+http://dummy-client.qubitproducts.com/shirts/two-tone-shirt.html+`</g:link>
<g:image_link>`+http://dummy-client.qubitproducts.com/media/catalog/product/cache/1/image/800x800/9df78eab33525d08d6e5fb8d27136e95/d/r/shirt.jpg+`</g:image_link>
<g:availability>in stock</g:availability>
<g:price>169.00 USD</g:price>
<g:product_type>Men's clothing > Dresses</g:product_type>
</item>
</channel>
</rss>
It’s possible to add custom values such as exclude_from_recommendations
.
It’s important to follow the guidelines in Custom attributes in XML data feeds.
An updated example is shown below:
<?xml version="1.0"?>
<rss xmlns:g="http://base.google.com/ns/1.0" xmlns:c="http://base.google.com/cns/1.0" version="2.0">
<channel>
<title>Dummy Client - Online Store</title>
<link>`+http://dummy-client.qubitproducts.com+`</link>
<description>This is a sample feed containing the required and recommended attributes for a variety of different products</description>
<item>
<g:id>UNIQUE_ID_00001</g:id>
<g:title>Two tone dress</g:title>
<g:description>Two tone dress</g:description>
<g:link>`+http://dummy-client.qubitproducts.com/dresses/two-tone-dress.html+`</g:link>
<g:image_link>`+http://dummy-client.qubitproducts.com/media/catalog/product/cache/1/image/800x800/9df78eab33525d08d6e5fb8d27136e95/d/r/dress_1.jpg+`</g:image_link>
<g:availability>in stock</g:availability>
<g:price>159.00 USD</g:price>
<g:product_type>Women's clothing > Dresses</g:product_type>
<g:sale_price>150.00 USD</g:sale_price>
<c:exclude_from_recommendations type="boolean">false</c:exclude_from_recommendations>
</item>
<item>
<g:id>UNIQUE_ID_00002</g:id>
<g:title>Two tone shirt</g:title>
<g:description>Two tone shirt</g:description>
<g:link>`+http://dummy-client.qubitproducts.com/shirts/two-tone-shirt.html+`</g:link>
<g:image_link>`+http://fashion-demo.qubitproducts.com/media/catalog/product/cache/1/image/800x800/9df78eab33525d08d6e5fb8d27136e95/d/r/shirt.jpg+`</g:image_link>
<g:availability>in stock</g:availability>
<g:price>169.00 USD</g:price>
<g:product_type>Men's clothing > Dresses</g:product_type>
<g:sale_price>160.00 USD</g:sale_price>
<c:exclude_from_recommendations type="boolean">true</c:exclude_from_recommendations>
</item>
</channel>
</rss>
Catalog field mapping
Catalog fields can be mapped from:
-
a Google feed.
Fields are mapped "as is", except for ones in the table below.
-
the
ecProduct
events.Fields are mapped as specified in the table below.
Other fields are taken from the
ecProduct.product
object with:-
underscores instead of dots
-
the
product_
prefix dropped.Exampleproduct.manufacturer
becomesmanufacturer
.
-
-
both sources. In that case, the Google feed is prioritized.
Catalog field | Merged from QP events | Renamed during catalog creation | Derived during catalog creation | Notes |
---|---|---|---|---|
|
Renamed from |
|||
|
Categories are extracted from |
|||
|
The first value from the |
|||
|
Derived from the locale chosen when uploading this feed into Coveo Experimentation Hub. |
|||
|
Checks which of the following fields from the Google feed has the best match rate with
Once the best match is found, it’s mapped to |
|||
|
Renamed from |
|||
|
Derived by creating an array where first value is |
|||
|
Derived from the locale chosen when uploading this feed into Coveo Experimentation Hub. |
|||
|
Derived from the locale chosen when uploading this feed into Coveo Experimentation Hub. |
|||
|
Renamed from |
|||
|
Populated using the value of the |
|||
|
Checks which of the following fields exist in the Google feed, in that order:
The first found field is mapped to |
|||
|
If Otherwise, the stock integer value is retrieved from the following fallback logic:
|
|||
|
Mapped from |
|||
|
Mapped from |
|||
|
Mapped from |
|||
|
Mapped from |
|||
|
Renamed from |
|||
|
Count of the |
Next steps
Once your data layer or product feed has been verified, you can add the Recommendations programmatic experience. You can do this in 2 different ways.
You can either add it as an experience in the Qubit platform or call the Recommendations API.