Skip to content

Data Layout and Modeling Guide - Feeds

View MD

This guide is the central source of truth for structuring your feed data before sending it to Luigi’s Box. Proper data modeling is the single most important factor for achieving high-quality search results and recommendations.

The concepts and conventions described here apply specifically to Feeds in XML, JSON, or CSV format. If you’re using the Content Update API, please refer to the separate API data modeling guide.

Here’s the simplest possible product you can index with just the required fields:

<?xml version="1.0" encoding="UTF-8"?>
<items>
<item>
<identity>product-123</identity>
<title><![CDATA[Blue Cotton T-Shirt]]></title>
<web_url>https://example.com/products/blue-tshirt</web_url>
</item>
<!-- more products -->
</items>

This is enough to make your product searchable. However, to unlock the full power of Luigi’s Box, you’ll want to add more fields as described below.

Luigi’s Box is very flexible regarding feed structure and support any valid XML, JSON or CSV file. However, to make the processing easier (and reduce the time to integration), please follow these guidelines:

  • Preferred formats: XML and JSON over CSV
  • XML specifics:
    • Avoid using tag attributes. Instead of <product id="123">... use <product><id>123</id></product>
    • Keep the structure as flat as possible. Nesting tags is ok, but don’t use complex nesting if possible
    • In many cases, nesting is unavoidable and it’s acceptable
  • Field naming: Name the attributes in a way that makes sense to you, there’s no prescribed naming convention

Luigi’s Box frequently encounters these problems when dealing with XML files. Avoiding them will make the process much faster:

1. No encoding of special characters (e.g., &)

<!-- ✗ WRONG - Invalid XML -->
<title>Black & White</title>
<!-- ✓ CORRECT - Using entities -->
<title>Black &amp; White</title>
<!-- ✓ CORRECT - Using CDATA -->
<title><![CDATA[Black & White]]></title>

2. Double encoding using both CDATA and entities

<!-- ✗ WRONG - Double encoded, will display as "Black &amp; White" -->
<title><![CDATA[Black &amp; White]]></title>
<!-- ✓ CORRECT - Use either CDATA or entities, not both -->
<title><![CDATA[Black & White]]></title>
<!-- OR -->
<title>Black &amp; White</title>

3. HTML in descriptions

