> ## Documentation Index
> Fetch the complete documentation index at: https://help.lobyco.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Importing product and article information

> Importing product and article information.

This guide provides insights into the integration steps necessary to enable the Product Catalog service functionalities.

In order to benefit from the full functionality spectre that the Product Catalog service offers, there are multiple import steps that need to performed:

<Steps>
  <Step>
    ## Import the [hierarchy reference book](/api-reference/retail-master-data/products/hierarchyreferencebook/post-v1-hierarchyreferencebook-import)

    The main levels that the hierarchy tree consists of.
  </Step>

  <Step>
    ## Import [hierarchy tree structure](/api-reference/retail-master-data/products/hierarchies/post-v1-hierarchies-import)

    The product categories.
  </Step>

  <Step>
    ## Import [products](/api-reference/retail-master-data/products/post-v1-products-import)

    Including their corresponding categories that they belong to.
  </Step>

  <Step>
    ## Optional: Import [article](/api-reference/retail-master-data/articles-v2/post-v2-articles-import) information
  </Step>
</Steps>

From an integration perspective, there are multiple options to make use of these import endpoints:

<Steps>
  <Step>
    ## Import via Data Import Service

    Import via Data Import Service, exposed via Lobyco Admin Tool, as all of the specified endpoints are available as import options within this tool This option is the **preferred** integration process, as the UI offers a more detailed overview of each import that was performed including number of successfully imported entries, retry functionalities, propagation of import validation errors.
  </Step>

  <Step>
    ## Import via direct API-based integration

    Import via direct API-based integration, which incurs that the client is responsible for integrating and managing the import logic (e.g. error handling).
  </Step>
</Steps>

## Hierarchy reference book

As previously specified, the hierarchy reference book is an abstraction of the main levels that the hierarchy tree consists of. The hierarchy reference book import perform only **upserts** on the specified data and can consist of:

```json theme={"system"}
[
  {
    "depthId": 0,
    "name": "Root",
    "externalDepth": -1
  },
  {
    "depthId": 1,
    "name": "Level 1",
    "externalDepth": 1
  },
  {
    "depthId": 2,
    "name": "Level 2",
    "externalDepth": 2
  },
  {
    "depthId": 3,
    "name": "Level 3",
    "externalDepth": 3
  },
  {
    "depthId": 4,
    "name": "Level 4",
    "externalDepth": 4
  },
  {
    "depthId": 5,
    "name": "Level 5",
    "externalDepth": 5
  }
]
```

## Hierarchies

The hierarchy tree structure offers an efficient data organization, its main purposes being easy hierarchy management and navigation. Via the hierarchy import endpoint (that performs only record upserts), external vendors and clients can provide a tree-like structure such as:

```json theme={"system"}
[
  {
    "name": "Root",
    "id": "1001",
    "parentId": null,
    "imageLink": null
  },
  {
    "name": "Food",
    "id": "1002",
    "parentId": "1001",
    "imageLink": null
  },
  {
    "name": "Bakery",
    "id": "1003",
    "parentId": "1002",
    "imageLink": "https://example.com/images/Bakery.png"
  },
  {
    "name": "Groceries",
    "id": "2001",
    "parentId": "1002",
    "imageLink": "https://example.com/images/groceries.png"
  },
  {
    "name": "Beverages",
    "id": "2002",
    "parentId": "2001",
    "imageLink": "https://example.com/images/beverages.png"
  },
  {
    "name": "Snacks",
    "id": "2003",
    "parentId": "2001",
    "imageLink": "https://example.com/images/snacks.png"
  },
  {
    "name": "Soft Drinks",
    "id": "2004",
    "parentId": "2002",
    "imageLink": "https://example.com/images/softdrinks.png"
  },
  {
    "name": "Chips",
    "id": "2005",
    "parentId": "2003",
    "imageLink": "https://example.com/images/chips.png"
  },
  {
    "name": "Chocolate",
    "id": "2006",
    "parentId": "2003",
    "imageLink": "https://example.com/images/chocolate.png"
  }
]
```

