7 min read

Product Catalogue Feed Integration

To keep your app's catalogue up-to-date with your latest product information, you need to provide a single CSV file which Poq uses to populate your catalogue. This file is called the Product feed file.

Your product feed file contains all the information required to display your products to your customers.

How Product Storage Works

  1. When Product Feed processing commences, products are constructed from the data provided in the feed.
  2. The latest products are distributed throughout the Poq Platform.
  3. Catalogue, Content, and Search services ingest this data in an appropriate format.
  4. The Poq platform serves product data to the app when it is requested.

Importing your Product Catalogue

Your app's product catalogue can be imported & distributed throughout the Product Platform via the product feed processor. Product Feed files should be separate from your category feed file. Feed files must be a valid RFC4180 CSV file.

Feed Comparison

Poq's product feed processor can be configured to run comparatively. When enabled, the latest feed file will be compared to the file that was used previously. This allows us to find which products have been added, updated, and deleted. Your app's catalogue is then updated accordingly.

Product deletion is not supported when feed comparison is disabled.

Keeping your Catalogue Up-To-Date

To ensure that your app's product catalogue is kept up-to-date, product feed processing can be configured to run on a schedule. This can be a recurring interval, such as every 15 minutes. Or at a specific time during the day, such as at midnight.

When feed comparison is disabled, it cannot be executed more frequently than once per hour.

Hosting your Product Feed File

Your product feed file must be publicly available over HTTP. It is highly recommended to use a static location, as we will check it regularly for updates.

Creating your Product Feed

Product Level and Product Variant Level Data

Each line of your feed file corresponds to a single Product Variant, as such, a whole Product can be comprised across multiple lines. This is particularly pertinent to data that is considered "Product level". Generally, Product level data does not differ between each variant, for example, the Product's brand and description.

Product level data must be supplied in the first variant in the feed. It does not need to be repeated for subsequent variants (lines) in the feed, if it is supplied, it will be ignored. The following property sections are considered Product level data, and only need to appear once per product:

  • Product Meta
  • Product Details
  • Product Review
  • Product Promotions
  • Product Categories
  • Custom Data

The remaining property sections must appear for each variant.

  • Product (Product ID is considered product level data, however it must appear for each variant.)
  • Product Variant
  • Product Forms
  • Product Variant Meta
  • Product Variant Forms
  • Product Variant Stock
  • Product Variant Filters
  • Product Variant Images
  • Custom Data

Note: Custom Data appears in both lists, see Custom Data for more information.

Product Feed Specification