<!-- ✓ CORRECT - HTML tags inside CDATA -->
<description><![CDATA[A nice & comfortable shirt. It's ok to use <strong>html tags</strong> in description.]]></description>

Each of your searchable types must have a separate feed. Here’s how to structure each type:

Product feeds use <items> or <products> as the root element:

<?xml version="1.0" encoding="UTF-8"?>
<items>
<item>
<!-- product attributes -->
</item>
<item>
<!-- product attributes -->
</item>
</items>

Category feeds use <categories> as the root element:

<?xml version="1.0" encoding="UTF-8"?>
<categories>
<category>
<!-- category attributes -->
</category>
</categories>

Brand feeds use <brands> as the root element:

<?xml version="1.0" encoding="UTF-8"?>
<brands>
<brand>
<!-- brand attributes -->
</brand>
</brands>

Article feeds use <articles> as the root element:

<?xml version="1.0" encoding="UTF-8"?>
<articles>
<article>
<!-- article attributes -->
</article>
</articles>

Make sure that the feed contains all products that you have, even those that are not in stock. For product attributes, it’s useful to think about four aspects of the data in the feed:

Luigi’s Box only requires two attributes for each product: title and web_url.
They must be present in the feed for each product (the tag names do not matter) as the bare minimum.

Look at the product tile in the category listing and all the information that it shows.
If you want the product tile in search results to show the same information, it must be present in the feed. This usually includes:

  • Product image
  • Product price
  • Discounts
  • Various labels

Keep in mind that some information is only visible under certain circumstances, so it’s best to check the code that renders the product tile and make sure that all information is included in the feed.

These attributes are not required to render the product tile, but they are essential for some features related to the product tile. For example, if your product tile shows an “Add to cart” button, and this button will trigger an XHR request which sends the internal product ID, make sure that this internal ID is present in the feed.

All attributes that your product should be findable by.
For example, if you want your products to be searchable by EAN, you must include product EAN code in the feed. In this regard: more is more, and the more data you provide in the feed, the better the search will be.

Following consistent naming conventions makes your data easier to maintain and debug:

  • ✓ Use descriptive, human-readable names: screen_size, color, brand
  • ✓ Be concise but clear: color instead of c, brand instead of brand_name_of_manufacturer
  • ✓ Use consistent naming across all feeds: if you use color for one product, use color for all products
  • ✓ Use lowercase with underscores (snake_case) for consistency
  • ✓ Use plural for comma-separated values: labels, tags, sizes
  • ✗ Avoid dots in parameter names: product.color (use product_color instead)
  • ✗ Especially in <parameters> tags: "N. Size" is not valid (use "Size" instead)
  • ✗ Avoid brackets: price[eur] (use price_eur instead)
  • ✗ Avoid spaces: screen size (use screen_size instead)
  • ✗ Avoid mixed case: ScreenSize or screenSize (use screen_size instead)

Certain field names have special, built-in behaviors that power ranking, filtering, and display logic.

Field NameTypeRequiredDescriptionExample
identityStringUnique identifier for the object. Must match the identity reported by analytics events. See Identity guide.NH757A
titleStringThe primary display name of the object. Used as the title in autocomplete and search widgets. Must be properly encoded or wrapped in CDATA.<title><![CDATA[Black & Decker Drill]]></title>
web_urlStringCanonical URL of the object. Often a single product can have several URLs, use the canonical URL for the feed.https://example.org/products/drill-123
Field NameTypeRequiredDescriptionExample
image_link_sStringTiny image for variant previews. Best size is around 100x100px.https://example.org/images/thumbs/100x100/2172.png
image_link_mStringMedium image suitable for autocomplete, around 200x200px.https://example.org/images/thumbs/200x200/2172.png
image_link_lStringLarge image suitable for product tile in search results. Best size is 600x600px. Use the same image that you use for rendering your current search result tile if possible.https://example.org/images/thumbs/600x600/2172.png
descriptionStringLong-form description of the product. Feel free to use formatted HTML, but make sure it is correctly encoded or enclosed in CDATA section.<description><![CDATA[A comfortable <strong>cotton</strong> shirt.]]></description>
labelsStringComma-separated list of labels, such as “Free shipping” or “Sale”.Summer sale, Free shipping
Field NameTypeRequiredDescriptionExample
priceStringThe fully formatted price as you want it to appear in the product tile, including currency. This is the price for which the product is available for purchase. A numeric price_amount is automatically extracted for sorting.$78.9 or 65 EUR
price_oldStringIf the product is on sale, this is the original price. Formatted the same as price.$81.9 or 67.50 EUR
price_*StringPer-currency price fields. The fully formatted price in a specific currency (e.g., price_eur, price_usd, price_czk). Add as many per-currency prices as you need. A corresponding _amount field is automatically extracted.<price_eur>65 EUR</price_eur>
price_*_oldStringOriginal price in a specific currency before discount (e.g., price_eur_old, price_usd_old).<price_eur_old>67.50 EUR</price_eur_old>

Multi-currency example:

<price>$78.9</price>
<price_old>$81.9</price_old>
<price_eur>65 EUR</price_eur>
<price_eur_old>67.50 EUR</price_eur_old>
<price_czk>1,850 Kč</price_czk>
Field NameTypeRequiredDescriptionExample
availabilityNumberBinary attribute. 1 = Product is orderable, 0 = Product is not orderable. Available results are automatically prioritized in ranking. If omitted, the product is treated as available.1 or 0
availability_rankNumberNumeric value strictly within <1, 15>, which encodes the availability of the product. The higher the number, the less available the product is. Takes precedence over availability if both are provided. For unavailable products, must be 15 with availability: 0.1, 3, 7, 15
availability_rank_textStringThe exact availability text as it should appear in the product tile. This field does not affect ranking but is used for frontend display.Ships within 14 days or In external warehouse / Ships within 5 days

Recommended availability_rank encoding scheme:

If your store uses 4 availability states: “In stock”, “Ships within 7 days”, “Ships within 14 days”, “Out of stock”, then a good encoding would be:

  • 1: In stock (immediately available)
  • 3: Ships within 7 days
  • 7: Ships within 14 days
  • 15: Out of stock (unavailable)

Example:

<availability>1</availability>
<availability_rank>3</availability_rank>
<availability_rank_text><![CDATA[In external warehouse / Ships within 5 days]]></availability_rank_text>
Field NameTypeRequiredDescriptionExample
boostNumberManual ranking boost for the product. Luigi’s Box supports 3 boosting levels: 1, 2, and 3. The higher the number, the stronger the boosting effect. Use judiciously to avoid interfering with the core ranking algorithm too much. You can also set up boosting in the Luigi’s Box application.1, 2, or 3
introduced_atDateDate/timestamp value in ISO 8601 format indicating the novelty of a product or when it started/will start to sell. Used to prefer newer items when sorting search results. If omitted, novelty is ignored.2021-07-15T08:00:00Z
marginNumberRelative profit margin of the product. Must be a float value between <0, 1> (e.g., 0.42 means 42% margin of product price). Used to prefer items with higher margin when sorting search results. If omitted, treated as if there is no margin.0.42

Example:

<boost>2</boost>
<introduced_at>2021-07-15</introduced_at>
<margin>0.42</margin>
Field NameTypeRequiredDescriptionExample
categoryStringProduct category with full hierarchy using pipe ( | ) delimiter. This exact category with hierarchy must appear in the category feed. If the product is in multiple categories, use the <category> tag multiple times. For XML, mark the primary category with primary="true" attribute. For JSON, the first element in the array is treated as primary.<category primary=“true”><![CDATA[Apparel | Men | Shirts]]></category>
brandStringProduct brand. This exact brand must appear in the brand feed.Nike
<category primary="true"><![CDATA[Apparel | Men | Shirts]]></category>
<category><![CDATA[Seasons | Summer | Shirts]]></category>
Field NameTypeRequiredDescriptionExample
product_codeStringSKU code. Based on our experience, people often search for products using their codes, especially in B2B segments.NK8277S
eanStringEAN barcode of the product, if available.8288881881818
to_cart_idStringInternal ID of the product necessary for add-to-cart functionality. Include all attributes necessary to add product to cart. May not be applicable in all cases. See Add to cart for more details.2172
Field NameTypeRequiredDescriptionExample
item_group_idStringLinks individual product variants together for variants search mode. All variants of the same product must share the same item_group_id and must be listed consecutively in the feed (no other products between them). See Variants in the feed.8272

Example:

<item>
<identity>NH7636A</identity>
<title>Black Nike Shirt</title>
<item_group_id>8272</item_group_id>
<!-- other attributes -->
</item>
<item>
<identity>NH7636B</identity>
<title>White Nike Shirt</title>
<item_group_id>8272</item_group_id>
<!-- All variants must follow each other -->
</item>
Field NameTypeRequiredDescriptionExample
geo_locationObjectGeographic location point in geo_point format with lat and lon properties. Used to prefer items within certain distance from user when sorting search results. If omitted, treated as if there is no location.{"lat": 49.0448, "lon": 18.553}

Example:

<geo_location>{"lat": 49.0448, "lon": 18.553}</geo_location>
Field NameTypeRequiredDescriptionExample
parametersArray/ObjectArbitrary product parameters in name/value format. You can use any names with one rule: avoid dots in the parameter name (e.g., “N. Size” is not valid).See below
<parameters>
<param>
<name><![CDATA[Size]]></name>
<value><![CDATA[XS, M, L, XL]]></value>
</param>
<param>
<name><![CDATA[Material]]></name>
<value><![CDATA[Cotton (80%), Polyester (20%)]]></value>
</param>
</parameters>
<?xml version="1.0" encoding="UTF-8"?>
<items>
<item>
<identity>NH757A</identity>
<title><![CDATA[Black Nike Shirt]]></title>
<web_url>https://example.org/2172-black-nike-shirt</web_url>
<availability>1</availability>
<availability_rank>3</availability_rank>
<availability_rank_text><![CDATA[In external warehouse / Ships within 5 days]]></availability_rank_text>
<category primary="true"><![CDATA[Apparel | Men | Shirts]]></category>
<category><![CDATA[Seasons | Summer | Shirts]]></category>
<brand><![CDATA[Nike]]></brand>
<price>$78.9</price>
<price_old>$81.9</price_old>
<price_eur>65 EUR</price_eur>
<price_eur_old>67.50 EUR</price_eur_old>
<image_link_s>https://example.org/images/thumbs/100x100/2172.png</image_link_s>
<image_link_m>https://example.org/images/thumbs/200x200/2172.png</image_link_m>
<image_link_l>https://example.org/images/thumbs/600x600/2172.png</image_link_l>
<description><![CDATA[A nice & comfortable shirt. It's ok to use <strong>html tags</strong> in description.]]></description>
<labels><![CDATA[Summer sale, Free shipping]]></labels>
<product_code>NK8277S</product_code>
<ean>8288881881818</ean>
<to_cart_id>2172</to_cart_id>
<margin>0.42</margin>
<boost>1</boost>
<introduced_at>2021-07-15</introduced_at>
<parameters>
<param>
<name><![CDATA[Size]]></name>
<value><![CDATA[XS, M, L, XL]]></value>
</param>
<param>
<name><![CDATA[Material]]></name>
<value><![CDATA[Cotton (80%), Polyester (20%)]]></value>
</param>
</parameters>
</item>
<!-- more products -->
</items>
<?xml version="1.0" encoding="UTF-8"?>
<categories>
<category>
<identity>1</identity>
<title>Shirts</title>
<web_url>https://example.org/categories/shirts</web_url>
</category>
<category>
<identity>2</identity>
<title>Blazers</title>
<web_url>https://example.org/categories/blazers-men</web_url>
<hierarchy>Apparel | Men</hierarchy>
<image_url>https://example.org/images/categories/blazers.png</image_url>
</category>
<category>
<identity>3</identity>
<title>Blazers</title>
<web_url>https://example.org/categories/blazers-women</web_url>
<hierarchy>Apparel | Women</hierarchy>
<image_url>https://example.org/images/categories/blazers-women.png</image_url>
</category>
</categories>

Category feed fields:

Field NameTypeRequiredDescription
identityStringCategory Identity.
titleStringCategory title.
web_urlStringCanonical URL pointing to category listing. This is where users go when they click on category suggestion in autocomplete.
hierarchyStringCategory hierarchy where the | character serves as a delimiter and does not include the category itself (only the path to it). Luigi’s Box will automatically convert the hierarchy into an array for displaying in the autocomplete UI. Make sure the title + hierarchy matches the categories in the product feed.
image_urlStringURL pointing to an image to show in the autocomplete UI. Images should not be larger than 100x100 pixels.

Important notes about categories:

  • The feed must be flat, no nesting is allowed (no <category> nested in another <category> tag).
  • If your categories are nested in a category tree, use the hierarchy tag to denote parent categories.
  • The title + hierarchy must match exactly with what you use in the product feed to ensure correct pairing.
<?xml version="1.0" encoding="UTF-8"?>
<brands>
<brand>
<identity>7</identity>
<title>NiceShirts</title>
<web_url>https://example.org/brands/nice-shirts</web_url>
<image_url>https://example.org/images/brands/niceshirts-logo.png</image_url>
</brand>
<brand>
<identity>8</identity>
<title>Blue</title>
<web_url>https://example.org/brands/blue</web_url>
</brand>
</brands>

Brand feed fields:

Field NameTypeRequiredDescription
identityStringBrand Identity.
titleStringBrand title. Must match the brand title used in the product feed.
web_urlStringCanonical URL pointing to brand listing. This is where users go when they click on brand suggestion in autocomplete.
image_urlStringURL pointing to an image to show in the autocomplete UI. Images should not be larger than 100x100 pixels.
<?xml version="1.0" encoding="UTF-8"?>
<articles>
<article>
<identity>37271</identity>
<title>Lorem ipsum title of the blog post</title>
<annotation>Short description, perex</annotation>
<text>Full text of the article goes here...</text>
<web_url>https://example.org/article/blog-post-lorem</web_url>
</article>
<article>
<identity>37272</identity>
<title>Another blog post title</title>
<annotation>Another short description</annotation>
<text>Full text of this article...</text>
<web_url>https://example.org/article/blog-post-ipsum</web_url>
</article>
</articles>

Article feed fields:

Field NameTypeRequiredDescription
identityStringArticle Identity.
titleStringArticle title.
web_urlStringCanonical URL pointing to the article. This is where users go when they click on article suggestion in autocomplete.
annotationStringShort annotation or perex of the article.
textStringComplete text of the article.

Understanding how to properly structure category hierarchies is crucial for accurate search results and navigation.

Categories are handled using two separate feeds that work together:

  1. Product feed: Contains products with their full category paths using pipe (|) delimiter
  2. Category feed: Contains all categories with their hierarchical relationships

In your product feed, include the full category path from top-level to the most specific category:

<item>
<identity>white-tshirt-123</identity>
<title><![CDATA[White T-shirt]]></title>
<web_url>/products/white-tshirt</web_url>
<!-- Full category path: Top-level | Parent | Leaf -->
<category primary="true"><![CDATA[Apparel | Men | T-shirts]]></category>
</item>

In your category feed, define each category with its hierarchy showing the path to it (not including itself):

<categories>
<!-- Top-level category - no hierarchy -->
<category>
<identity>category-apparel</identity>
<title>Apparel</title>
<web_url>/categories/apparel</web_url>
</category>
<!-- Second-level category - hierarchy shows parent -->
<category>
<identity>category-men</identity>
<title>Men</title>
<web_url>/categories/apparel/men</web_url>
<hierarchy>Apparel</hierarchy>
</category>
<!-- Third-level category - hierarchy shows full path to it -->
<category>
<identity>category-t-shirts</identity>
<title>T-shirts</title>
<web_url>/categories/apparel/men/t-shirts</web_url>
<hierarchy>Apparel | Men</hierarchy>
</category>
</categories>
  1. Product feed contains full paths: Apparel | Men | T-shirts
  2. Category feed contains path TO each category:
    • “Apparel” has no hierarchy (it’s top-level)
    • “Men” has hierarchy Apparel
    • “T-shirts” has hierarchy Apparel | Men
  3. Exact matching is required: The category title and hierarchy in the product feed must match exactly with the category feed

If a product belongs to multiple category paths, include all paths in the product feed:

<item>
<identity>cheddar-cheese-456</identity>
<title><![CDATA[Cheddar Cheese]]></title>
<web_url>/products/cheddar-cheese</web_url>
<category primary="true"><![CDATA[Dairy | Cow milk]]></category>
<category><![CDATA[Wine | Snacks]]></category>
</item>

The corresponding category feed would include all categories from both hierarchies:

<categories>
<category>
<identity>category-dairy</identity>
<title>Dairy</title>
<web_url>/categories/dairy</web_url>
</category>
<category>
<identity>category-cow-milk</identity>
<title>Cow milk</title>
<web_url>/categories/dairy/cow-milk</web_url>
<hierarchy>Dairy</hierarchy>
</category>
<category>
<identity>category-wine</identity>
<title>Wine</title>
<web_url>/categories/wine</web_url>
</category>
<category>
<identity>category-snacks</identity>
<title>Snacks</title>
<web_url>/categories/wine/snacks</web_url>
<hierarchy>Wine</hierarchy>
</category>
</categories>

For products that come in different variations (e.g., by size or color), Luigi’s Box offers a “variants search” mode where individual variants are aggregated and only the best match for each variant group is shown.

To activate this feature:

  1. Link individual variants using the item_group_id attribute
  2. List all variants of the same product consecutively in the feed (no other products between them)
<?xml version="1.0" encoding="UTF-8"?>
<items>
<!-- First variant group -->
<item>
<identity>NH7636A</identity>
<title>Black Nike Shirt</title>
<web_url>https://example.org/2172-black-nike-shirt</web_url>
<item_group_id>8272</item_group_id>
<color>Black</color>
<size>M</size>
<availability>1</availability>
<price>$45.00</price>
<!-- other attributes -->
</item>
<item>
<identity>NH7636B</identity>
<title>White Nike Shirt</title>
<web_url>https://example.org/2173-white-nike-shirt</web_url>
<item_group_id>8272</item_group_id>
<color>White</color>
<size>M</size>
<availability>1</availability>
<price>$45.00</price>
</item>
<item>
<identity>NH7636C</identity>
<title>Red Nike Shirt</title>
<web_url>https://example.org/2174-red-nike-shirt</web_url>
<item_group_id>8272</item_group_id>
<color>Red</color>
<size>L</size>
<availability>0</availability>
<price>$45.00</price>
</item>
<!-- All variants with item_group_id=8272 must be listed together -->
<!-- Now start a new variant group -->
<item>
<identity>NM2887A</identity>
<title>Black Hoodie - Small</title>
<web_url>https://example.org/2175-black-hoodie</web_url>
<item_group_id>8273</item_group_id>
<color>Black</color>
<size>S</size>
<availability>1</availability>
<price>$65.00</price>
</item>
<item>
<identity>NM2887B</identity>
<title>Black Hoodie - Medium</title>
<web_url>https://example.org/2176-black-hoodie-m</web_url>
<item_group_id>8273</item_group_id>
<color>Black</color>
<size>M</size>
<availability>1</availability>
<price>$65.00</price>
</item>
<!-- more products/items -->
</items>
  • Each variant needs a unique identity: Even though they belong to the same product group, each variant must have its own unique identity
  • Keep variants together: All variants with the same item_group_id must appear consecutively in the feed
  • Include distinguishing attributes: Add fields like color, size, or other variant-specific attributes so users can distinguish between variants
  • Maintain consistent data: All variants in a group should have similar base information (brand, category, description) but can differ in variant-specific attributes (color, size, availability, price)

Problem: Category in product feed doesn’t match category feed exactly.

<!-- ✗ WRONG - Product feed -->
<category>Apparel | Men's | T-shirts</category>
<!-- Category feed -->
<category>
<title>T-shirts</title>
<hierarchy>Apparel | Men</hierarchy>
</category>
<!-- The "Men's" vs "Men" mismatch will break the pairing -->
<!-- ✓ CORRECT - Product feed -->
<category>Apparel | Men | T-shirts</category>
<!-- Category feed -->
<category>
<title>T-shirts</title>
<hierarchy>Apparel | Men</hierarchy>
</category>
<!-- ✗ WRONG - Variants separated by other products -->
<item>
<identity>shirt-red-m</identity>
<item_group_id>shirt-123</item_group_id>
</item>
<item>
<identity>different-product</identity>
<item_group_id>other-456</item_group_id>
</item>
<item>
<identity>shirt-blue-m</identity>
<item_group_id>shirt-123</item_group_id>
</item>
<!-- ✓ CORRECT - All variants together -->
<item>
<identity>shirt-red-m</identity>
<item_group_id>shirt-123</item_group_id>
</item>
<item>
<identity>shirt-blue-m</identity>
<item_group_id>shirt-123</item_group_id>
</item>
<item>
<identity>different-product</identity>
<item_group_id>other-456</item_group_id>
</item>

Problem: Sending different data types for the same field across products.

<!-- ✗ WRONG - Mixing types -->
<item>
<identity>prod-1</identity>
<availability>1</availability>
<margin>0.42</margin>
</item>
<item>
<identity>prod-2</identity>
<availability>yes</availability> <!-- Should be 1 or 0 -->
<margin>42%</margin> <!-- Should be 0.42 -->
</item>
<!-- ✓ CORRECT - Consistent types -->
<item>
<identity>prod-1</identity>
<availability>1</availability>
<margin>0.42</margin>
</item>
<item>
<identity>prod-2</identity>
<availability>1</availability>
<margin>0.42</margin>
</item>
<!-- ✗ WRONG -->
<parameters>
<param>
<name>N. Size</name> <!-- Dots are not allowed -->
<value>M</value>
</param>
</parameters>
<!-- ✓ CORRECT -->
<parameters>
<param>
<name>Size</name>
<value>M</value>
</param>
</parameters>
<!-- ✗ WRONG - Values outside allowed range -->
<availability_rank>20</availability_rank> <!-- Max is 15 -->
<availability_rank>0</availability_rank> <!-- Min is 1 -->
<!-- ✓ CORRECT -->
<availability_rank>1</availability_rank> <!-- In stock -->
<availability_rank>7</availability_rank> <!-- Ships in 7-14 days -->
<availability_rank>15</availability_rank> <!-- Out of stock -->
<!-- ✗ WRONG - Multiple categories without primary marker in XML -->
<category>Apparel | Men | Shirts</category>
<category>Seasons | Summer | Shirts</category>
<!-- ✓ CORRECT - Primary category marked -->
<category primary="true">Apparel | Men | Shirts</category>
<category>Seasons | Summer | Shirts</category>
Section titled “”My categories aren’t showing up in search””

Solution: Verify that:

  • The category name + hierarchy in the product feed exactly matches the category feed
  • There are no extra spaces or different delimiters
  • The pipe character (|) is used consistently with spaces around it

Solution: Ensure your price format is consistent and recognizable. Luigi’s Box automatically extracts numeric values, but unusual formats may cause issues. Use standard formats like:

  • $45.00
  • 45.00 USD
  • €45,00
  • 1 234,56 Kč

Solution: Check that:

  • All variants share the same item_group_id
  • All variants with the same item_group_id appear consecutively in the feed
  • There are no other products between variants of the same group

”Special characters appearing incorrectly”

Section titled “”Special characters appearing incorrectly””

Solution: Use proper XML encoding:

  • Wrap text in CDATA: <title><![CDATA[Black & White]]></title>
  • Or use entities: <title>Black &amp; White</title>
  • Never use both CDATA and entities together

Solution: Verify that:

  • Your feed is accessible from the Luigi’s Box servers
  • The XML/JSON is valid (use an online validator)
  • The identity values are unique and consistent with analytics events

Luigi’s Box can work with feeds you may already have for other services:

Feed TypeUsabilityComments
HeurekaNoUses Heureka-specific categories and usually contains only a subset of products
Google MerchantYesUsually usable, or requires slight modifications
Custom feedsContact usLuigi’s Box can process feeds in custom formats - contact support to discuss

Luigi’s Box can join and merge product data from several feeds to build full product data. This is useful when:

  • Performance problems exist with taking a full data snapshot
  • Multiple data stores need to be accessed
  • Different data changes at different rates (e.g., static data vs. pricing)

Luigi’s Box can combine up to 5 different feeds:

  1. One driving feed: Contains the primary product data
  2. Up to 4 additional feeds: Contains supplementary data that gets merged
  • A single “join attribute” must be present in all feeds (typically product ID)
  • The driving feed is processed first
  • For each product, data from additional feeds is looked up and merged

Driving feed (regenerated daily):

  • Product descriptions
  • Images
  • Product parameters
  • Categories

Additional feed (regenerated hourly):

  • Pricing
  • Availability
  • Stock levels

Luigi's Box currently does not support multiple driving feeds. The product database cannot be split into several driving feeds where each contains different products (e.g., 50% in one feed, 50% in another).

While it is technically possible to provide product updates using both feeds and API simultaneously, this approach is not recommended as it will lead to subtle and hard-to-debug data discrepancies.

The intuitive expectation might be to:

  1. Provide Luigi’s Box a feed with product data that processes periodically
  2. Use the Partial Update API to update frequently changing attributes (pricing, availability) in real time

However, this leads to unexpected inconsistencies because:

  • Feed processing is not instant, it takes time depending on the number of products
  • The feed is a snapshot of data at download time
  • While processing is in progress, API updates may occur
  • The feed processing will then overwrite those API updates back to the old snapshot state
  • Luigi’s Box currently doesn’t provide protection against this data inconsistency

Instead of combining feeds and API:

  1. Increase feed processing frequency: Process feeds more often (e.g., every 15 minutes instead of hourly)
  2. Split product data into multiple feeds: Use the multiple feeds feature to separate static data (updated daily) from dynamic data (updated hourly)
  3. Use API exclusively: If real-time updates are critical, use the API for all data updates