<Warning>
  **Important**: The hierarchy tree structure should contain a root (meaning that it has no parent identifier). Also, it is highly important that each intermediary hierarchy nodes should contain a valid parent identifier. The imageLink is an optional field, but it can be used within other enabled features, if available (e.g. Scan\&Pay).
</Warning>

The hierarchy import functionalities also offer a [patch-like functionality](/api-reference/retail-master-data/products/hierarchies/patch-v1-hierarchies-import), that permits the modification of an existing hierarchy tree. Basically, this endpoint offers a partial import functionality that performs upserts of existing nodes and the addition of new leaf nodes and subtrees.

## Products

The hierarchy import enables also the import of product information (non-store specific information). The product import endpoint expects an array of products that will be upserted within the Product Catalog system:

```json theme={"system"}
[
  {
    "name": "White Sandwich Bread 500 g",
    "externalId": "EXT-1001",
    "hierarchyId": "1001",
    "imageLink": "https://example.com/images/bread_white_500.jpg",
    "eans": [
      "4820001000006"
    ],
    "brand": {
      "id": "BR-001",
      "name": "Daily Loaf"
    },
    "suppliers": [
      {
        "id": "SUP-001",
        "name": "Fresh Market"
      },
      {
        "id": "SUP-002",
        "name": "Local Bakery Co."
      }
    ],
    "saleUnit": "piece",
    "weightUnit": "kg",
    "unitOfMeasure": "piece",
    "unitsPerPiece": 1,
    "isWeightable": false,
    "restrictions": [],
    "metadata": {"isEcological": true}
  }
]
```

<Warning>
  **Important**: The endpoint exposes multiple fields that can be filled up for a more comprehensive product information structure, but the required fields are:

  * Product name
  * External Identifier - client-specific product identifier
  * Hierarchy Identifier - the category the product belongs to
  * Eans - barcodes scannable within the store
</Warning>

<Warning>
  **Important**: If the current product information structure does not suffice, external clients and vendors can use the **metadata** field for custom information.
</Warning>

## Articles

If the client-specific integration requires also the storage of store-specific information (e.g. sale prices), the Product Catalog service also exposes two different import types to accommodate this scenario:

1. Full article import - upsert article information (supports both non-store and store-specific details)
2. Article prices import - upsert only price information attached to existing articles

<Warning>
  **Important**: In case the product information is already stored within the Product Catalog service, then it is recommended to use directly the [Article prices import](/api-reference/retail-master-data/articles-v2/post-v2-articles-prices-import)
</Warning>

### Full article import

Supports the import of non-store specific (product) and store-specific information (relevant for articles) within a single request.

```json theme={"system"}
[
  {
    "name": "Coca-Cola Classic 1.5L",
    "externalId": "EXT-1001",
    "hierarchyId": "2001",
    "imageLink": "https://example.com/images/cocacola-1-5l.jpg",
    "brand": {
      "id": "Coca-Cola",
      "name": "BR-COCA"
    },
    "eans": [
      "5449000131805"
    ],
    "suppliers": [
      {
        "id": "Metro Cash & Carry",
        "name": "SUP-201"
      },
      {
        "id": "Retail Partners",
        "name": "SUP-202"
      }
    ],
    "saleUnit": "bottle",
    "units": null,
    "unitOfMeasure": "liter",
    "unitsPerPiece": 1,
    "isWeightable": false,
    "restrictions": [],
    "metadata": {
      "isSugarFree": false,
      "volume": "1.5L"
    },
    "depositItemExternalId": null,
    "hamperItemExternalIds": [],
    "prices": [
      {
        "storeId": "-1",
        "salePrice": 19.99,
        "pricePerUnit": null,
        "pricePerPiece": null,
        "isWithoutBarcode": null,
        "taxCode": "VAT20"
      },
      {
        "storeId": "STORE-002",
        "salePrice": 19.99,
        "pricePerUnit": null,
        "pricePerPiece": null,
        "isWithoutBarcode": true,
        "taxCode": "VAT10"
      }
    ]
  }
]
```