PropertyField NameDescriptionRequiredExampleRemarks
Productproduct-idUnique identifier for a single product.Required001Must appear for each Product Variant. It must only appear in the feed consecutively.
Product Metadefault-variant-idThe default variant that represents the product.Optionalsku_001Must match a variant ID provided in the feed. Defaults to the first Product Variant present.
Product Metalink-title_[index]Title of a linked content page.Optional"Size Guide"Index is zero-based. See Links
Product Metalink-url_[index]Absolute URL of a content page.Optionalhttps://cdn.shop.com/sizeguide.htmlIndex is zero-based. See Links
Product Metalink-content_[index]Static content as HTML or plain text.Optional<p>Size Guide content</p>Index is zero-based. See Links
Product Metaweb-urlAbsolute website URL of the product.Optionalhttps://shop.com/products/001
Product DetailsbrandThe brand of the product.Optional"Ordinary Shirts"
Product DetailsdescriptionLong description of the product in plain text.Required"This is an ordinary T-shirt to wear on an ordinary day."
Product Detailsdescription-rawLong description of the product in raw format.Optional"<p>This is an ordinary T-shirt to wear on an ordinary day.<p>"Supports HTML formatting, the value of description will be displayed if not present.
Product Detailsshort-descriptionShort description of the product in plain text.Optional"This is an ordinary T-shirt to wear on an ordinary day."
Product Detailsshort-description-rawShort description of the product in raw format.Optional"<p>This is an ordinary T-shirt to wear on an ordinary day.<p>"Supports HTML formatting, the value of short-description will be displayed if not present.
Product Promotionpromotion-badge_[index]Text badge to display against the Product.Optional"Sale"Index is zero-based. See Promotion Badges
Product Promotionpromotion-message_[index]Promotional message to display against the Product.Optional"Buy 1 Get 1 Free"Index is zero-based. See Promotion Messages
Product Categoriescategory-id_[index]ID of the Category that the product belongs to.Optional"clothing"Index is zero-based. See Categories
Product Reviewreview-countThe number of reviews for the Product.Optional20Must be a positive, whole number.
Product Reviewreview-ratingThe average rating for the Product.Optional4.5Must be a decimal.
Product FormsformsThe variable forms of the product.Optional"colour,size"Comma-separated values. See Forms
Product Variantvariant-idUnique identifier for a single product variant.Requiredsku_001Must be unique among the feed. This is usually the variant SKU.
Product Variantlisting-idAn identifier that can be used to group variants together into a single product listing.Optionalproduct_001-blueDuplicate listing IDs must only exist within a single product. See Product Listings
Product VariantnameThe display name of the Product Variant.RequiredT-Shirt
Product Variant MetabarcodeBarcode number of the Product VariantOptionalT-Shirt
Product Variant Metarelease-dateDate that the Product Variant went on sale.Optional2020-09-11Value should be in ISO 8601 format. See Release Date
Product Variant Metasort-indexSort Index of the Product.Optional1001Value should be an integer. See Sort Index
Product Variant Metavideo-urlAbsolute video URL showcasing the Product Variant.Optionalhttps://cdn.shop.com/sku_001.mp4See Videos
Product Variant Priceprice-now_[Poq-Currency-Identifier]The current price of a Product Variant.Required10.99A Product Variant must have at least one "Now Price". See Prices
Product Variant Priceprice-was_[Poq-Currency-Identifier]The price of a Product Variant prior to reduction.Optional12.99A Product Variant must have at least one "Now Price". See Prices
Product Variant Formform-id_[Form Name]Unique ID of the Form Variation.Optionalcolour_red, size_smallEach comma-separated value in the forms field must have a matching form-id_[Form Name] field. See Forms
Product Variant Formform-value_[Form Name]Text value of the Form Variation.OptionalRed, SmallEach comma-separated value in the forms field must have a matching form-value_[Form Name] field. See Forms
Product Variant Formform-swatch_[Form Name]Swatch Image of the Form Variation.Optionalhttps://cdn.shop.com/swatch/red.pngEach comma-separated value in the forms field may have a matching form-swatch_[Form Name] field. See Forms
Product Variant StockavailableIndicates if the Product Variant is available.Optionaltrue, falseDefaults to true if not present. See Availability
Product Variant Stocklow-on-stockIndicates if the Product Variant is low on stock.Optionaltrue, falseDefaults to false if not present. See Low on Stock
Product Variant Stocklead-timeEstimated period of time between order placement and completion.Optional2 weeks
Product Variant Stockmax-orderable-quantityIndicates how many of a given Product Variant can be ordered at once.Optional5Must be a positive whole number. Defaults to the value of quantity
Product Variant StockquantityIndicates how many of a given Product Variant can be ordered is in stock.Optional5Assumed to be infinite when not provided.
Product Variant Imagesimage_[Index]Images of the Product Variant.Requiredhttps://cdn.shop.com/sku_011_0.pngIndex is zero-based. At least one image is required. See Images
Product Variant Dynamic Filtersfilter-attr-name_[Index]Name of a filter attribute.OptionalStyle, MaterialIndex is zero-based. See Filters
Product Variant Dynamic Filtersfilter-attr-value_[Index]Value of a filter attribute.OptionalFormal, CottonIndex is zero-based. See Filters
Custom Data[Custom Field Name]Any custom data to be attached to the Variant.OptionalCustom ValueAny field name not in the specification is supported. See Custom Data

