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
- When Product Feed processing commences, products are constructed from the data provided in the feed.
- The latest products are distributed throughout the Poq Platform.
- Catalogue, Content, and Search services ingest this data in an appropriate format.
- 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.
Each Variant of a given Product must appear sequentially. If a Product's Variants are interrupted by Variants belonging to another Product, they may not be processed.
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
Property | Field Name | Description | Required | Example | Remarks |
---|---|---|---|---|---|
Product | product-id | Unique identifier for a single product. | Required | 001 | Must appear for each Product Variant. It must only appear in the feed consecutively. |
Product Meta | default-variant-id | The default variant that represents the product. | Optional | sku_001 | Must match a variant ID provided in the feed. Defaults to the first Product Variant present. |
Product Meta | link-title_[index] | Title of a linked content page. | Optional | "Size Guide" | Index is zero-based. See Links |
Product Meta | link-url_[index] | Absolute URL of a content page. | Optional | https://cdn.shop.com/sizeguide.html | Index is zero-based. See Links |
Product Meta | link-content_[index] | Static content as HTML or plain text. | Optional | <p>Size Guide content</p> | Index is zero-based. See Links |
Product Meta | web-url | Absolute website URL of the product. | Optional | https://shop.com/products/001 | |
Product Details | brand | The brand of the product. | Optional | "Ordinary Shirts" | |
Product Details | description | Long description of the product in plain text. | Required | "This is an ordinary T-shirt to wear on an ordinary day." | |
Product Details | description-raw | Long 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 Details | short-description | Short description of the product in plain text. | Optional | "This is an ordinary T-shirt to wear on an ordinary day." | |
Product Details | short-description-raw | Short 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 Promotion | promotion-badge_[index] | Text badge to display against the Product. | Optional | "Sale" | Index is zero-based. See Promotion Badges |
Product Promotion | promotion-message_[index] | Promotional message to display against the Product. | Optional | "Buy 1 Get 1 Free" | Index is zero-based. See Promotion Messages |
Product Categories | category-id_[index] | ID of the Category that the product belongs to. | Optional | "clothing" | Index is zero-based. See Categories |
Product Review | review-count | The number of reviews for the Product. | Optional | 20 | Must be a positive, whole number. |
Product Review | review-rating | The average rating for the Product. | Optional | 4.5 | Must be a decimal. |
Product Forms | forms | The variable forms of the product. | Optional | "colour,size" | Comma-separated values. See Forms |
Product Variant | variant-id | Unique identifier for a single product variant. | Required | sku_001 | Must be unique among the feed. This is usually the variant SKU. |
Product Variant | listing-id | An identifier that can be used to group variants together into a single product listing. | Optional | product_001-blue | Duplicate listing IDs must only exist within a single product. See Product Listings |
Product Variant | name | The display name of the Product Variant. | Required | T-Shirt | |
Product Variant Meta | barcode | Barcode number of the Product Variant | Optional | T-Shirt | |
Product Variant Meta | release-date | Date that the Product Variant went on sale. | Optional | 2020-09-11 | Value should be in ISO 8601 format. See Release Date |
Product Variant Meta | sort-index | Sort Index of the Product. | Optional | 1001 | Value should be an integer. See Sort Index |
Product Variant Meta | video-url | Absolute video URL showcasing the Product Variant. | Optional | https://cdn.shop.com/sku_001.mp4 | See Videos |
Product Variant Price | price-now_[Poq-Currency-Identifier] | The current price of a Product Variant. | Required | 10.99 | A Product Variant must have at least one "Now Price". See Prices |
Product Variant Price | price-was_[Poq-Currency-Identifier] | The price of a Product Variant prior to reduction. | Optional | 12.99 | A Product Variant must have at least one "Now Price". See Prices |
Product Variant Form | form-id_[Form Name] | Unique ID of the Form Variation. | Optional | colour_red , size_small | Each comma-separated value in the forms field must have a matching form-id_[Form Name] field. See Forms |
Product Variant Form | form-value_[Form Name] | Text value of the Form Variation. | Optional | Red , Small | Each comma-separated value in the forms field must have a matching form-value_[Form Name] field. See Forms |
Product Variant Form | form-swatch_[Form Name] | Swatch Image of the Form Variation. | Optional | https://cdn.shop.com/swatch/red.png | Each comma-separated value in the forms field may have a matching form-swatch_[Form Name] field. See Forms |
Product Variant Stock | available | Indicates if the Product Variant is available. | Optional | true , false | Defaults to true if not present. See Availability |
Product Variant Stock | low-on-stock | Indicates if the Product Variant is low on stock. | Optional | true , false | Defaults to false if not present. See Low on Stock |
Product Variant Stock | lead-time | Estimated period of time between order placement and completion. | Optional | 2 weeks | |
Product Variant Stock | max-orderable-quantity | Indicates how many of a given Product Variant can be ordered at once. | Optional | 5 | Must be a positive whole number. Defaults to the value of quantity |
Product Variant Stock | quantity | Indicates how many of a given Product Variant can be ordered is in stock. | Optional | 5 | Assumed to be infinite when not provided. |
Product Variant Images | image_[Index] | Images of the Product Variant. | Required | https://cdn.shop.com/sku_011_0.png | Index is zero-based. At least one image is required. See Images |
Product Variant Dynamic Filters | filter-attr-name_[Index] | Name of a filter attribute. | Optional | Style , Material | Index is zero-based. See Filters |
Product Variant Dynamic Filters | filter-attr-value_[Index] | Value of a filter attribute. | Optional | Formal , Cotton | Index is zero-based. See Filters |
Custom Data | [Custom Field Name] | Any custom data to be attached to the Variant. | Optional | Custom Value | Any 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-Id1,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-0011,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-0021,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:
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_size001,sku_001,"colour,size",colour_white,White,https://cdn.shop.com/swatch/White.png,size_xx-small,XX-Small001,sku_002,"colour,size",colour_white,White,https://cdn.shop.com/swatch/White.png,size_x-small,X-Small001,sku_003,"colour,size",colour_white,White,https://cdn.shop.com/swatch/White.png,size_small,Small001,sku_004,"colour,size",colour_white,White,https://cdn.shop.com/swatch/White.png,size_medium,Medium001,sku_005,"colour,size",colour_white,White,https://cdn.shop.com/swatch/White.png,size_large,Large001,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:
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:
Links
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:
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:
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:
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:
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:
FAQ
How should I provide a Previous Feed File to be used in Feed Comparison?
You do not need to provide the previous feed file to be used as a basis for Comparison. This will be provided automatically by the Feed Manager from the History of the given Feed.
Can a Product Variant belong to several Products?
No, each Variant in the Catalogue must have a unique ID. Similarly, each Listing ID must only belong to a single Product.
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.