<Warning>
  **Important**: As in the case of the product import endpoint, this functionality also exposes multiple fields that can be filled up for a more comprehensive article information structure, but the required fields are:

  * Product name
  * External Identifier - client-specific product identifier
  * Hierarchy Identifier - the category the product belongs to
  * Eans - barcodes scannable within the store
  * Prices - information relevant on a store level:
    * Store identifier
    * SalePrice
    * TaxCode

  In order to obtain a more optimized data structure, if an article contains a price that is shared across multiple stores, the respective article entry can be imported with **-1** as store identifier to act as a default article price. If a store has a custom price, then upon retrieval the more specific price will be returned.
</Warning>

### Article prices import

Acts as an import type that can be run also during business hours, since prices usually represent a more dynamic article information. The endpoint requires only:

```json theme={"system"}
[
  {
    "externalId": "EXT-1001",
    "storeId": "-1",
    "salePrice": 19.99,
    "pricePerUnit": null,
    "pricePerPiece": null,
    "isWithoutBarcode": null,
    "taxCode": "VAT20"
  },
  {
    "externalId": "EXT-1001",
    "storeId": "STORE-002",
    "salePrice": 19.99,
    "pricePerUnit": null,
    "pricePerPiece": null,
    "isWithoutBarcode": true,
    "taxCode": "VAT10"
  }
]
```

<Warning>
  **Important**: Required fields are:

  * External identifier
  * Store identifier
  * Sale price
  * Tax code
</Warning>

## File content and limitations

The Product (Catalog) Service is used internally to expose core product (or article) information across different Lobyco features and flows. It serves as a central source for key product attributes, such as names, categories, hierarchy, and base pricing.

Product data is typically synchronized from the retailer’s Product Information Management (PIM) system to ensure consistency of product hierarchy and main product details across the platform. The service does not handle store-specific data (for example, store-level pricing).

Possible Integrations within Lobyco ecosystem:

* Purchase Load Enricher: retrieve the brandId and hierarchy
* Data Platform: required for the 1:1 Personal Offers algorithm: product hierarchy, product attributes
* Shopping List: retrieve the product name

Entities must be loaded sequentially in the following order:

1. Reference Book
2. Hierarchy
3. Products.

## **1. Reference Book**:

* **depthId**: Internal depth level identifier (starting from 0)
* **name**: Specific name for each level (e.g., *Root*, *Level 1*, or client-specific names)
* **externalDepth**: Depth level from the client’s system (e.g., root level might be -1)

### **Example of valid content**

**Json file format:**

```
{"depthId": 0, "name": "Root", "externalDepth": -1}
{"depthId": 1, "name": "Level 1", "externalDepth": 1}
```

**Json format:**

```
POST: /v1/entities/HierarchyReferenceBook/import
Body :
[
  {
    "depthId": 0,
    "name": "Root",
    "externalDepth": -1
  },
  {
    "depthId": 1,
    "name": "Level 1",
    "externalDepth": 1
  }
]
```

### Limitations

* The HierarchyReferenceBook should be created first and it should be created only once.
* An array of hierarchy items. Successful loading depends on the existence of a **reference book with appropriate levels** and **valid hierarchy items** (each with a name, ID, and proper parent-child relationships).
* When the hierarchy is created, products should not be included as a hierarchical level. Hierarchical levels should be created only for categories of products.

## **2. Hierarchy**

This is the format of the hierarchies.

* **name**: Name specific to this hierarchy level
* **id**: Unique identifier of the current item
* **parentId**: Identifier of the parent item (one level above). In case it's a **root item**, the `parentId` should be `null`
* **ImageLink**: Link of hierarchy image. Can be `null`

### **Example of valid content:**

**Json file format:**

```
{"name": "Food", "id": "1", "parentId": null, "imageLink": null}
{"name": "Sweets", "id": "2", "parentId": "1", "imageLink": null}
{"name": "Chocolate", "id": "3", "parentId": "1", "imageLink": null}

```

**Json format:**