Product Feed Example

Below is an example CSV that will create a single Product, T-Shirt. The Product has two forms: colour and size. The Product has three Product Variants: White Small, White Medium, and White Large. The feed file example can be downloaded here.

product-id,variant-id,listing-id,name,forms,form-id_colour,form-value_colour,form-swatch_colour,form-id_size,form-value_size,price-now_GBP_GB,price-was_GBP_GB,price-now_EUR_FR,available,low-on-stock,max-orderable-quantity,quantity,barcode,video-url,image_0,image_1,default-variant-id,brand,description,description-raw,web-url,link-title_0,link-url_0,link-title_1,link-url_1,promotion-badge_0,promotion-message_0,category-id_0,category-id_1,review-rating,review-count,filter-attr-name_0,filter-attr-value_0,Gifting-Available,Gift-Id
1,001-001,1,T-Shirt,"colour,size",colour_White,White,https://cdn.shop.com/colorimages/White.png,size_Small,Small,55.95,85.95,65.95,TRUE,FALSE,5,20,001-001,https://cdn.shop.com/001-001.mp4,https://cdn.shop.com/images/001_001a.png,https://cdn.shop.com/images/001_001b.png,001-001,Cool Shirts,This is a cool shirt.,<p>This is a cool shirt.<p>,https://www.shop.com/products/001,Size Guide,https://cdn.shop.com/sizeguide.html,Delivery Information,https://cdn.shop.com/delivery.html,Sale,Buy One Get One Free,clothing,cool,5,100,Style,Cool,TRUE,001-001
1,001-002,1,T-Shirt,,colour_White,White,https://cdn.shop.com/colorimages/White.png,size_Medium,Medium,55.95,85.95,65.95,FALSE,TRUE,5,0,001-002,https://cdn.shop.com/001-002.mp4,https://cdn.shop.com/images/001_002a.png,https://cdn.shop.com/images/001_002b.png,,,,,,,,,,,,,,,,,,TRUE,001-002
1,001-003,1,T-Shirt,,colour_White,White,https://cdn.shop.com/colorimages/White.png,size_Large,Large,55.95,85.95,65.95,TRUE,FALSE,5,20,001-003,https://cdn.shop.com/001-003.mp4,https://cdn.shop.com/images/001_003a.png,https://cdn.shop.com/images/001_003b.png,,,,,,,,,,,,,,,,,,TRUE,001-003

The above feed file will produce a Product with the following JSON Structure. The JSON file output can be downloaded here.

