---
title: Importing products using the API
related:
  - https://docs.kentico.com/13/e-commerce-features/configuring-on-line-stores/configuring-products/importing-products/importing-products-using-kentico-import-toolkit.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

You can import [products](https://docs.kentico.com/13/e-commerce-features/managing-on-line-stores/products.md) from an external source of data into Xperience using the API. As a source of data, you can use, for example, a CSV (comma-separated values) file.

> **Note:** **Note**: Before you start the import process, make sure you have a back up of your Xperience database for recovery purposes in case any issues arise during the import process.

## Preparing your product source data

Prepare your external source of data. Make sure that all product properties required for import into the Xperience database are included.

This example uses a CSV file containing the following records:

- **Field 1** - specifies the name of the product.
- **Field 2** - specifies the description of the product.
- **Field 3** - specifies the price of the product. Use a dot (.) to separate decimal places, e.g. _849.99_.
- **Field 4** - specifies the [department](https://docs.kentico.com/13/e-commerce-features/managing-on-line-stores/products/categorizing-products/departments.md) where the product will be placed after import. You need to enter the department code name, e.g. _DancingGoatMvc.Brewers_. If you leave the record empty or enter an invalid department code name, no department will be assigned to the product after import.

The sample file is available for download [here](https://docs.kentico.com/docsassets/13/importing-products-using-the-api/products.csv).

## Creating a console application for product imports

To import the products, create a new console application. The following sample console application allows you to import products specified in a CSV file into the **Store -> Brewers** section of the sample Dancing Goat MVC site as **Brewers**.

1. Create a new **Console application** project in Visual Studio
2. Add the connection string of your Xperience instance to the application as described in: [Using the Xperience API externally](https://docs.kentico.com/13/integrating-3rd-party-systems/using-the-xperience-api-externally.md).
3. Add the _Kentico.Xperience.Libraries_ [NuGet package](https://docs.kentico.com/13/developing-websites/starting-with-mvc-development/installing-xperience-integration-packages.md) to the project. The package version needs to match the hotfix version of the target Xperience project (and database).
4. Copy the following code into the default _Program.cs_ file.

   ```csharp

   using System;
   using System.Globalization;
   using System.IO;

   using CMS.DataEngine;
   using CMS.DocumentEngine;
   using CMS.Ecommerce;
   using CMS.Membership;
   using CMS.SiteProvider;

   namespace ProductImport
   {
       public class ProductImport
       {
           // Contains the relative path of the file with product data to import
           // By default expects the file to be located in the same directory as the compiled console application
           private const string IMPORT_FILE_PATH = "products.csv";

           // Sets the page creator
           private const string CREATOR_USERNAME = "administrator";

           // Contains the code name of the site under which the products get imported 
           private const string TARGET_SITE_CODENAME = "DancingGoatMvc";

           // Class name of the page type associated with the imported products
           private const string PRODUCT_CLASSNAME = "DancingGoatMvc.Brewer";

           // Alias path to the desired parent page type in the product tree
           private const string PARENT_PAGE_ALIAS_PATH = "/Store/Brewers";

           // Desired document culture
           private const string DOCUMENT_CULTURE = "en-US";

           // The following members are initialized based on the information provided above
           private int siteId;
           private TreeProvider tree;
           private TreeNode parentPage;
           private DataClassInfo productPageType;

           // The main entry point of the application
           public static void Main(string[] args)
           {            
               if (File.Exists(IMPORT_FILE_PATH))
               {
                   // Initializes Xperience for use in an external application
                   CMSApplication.Init();

                   ProductImport importer = new ProductImport();

                   importer.Import();
               }
               else
               {
                   Console.WriteLine($"The file \"{IMPORT_FILE_PATH}\" does not exist.");
                   Console.ReadKey();
                   Environment.Exit(1);
               }            

               Console.WriteLine($"Import process completed. Press any key to exit.");
               Console.ReadKey();           
           }

           /// <summary>
           /// Parses the provided file and imports product data to Xperience.
           /// </summary>
           public void Import()
           {
               // Retrieves contextual information necessary for the import process from the specified Xperience instance 
               InitializeContextualInformation();

               foreach (string line in File.ReadLines(IMPORT_FILE_PATH))
               {
                   ProcessLine(line);
               }
           }

           /// <summary>
           /// Retrieves and initializes Xperience objects and providers based on the provided configuration.
           /// </summary>
           private void InitializeContextualInformation()
           {
               siteId = SiteInfoProvider.GetSiteID(TARGET_SITE_CODENAME);

               UserInfo ui = UserInfo.Provider.Get(CREATOR_USERNAME);

               if (ui != null)
               {
                   tree = new TreeProvider(ui);
               }
               else
               {
                   tree = new TreeProvider();
               }

               // Gets product parent page
               parentPage = GetProductParentPage(tree);

               // Gets the default product page type
               productPageType = GetProductPageType();
           }

           /// <summary>
           /// Processes one line of the input file
           /// </summary>
           private void ProcessLine(string line)
           {
               if (line != null && line.Trim() != String.Empty)
               {
                   // Gets product data
                   string[] productData = line.Trim().Split(',');

                   ImportProduct(productData);
               }
           }

           /// <summary>
           /// Imports products from the specified file in *.csv format
           /// </summary>
           private void ImportProduct(string[] productData)
           {
               var sku = new SKUInfo
               {
                   SKUName = productData[0],
                   SKUDescription = productData[1].Trim(),
                   SKUPrice = Decimal.Parse(productData[2].Trim(), CultureInfo.InvariantCulture),
                   SKUEnabled = true,
                   SKUSiteID = siteId,
                   SKUProductType = SKUProductTypeEnum.Product
               };

               DepartmentInfo department = DepartmentInfo.Provider.Get(productData[3], siteId);
               if (department != null)
               {
                   // Assigns the product to its department
                   sku.SKUDepartmentID = department.DepartmentID;
               }

               try
               {
                   // Saves the created product to the database
                   SKUInfo.Provider.Set(sku);
               }
               catch (Exception ex)
               {
                   Console.WriteLine($"Unable to create product '{sku.SKUName}'. See errors.txt for exception details.");
                   File.AppendAllText("errors.txt", ex.ToString());
               }

               // If the product was created successfully
               if (sku.SKUID > 0)
               {
                   // Creates a product page and assigns the SKU
                   var productDoc = (SKUTreeNode)TreeNode.New(productPageType.ClassName, tree);

                   productDoc.DocumentName = sku.SKUName;
                   productDoc.DocumentSKUName = sku.SKUName;
                   productDoc.DocumentSKUDescription = sku.SKUDescription;
                   productDoc.NodeSKUID = sku.SKUID;
                   productDoc.DocumentCulture = DOCUMENT_CULTURE;

                   try
                   {
                       productDoc.Insert(parentPage, true);
                       Console.WriteLine($"Imported {sku.SKUName}.");
                   }
                   catch (Exception ex)
                   {
                       Console.WriteLine($"Unable to create page '{sku.SKUName}'. See errors.txt for exception details.");
                       SKUInfo.Provider.Delete(sku);
                       File.AppendAllText("errors.txt", ex.ToString());
                   }
               }
           }

           /// <summary>
           /// Ensures a parent page for product pages exists.
           /// </summary>
           private TreeNode GetProductParentPage(TreeProvider tree)
           {
               // Attempts to get the product parent page
               TreeNode parent = new DocumentQuery()
                                       .Path(PARENT_PAGE_ALIAS_PATH, PathTypeEnum.Single)
                                       .OnSite(TARGET_SITE_CODENAME)
                                       .AllCultures()
                                       .FirstOrDefault();      

               // Parent not found
               if (parent == null)
               {
                   Console.WriteLine($"Unable to obtain a parent page type based on the provided alias path.");
                   Console.ReadKey();
                   Environment.Exit(1);               
               }

               return parent;
           }

           /// <summary>
           /// Ensures a default product page type exists.
           /// </summary>   
           private DataClassInfo GetProductPageType()
           {
               DataClassInfo defaultProductType = DataClassInfoProvider.GetDataClassInfo(PRODUCT_CLASSNAME);

               if (defaultProductType == null)
               {
                   Console.WriteLine($"Unable to obtain a product page type from the provided codename.");
                   Environment.Exit(1);
               }

               return defaultProductType;
           }
       }
   }


   ```
5. Modify the _IMPORT\_FILE\_PATH_ constant to point to the location of the CSV file containing the product data to import.
6. Build and run the application.

The applications imports the product into the target site (_Dancing Goat MVC_ by default).

### Modifying the console application

Adjust the code as required to:

- [Change the target site](#changing-the-target-site)
- [Change the import location in the product tree](#changing-the-import-location)
- [Change the product type](#changing-the-product-type)
- [Change the culture of the created pages](#changing-the-page-culture)
- [Change the user account the associated product pages are created under](#changing-the-user-account)

#### Changing the target site

If you need to change the target site, adjust TARGET\_SITE\_CODENAME to the code name of the desired site. Site code names can be found in: **Sites** application -> edit () a site -> **General** tab.

```csharp

// Contains the code name of the site under which the products get imported 
private const string TARGET_SITE_CODENAME = "DancingGoatMvc";

```

#### Changing the import location

If you need to change the import location, adjust the value of _PARENT\_PAGE\_ALIAS\_PATH_.

```csharp

// Alias path to the desired parent page type in the product tree
private const string PARENT_PAGE_ALIAS_PATH = "/Store/Brewers";

```

For example, if you want to import your products directly into the **Store** section, change the path to _"/Store"_. The system then adds the imported products under this parent page.

#### Changing the product type

If you need to change the product type, adjust the value of _PRODUCT\_CLASSNAME_:

```csharp

// Class name of the page type associated with the imported products
private const string PRODUCT_CLASSNAME = "DancingGoatMvc.Brewer";

```

For example, if you want to import your products as **Coffee**, change the value to _"DancingGoatMvc.Coffee"_.

> **Note:** To be able to perform the import, your website must have [product types](https://docs.kentico.com/13/e-commerce-features/configuring-on-line-stores/configuring-product-page-types.md) with the corresponding code names defined.

#### Changing the page culture

If you need to change the culture of the created pages, adjust the value of _DOCUMENT\_CULTURE_:

```csharp

// Desired document culture
private const string DOCUMENT_CULTURE = "en-US";

```

#### Changing the user account

If you need to change the user the pages associated with the imported products get created under, adjust the value of CREATOR\_USERNAME:

```csharp

// Sets the page creator
private const string CREATOR_USERNAME = "administrator";

```

Running the product import

Run the console application. The system runs the application's code and informs you about the import result.

If you open the **Products** application, you can see the imported products listed under **Store** **-> Brewers**.

![](https://docs.kentico.com/docsassets/13/importing-products-using-the-api/imported_products.png)