```
POST: /v1/entities/Hierarchy/import
Body :
[
  {
    "name": "Food",
    "id": "1",
    "parentId": null,
    "imageLink": null
  },
  {
    "name": "Bakery",
    "id": "2",
    "parentId": "1",
    "imageLink": null
  },
  {
    "name": "Sweets",
    "id": "3",
    "parentId": "1",
    "imageLink": null
  }
]

```

### Limitations

* Hierarchies must be created in a single request. You can't create just the root level in one request and then add additional levels for it in a separate request.
* If you want to update a hierarchy, you must send the **entire structure**, from the root level down to the last category — otherwise, the operation will fail.
* Hierarchical levels should match the depth used when the HierarchyReferenceBook was created.

## **3. Products**

This final step depends on the successful loading of the hierarchy, as it contains the hierarchy identifier.

### **Products**

* **name**: Product name
* **externalId**: Product identifier
* **imageLink**: Product image URL \[**optional**]
* **eans**: Array of EANs and/or UPCs
* **brand**: Brand name and identifier \[**optional**]
* **suppliers**: Array of suppliers with identifiers and names \[**optional**]
* **saleUnit**: Sale unit \[**optional**]
* **weightUnit**: Weight unit \[**optional**]
* **hierarchyId**: Identifier of the hierarchy leaf, which must exist in our DB (`externalId` in our DB, previously referred to as `id` in the contract)

### **Example of valid content:**

**Json file format:**

```
{"name":"Milka chocolate","externalId":"12345","imageLink":"some url","eans":["1234567890123","346534343434"],"brand":{"id":"32","name":"Milka"},"suppliers":[{"id":"432","name":"Some supplier"}],"saleUnit":"12","weightUnit":"321","hierarchyId":"3"}
{"name":"Toblerone 360g","externalId":"54321","imageLink":"some url","eans":["1234567890123","346534343434"],"brand":{"id":"32","name":"Toblerone"},"suppliers":[{"id":"432","name":"Some supplier"}],"saleUnit":"15","weightUnit":"1","hierarchyId":"3"}
{"name":"Whole Grain Bread","externalId":"98765","imageLink":"https://example.com/images/whole-grain-bread.jpg","eans":["8901234567890","8901234567891"],"brand":{"id":"78","name":"PanGust"},"suppliers":[{"id":"876","name":"Rustic Bakery Co."}],"saleUnit":"1","weightUnit":"500g","hierarchyId":"2"}

```

**Json format:**

```
POST: /v1/entities/Product/import
Body:
[
  {
    "name": "Milka chocolate",
    "externalId": "12345",
    "imageLink": "some url",
    "eans": [
      "1234567890123",
      "346534343434"
    ],
    "brand": {
      "id": "32",
      "name": "Milka"
    },
    "suppliers": [
      {
        "id": "432",
        "name": "Some supplier"
      }
    ],
    "saleUnit": "12",
    "weightUnit": "321",
    "hierarchyId": "3"
  },
  {
    "name": "Toblerone 360g",
    "externalId": "54321",
    "imageLink": "some url",
    "eans": [
      "1234567890123",
      "346534343434"
    ],
    "brand": {
      "id": "32",
      "name": "Toblerone"
    },
    "suppliers": [
      {
        "id": "432",
        "name": "Some supplier"
      }
     ],
    "saleUnit": "15",
    "weightUnit": "1",
    "hierarchyId": "3"
  },
  {
    "name": "Whole Grain Bread",
    "externalId": "98765",
    "imageLink": "https://example.com/images/whole-grain-bread.jpg",
    "eans": [
      "8901234567890",
      "8901234567891"
    ],
    "brand": {
      "id": "78",
      "name": "PanGust"
    },
    "suppliers": [
      {
        "id": "876",
        "name": "Rustic Bakery Co."
    }
   ],
   "saleUnit": "1",
   "weightUnit": "500g",
   "hierarchyId": "2"
  }
]
```

## API reference

Endpoint documentation: [Products](/api-reference/retail-master-data/products).