{
"CategoryIds": [
"clothing",
"cool"
],
"Details": {
"Name": "T-Shirt",
"Brand": "Cool Shirts",
"Description": "This is a cool shirt.",
"DescriptionRaw": "<p>This is a cool shirt.</p>"
},
"Forms": [
{
"Name": "colour",
"Preselected": true,
"Variations": [
{
"Id": "colour_White",
"Value": "White",
"Swatch": "https://cdn.shop.com/colorimages/White.png"
}
]
},
{
"Name": "size",
"Preselected": false,
"Variations": [
{
"Id": "size_Small",
"Value": "Small"
},
{
"Id": "size_Medium",
"Value": "Medium"
},
{
"Id": "size_Large",
"Value": "Large"
}
]
}
],
"id": "001",
"Meta": {
"DefaultVariantId": "001-001",
"Links": [
{
"Title": "Size Guide",
"Url": "http://cdn.shop.com/sizeguide.html"
},
{
"Title": "Delivery Information",
"Url": "http://cdn.shop.com/delivery.html"
}
],
"WebUrl": "https://www.shop.com/products/001"
},
"Promotion": {
"Badges": [
"Sale"
],
"Messages": [
"Buy One Get One Free"
]
},
"Review": {
"Rating": 5.0,
"Count": 100
},
"Variants": {
"001-001": {
"Id": "001-001",
"Forms": {
"colour": {
"Id": "colour_White",
"Value": "White",
"Swatch": "https://cdn.shop.com/colorimages/White.png"
},
"size": {
"Id": "size_Small",
"Value": "Small"
}
},
"Images": {
"Default": [
"https://cdn.shop.com/images/001_001a.png",
"https://cdn.shop.com/images/001_001b.png"
]
},
"ListingId": "001",
"Meta": {
"Barcode": "001-001",
"videoURL": "https://cdn.shop.com/001-001.mp4",
"DefaultCurrency": "GBP_EN"
},
"Name": "T-Shirt",
"Prices": {
"GBP_EN": {
"Now": 55.95,
"NowFormatted": "£55.95",
"Was": 85.95,
"WasFormatted": "£85.95",
"CurrencySymbol": "£"
},
"EUR_FR": {
"Now": 65.95,
"NowFormatted": "€65.95",
"Was": 85.95,
"WasFormatted": "€85.95",
"CurrencySymbol": "€"
}
},
"Stock": {
"Available": true,
"LowOnStock": false,
"MaxOrderableQuantity": 5,
"Quantity": 20
},
"CustomData": {
"Gifting-Available": "true",
"Gift-Id": "001-001"
}
},
"001-002": {
"Id": "001-002",
"Forms": {
"colour": {
"Id": "colour_White",
"Value": "White",
"Swatch": "https://cdn.shop.com/colorimages/White.png"
},
"size": {
"Id": "size_Medium",
"Value": "Medium"
}
},
"Images": {
"Default": [
"https://cdn.shop.com/images/001_002a.png",
"https://cdn.shop.com/images/001_002b.png"
]
},
"ListingId": "001",
"Meta": {
"Barcode": "001-002",
"videoURL": "https://cdn.shop.com/001-002.mp4",
"DefaultCurrency": "GBP_EN"
},
"Name": "T-Shirt",
"Prices": {
"GBP_EN": {
"Now": 55.95,
"NowFormatted": "£55.95",
"Was": 85.95,
"WasFormatted": "£85.95",
"CurrencySymbol": "£"
},
"EUR_FR": {
"Now": 65.95,
"NowFormatted": "€65.95",
"Was": 85.95,
"WasFormatted": "€85.95",
"CurrencySymbol": "€"
}
},
"Stock": {
"Available": false,
"LowOnStock": true,
"MaxOrderableQuantity": 5,
"Quantity": 0
},
"CustomData": {
"Gifting-Available": "true",
"Gift-Id": "001-002"
}
},
"001-003": {
"Id": "001-003",
"Forms": {
"colour": {
"Id": "colour_White",
"Value": "White",
"Swatch": "https://cdn.shop.com/colorimages/White.png"
},
"size": {
"Id": "size_Large",
"Value": "Large"
}
},
"Images": {
"Default": [
"https://cdn.shop.com/images/001_003a.png",
"https://cdn.shop.com/images/001_003b.png"
]
},
"ListingId": "001",
"Meta": {
"Barcode": "001-003",
"videoURL": "https://cdn.shop.com/001-003.mp4",
"DefaultCurrency": "GBP_EN"
},
"Name": "T-Shirt",
"Prices": {
"GBP_EN": {
"Now": 55.95,
"NowFormatted": "£55.95",
"Was": 85.95,
"WasFormatted": "£85.95",
"CurrencySymbol": "£"
},
"EUR_FR": {
"Now": 65.95,
"NowFormatted": "€65.95",
"Was": 85.95,
"WasFormatted": "€85.95",
"CurrencySymbol": "€"
}
},
"Stock": {
"Available": true,
"LowOnStock": false,
"MaxOrderableQuantity": 5,
"Quantity": 20
},
"CustomData": {
"Gifting-Available": "true",
"Gift-Id": "001-003"
}
}
},
"CustomData": {
"Gifting-Available": "true",
"Gift-Id": "001-001"
}
}

Product Feed Deep Dive

This section provides a closer look into some of the properties that can be supplied in the product feed, and how they will impact the app experience.

Availability

The available field can be supplied to indicate that a Product Variant is not available for purchase. Users will not be able to add them to their cart:

Availability Flag in App.
Availability Flag in App.

Categories

Categories that each product belongs to can be defined via the category-id_[index] field. [index] should be substituted with a zero-based numerical index. For example; category-id_0, category-id_1.

Products are associated to the category with the matching ID. Products associated to a category will be displayed in the Product Listing Page when viewing the category.

Custom Data

Product data can be enriched to include extra data that can be used to power customisations in the App. For example, some products may have some gifting options to select from, which can be provided via Custom Data. Custom Data is included at both the Product and Product Variant level. The first Product Variant in the feed will have its Custom Data stored at both the Product and Product Variant levels. Product Variants that follow the first will only have their Custom Data at the Variant level.

Filters

Filters appear in the Product Listing Page when Poq's Search Service is enabled. They allow for filtering of Search results.

Forms

Product Forms can be supplied for Products that have multiple Product Variants. Forms define the properties by which each variant can differ. A T-shirt may have Size, Colour, and Fit forms. A Product Variant is an instance of the Product with a distinct variation of these forms. For example a medium green loose fit T-Shirt.

Other examples may include:

  • A 128GB Space Gray iPhone (Disk Space & Colour Forms)
  • An A3 Black Wooden Picture Frame (Size, Colour, & Material Forms)
  • A 1KG Strawberry Protein Supplement (Size & Flavour Forms)

The forms available for a Product are defined against the first variant in the feed using the forms field. Each comma-separated value in this field corresponds to a single form. Each variant must have a form-id_[Form-Name] and a form-value_[Form-Name] field for each form. form-swatch_[Form-Name] fields can be to enable a swatch picker. [Form-Name] should be substituted with one of the forms.

Example:

product-id,variant-id,forms,form-id_colour,form-value_colour,form-swatch_colour,form-id_size,form-value_size
001,sku_001,"colour,size",colour_white,White,https://cdn.shop.com/swatch/White.png,size_xx-small,XX-Small
001,sku_002,"colour,size",colour_white,White,https://cdn.shop.com/swatch/White.png,size_x-small,X-Small
001,sku_003,"colour,size",colour_white,White,https://cdn.shop.com/swatch/White.png,size_small,Small
001,sku_004,"colour,size",colour_white,White,https://cdn.shop.com/swatch/White.png,size_medium,Medium
001,sku_005,"colour,size",colour_white,White,https://cdn.shop.com/swatch/White.png,size_large,Large
001,sku_006,"colour,size",colour_white,White,https://cdn.shop.com/swatch/White.png,size_x-large,X-Large

In the App, the above feed snippet would appear as below. Each form will correspond to a picker that allows users to select a variant:

Form pickers in App.
Form pickers in App.

Images

Images can be provided to showcase Product Variants. Images are defined in the feed via the image_[index] field. [index] should be substituted with a zero-based numerical index. For example; image_0, image_1. Images are displayed and swipe-able in the app:

Images in App.

Product Metadata Links can be used to link to external resources associated with the Product. Links are defined in the feed via the link-title_[index] and the link-url_[index]/link-content_[index] fields. [index] should be substituted with a zero-based numerical index. For example; link-title_0, link-url_0, link-content_0.

In cases where a given link is present for a large number of products, it is recommended to provide a URL to the content, instead of using the content field. The content field should be used sparingly for static content that is unique to the Product.

Example:

link-title_0,link-url_0,link-title_1,link-content_1
"Size Guide",https://cdn.shop.com/sizeguide.html,"Delivery Information","<p>Delivery Information Content<p>"

The screenshot below demonstrates how the above example would display Links in the Product Details Page:

Content Links in App.
Content Links in App.

Low On Stock

A Product Variant can be highlighted as being low on stock via the low-on-stock field in the feed. Variants that are low on stock have a message displayed against them:

Low on Stock alert in App.
Low on Stock alert in App.

Prices

Prices are defined in the feed via the price-now_[Poq-Currency-Identifier] and price-was_[Poq-Currency-Identifier] fields. [Poq-Currency-Identifier] should be substituted with a Poq Currency Identifier.

Product Variants may have multiple prices, this allows Apps that are available in different regions to use the same product data. The App should only display the price as available in the user's selected region and currency. By default, the first currency provided for the variant is used.

A variant's price is made up of a "Now Price" (The current price) and a "Was Price" (The price prior to reduction). When a Was Price is provided, the App will display reduction information:

Price Reduction in App.
Price Reduction in App.

Product Listings

The listing-id is a grouping ID which indicates that a group of product variants comprise a single product listing. Product listings are shown on pages such as the Wishlist or the Product Listing Page. For example, the blue & pink variants of a single T-shirt would appear as two items if their listing IDs were different, even if they were part of the same Product.

Users are able to add Product Listings to their Wishlists without selecting a specific Product Variant, for example, if Product Variants are grouped into Product Listings based on their colour, a user can add the green T-shirt to their Wishlist without having to select a specific size.

If no listing ID is defined, the product ID will be used instead. This means that the whole Product would appear as a listing.

Promotion Badges

Promotion badges appear on the Product Details Page to highlight a particular promotion:

Promotional Badges in App.
Promotional Badges in App.

Promotion Messages

Promotion messages do not appear in the Product Details Page by default, however they can be enabled via customisations on the App.

Release Date

The Release Date property is used by Poq's Search service when sorting Product Listings by the "New In" option. When a listing is made up of multiple variants, the first variant's release date is used.

Sort Index

The Sort Index property is used by Poq's Search service when sorting Product Listings by the "Featured" option. When a listing is made up of multiple variants, the first variant's sort index is used.

Videos

The video-url property can be used to provide a link to a video that showcases the Product Variant. Video URLs are defined at the Product Variant Level. If a Video URL is provided, an icon will be displayed in the Product Details Page that will open the video when tapped:

Product Videos in App.

FAQ

When should I provide a Previous Feed File to create a Feed Diff?

The Feed Processor should run using a Feed Diff in most cases, for example, when the Product Catalogue already exists and the feed is running on a regular schedule.

When shouldn't I provide a Previous Feed File?

The Feed Processor should only run without using a Feed Diff in a few cases, such as when importing the initial Product Catalogue for the first time.

Must the Previous Feed File be the feed file that was previously run?

No, any feed file can be provided for Diffing purposes, however it is most effective when the two Feed Files are similar and contain fewer changes.

Glossary of Terms

Poq Currency Identifier

A unique identifier for a currency in a country. It consists of a required currency code and an optional country code.

Currency code is a 3-digit ISO 4217 code. Although it is expected to be a standard ISO code, it is not validated against the ISO standard. It must consist of upper case letters from the English alphabet.

Country code is a 2-digit ISO 3166 Alpha 2 code. Although it is expected to be a standard ISO code, it is not validated against the ISO Standard.

The format is as follows: (Required: [Currency Code])(Optional:_[Country Code])

Examples: GBP, EUR, EUR_DE, XBT_TW

Product

An abstract grouping of one or many Product Variants. For example, a shirt that comes in different sizes and different colours.

Product Variant

A distinct SKU of a given Product. For example, a medium green T-shirt.

Product Listing

An abstract grouping of many Product Variants for listing purposes. For more information, see Product Feed Deep Dive - Product Listings.

SKU

Initialism of 'Stock Keeping Unit'.

Now Price

The current price of a product variant.

Was Price

The previous price of a product variant.

Swatch Picker

An image based selection tool that allows users to select a form of a Product.