Field mapping and data

Set up field mapping for product data imports

In order to import any product data into Dotdigital Personalization we need to be able to understand the source product data items, and be able to map values from the product data's source format to Personalization's format.

[
  {
    "id": "ab1234-1",
    "sku": "gzz63774_red_xl_2",
    "price": 19.99,
    "currency": "USD",
    "display_name": "Festive jumper with dancing reindeer",
    "description": "Keep warm and look fashionable this festive season with this warm, stylish and festive jumper. Made in Lapland by elves!",
    "thumbnail": "https://media.example.com/i/gzz63774_red_xl_2/female-red-dancing-reindeer-crop-christmas-jumper",
    "store_link": "https://store.example.com/product/gzz63774_red_xl_2/",
    "stock": 32,
    "color": "red",
    "styles": "Casual|Loose|Generous",
    "categories": "festive|women|jumper|wool",
    "review_id": "0de0fb84-3180-44f6-9bf1-c4dc1b00df46",
    "review_score": 4.9,
    "review_count": 1562,
    "lat": 51.5061984,
    "long": -0.0873022,
    "postcode": "SE19BG",
    "country": "GB",
    "product_locations": "1234|23543"
  },
  {
    "id": "ab1234-3",
    "sku": "izz84994_silver_m_1",
    "price": 14.99,
    "currency": "USD",
    "display_name": "Silver Snowflake Christmas Ornament",
    "description": "Add a touch of elegance to your Christmas tree with this beautifully crafted silver snowflake ornament. Made from high-quality metal, this ornament is sure to become a cherished family keepsake for years to come.",
    "thumbnail": "https://media.example.com/i/izz84994_silver_m_1/silver-snowflake-christmas-ornament",
    "store_link": "https://store.example.com/product/izz84994_silver_m_1/",
    "stock": 60,
    "color": "silver",
    "styles": null,
    "categories": "festive|ornament|decoration",
    "review_id": "44079bfd-57f2-46c2-bf8c-b5d237c7e3cc",
    "review_score": 3.2,
    "review_count": 12,
    "lat": 51.5061984,
    "long": -0.0873022,
    "postcode": "SE19BG",
    "country": "GB",
    "product_locations": "1234|23543"
  },
  {
    "id": "ab1234-4",
    "sku": "jzz95104_blue_s_4",
    "price": 29.99,
    "currency": "USD",
    "display_name": "Plush Santa Claus Stuffed Toy",
    "description": "Bring joy and cheer to your home this Christmas with this adorable plush Santa Claus stuffed toy. Made from soft, high-quality materials, this cuddly toy is perfect for kids and adults alike.",
    "thumbnail": "https://media.example.com/i/jzz95104_blue_s_4/plush-santa-claus-stuffed-toy",
    "store_link": "https://store.example.com/product/jzz95104_blue_s_4/",
    "stock": 25,
    "color": "red",
    "styles": null,
    "categories": "festive|toy|plush",
    "review_id": "fd888119-61ba-423d-84a8-1130ba083d72",
    "review_score": 4.1,
    "review_count": 47,
    "lat": 51.5061984,
    "long": -0.0873022,
    "postcode": "SE19BG",
    "country": "GB",
    "product_locations": "1234|23543"
  }
]

Describe field mappings

In the field_mapping field you must pass an object with a field for each Personalization product field you want to map, with a mapping object defining how values are mapped to it from the source product data.

Almost all field mappings require the source_field_name defining, as this tells importer how to find the unique product identifier for each product item in the source data. The exception to this is fixed value fields, which have a val field instead.

Optional fields you can also utilize to define the field mapping are:

FieldPurpose
source_field_nameThe field name in the source product data to map to.
field_type

The data can be loaded as a specific data type using the field_type attribute.

Allowed values of field_type:
  • int - integer values such as stock level.

  • double - non-integer values such as prices.

  • datetime - date

  • bool - Boolean value Supported values areyes/no, 1/0, true/false. Not case sensitive.

  • stock - converts in stock or yes to 1 and other values to 0. Not case sensitive.

  • json - maps {"key":"value"} to a dictionary / nest of dictionaries.

  • jsonpricelist - allows for the import of JSON-based customer group price lists Requires B2B module.

    Fields with a mapping containing a list_separator attribute are split based on the separator. For example, "list_separator":"," is treated as a CSV file. Quotes and spaces are not permitted within the field.

valUse if this is a fixed value field rather than a mapping.
list_separatorOnly apply to fields that have multiple values separated by a character (CSV), and should contain the separating character , for example, |.
ignore_blankNormally, empty fields in the import file are loaded and overwrite any existing data in the field. If you want to keep existing data when no data is supplied in the import file, set this field to true. This mapping field is then only loaded if non-blank data is supplied in the file.
Category / tag specific
category_groupOnly applies to category / tag fields, and is used to indicate the grouping for the categories / tags being mapped.
replace_category_groupIf true this replaces all existing values in the category / tag group with the imported value.
Google Shopping specific
google_currency_fieldIs used to indicate that the field mapping is linked to a compound price and currency value, for example, 14.99 GBP and this indicates what aspect to extract for this mapping either uv the numeric price or curr the currency code

Mandatory field mappings

The absolute minimum required for mapping in order to import product data is the prid field, but that alone would not be very useful, so we strongly advise you to map as many fields as you can.

Example mapping for prid:

{
  "prid": {
    "source_field_name": "id"    
  }
}

Optional field mappings

Optional fields you can also utilize are:

Personalization Product FieldAreaPurpose
vidIdentifierThe variant identifier for variants of a product.
skuIdentifierThe SKU for the product.
nDescriptionThe name of the product.
descDescriptionThe description of the product.
qtyDescriptionThe quantity of items in the product.
imgDescriptionProduct image URL.
img_tnDescriptionProduct image thumbnail URL.
sbrDescriptionSite brand of the product, for sites that support this.
langDescriptionLanguage of the product description using ISO 639 language codes, for example en.
catDescriptionSeparated list of categories or tags for this product. You can set what separator character is used in the field mapping.
relatedDescriptionSeparated list of product ids related this product. You can set what separator character is used in the field mapping.
location_idsDescriptionLocation information for the product, if location based.
ridReviewsProduct review ID (rid) field, if neither the product ID or SKU values are suitable for this purpose.
reviews.ratingReviewsThe average review rating for the product, for example, 4.9.
reviews.ratingCountReviewsThe number of reviews that contributed to the average score.
stockCommerceQuantity in stock.
uCommerceProduct page URL.
pthCommercePath of the product, for example, clothes/jumpers. Should only be used if the path is fixed for one product. Product ID / SKU preferred.
upCommerceUnit price as seen by the user, with the currency symbol and value, for example, $14.99.
rupCommerceRegular unit price, before any sale or offer, with the currency symbol and value, for example, $19.99.
uvCommerceUnit value, the product's numeric value in the currency, for example, 14.99.
ruvCommerceRegular unit value, before any sale or offer. Numeric value.
currCommercePrice currency - ISO 4217 currency code, for example, USD.
cg_pricesCommerceSet of prices to allow different pricing by groups.
promoCommerceSeparated list of promotional flags for this product. You can set what separator character is used in the field mapping.
ex.{field}Meta dataYou can update any attribute of extra properties for the product (ex) using this naming pattern.

Example:

{
  "prid": {
    "source_field_name": "id",
    "field_type": "int"
  },
  "ex.color": {
    "source_field_name": "color"
  },
  "curr": {
    "source_field_name": "currency"
  },
  "uv": {
    "source_field_name": "price",
    "field_type": "double"
  },
  "img": {
    "source_field_name": "thumnail"
  },
  "u": {
    "source_field_name": "store_link"
  },
  "stock": {
    "source_field_name": "stock",
    "field_type": "int"
  },
  "n": {
    "source_field_name": "display_name"
  },
  "cat": {
    "source_field_name": "categories",
    "list_separator": "|"
  }
}

Fixed value fields

Sometimes an element of the required data for Personalization may not exist in the source product data, but is a known fixed value. These can be defined using the val field, optionally combined with the field_type field.

{
  "curr": {
    "val": "USD"
  },
  "stock": {
    "val": 1,
    "field_type": "integer"
  }
}

Categories and product tag values

There's special support for uploading categories or tag values for each product. These can be used for many purposes, including in Recommendation SmartBlock filters to only show products with particular category or tag values.

You can map these values to either one CSV-style source field or to source multiple fields, dependent on your source data format.

🚧

Categories and tags are overwritten

Any existing categories or tag values for the product are cleared when you upload new values to that product.

CSV fields

For mapping to CSV fields you need to map to a single field but specify a list_separator character so we can split the value using this into multiple categories / tags.

{
  "cat": {
    "source_field_name": "categories",
    "list_separator": "|"
  }
}

Multiple fields

For mapping multiple separate fields to categories or tags you must define a mapping per field using an index suffix on the cat field: cat:{Index}

{
  "cat:1": {
    "source_field_name": "main_category"
  },
  "cat:2": {
    "source_field_name": "secondary_category"
  }
}

Category and tag grouping

You can optionally group category or tag values into groups using the category_group field.

For example, if you want to pick the style of clothes that a shopper browses most often, you'd have a category or tag group called Style and within that, categories such as casual, lingerie, and formal. You can import categories and tags into more than one group if required; just add an additional category_group field.

Use the replace_category_group field to replace all existing values in the category or tag group with the imported value.

{
  "cat": {
    "source_field_name": "styles",
    "list_separator": "|",
    "category_group": "style"
  }
}

Google Shopping price fields

Google Shopping product feeds contain a compound price and currency value, for example, 14.99 GBP.

Personalization requires the numeric price and currency to be mapped separately. To do this you can add the field google_currency_field to the up and curr field mappings to indicate they refer to a compound price and currency value, and the field value indicates whether we should map the uv (Unit Value) or curr currency code from the source value.

{
  "up": {
    "source_field_name": "google_price",
    "google_currency_field": "uv"
  },
  "curr": {
    "source_field_name": "google_price",
    "google_currency_field": "curr"
  }
}

Promotional flags

We support setting promotional flags on products. These can be used in the recommendation SmartBlock filters to only show products with particular promotional flags. For example, you could use flags for onOffer, new, or blackFriday.

CSV fields

For mapping to CSV fields you must map to a single field but specify a list_separator character so we can split the value into multiple categories or tags.

{
  "promo": {
    "source_field_name": "promotions",
    "list_separator": "|"
  }
}

Multiple fields

For mapping multiple separate fields to promotion flags you must define a mapping per field using an index suffix on the promo field: promo:{Index}

{
  "promo:1": {
    "source_field_name": "main_promotion"
  },
  "promo:2": {
    "source_field_name": "secondary_promotion"
  }
}

Related products

We support related products. Use the related field to indicate which product IDs are related. The related products inherit any Site Brand, Currency, and Language that the parent product has. These can then be used by SmartBlocks to load the corresponding full products.

CSV fields

For mapping to CSV fields you must map to a single field but specify a list_separator character so we can split the value into multiple categories or tags.

{
  "related": {
    "source_field_name": "related_ids",
    "list_separator": ","
  }
}

Mapping to variants

To import a variant as a related product use .. to separate the product ID from the variant ID. For example, your source related products CSV might look like:

bbg233,abc123..variantA,abc123..variantB

Product variants

It’s also possible to upload multiple SKU-level variants of the same product. This is done by first including the base product, which is where all the shared data values are stored, then each variant can be included.

You must have a base product record that does not contain a vid field or has a null value. Only the variants should have this defined.

A variant is identified by the Variant ID (vid) value and matching Product ID (prid) to the base product. Variant IDs can be any string but must match what is used on your ecommerce site to ensure correlation.

For example, this source product data:

[
   {
    "id": "ab1234",
    "sku": "ab1234_red_xl_2",
    "price": 19.99,
    "currency": "USD",
    "display_name": "Festive jumper with dancing reindeer",
    "description": "Keep warm and look fashionable this festive season with this warm, stylish and festive jumper. Made in Lapland by elves!",
    "thumbnail": "https://media.example.com/i/ab1234_red_xl_2",
    "store_link": "https://store.example.com/product/ab1234_red_xl_2/",
    "stock": 32,
    "color": "red",
    "styles": "Casual|Loose|Generous",
    "categories": "festive|women|jumper|wool"
  },
  {
    "id": "ab1234",
    "sku": "ab1234_blue_xl_2",
    "variant": "blue",
    "price": 14.99,
    "currency": "USD",
    "thumbnail": "https://media.example.com/i/ab1234_blue_xl_2",
    "store_link": "https://store.example.com/product/ab1234_blue_xl_2/",
    "stock": 60,
    "color": "blue"
  }  
]

using this mapping:

{
  "prid": {
    "source_field_name": "id"
  },
  "vid": {
    "source_field_name": "variant"
  },
  "n": {
    "source_field_name": "display_name"
  },
  "img": {
    "source_field_name": "thumbnail"
  },
  "u": {
    "source_field_name": "store_link"
  },
  "curr": {
    "source_field_name": "currency"
  },
  "up": {
    "source_field_name": "price",
    "field_type": "double"
  },
  "stock": {
    "source_field_name": "stock",
    "field_type": "integer"
  }
}

would create the following product listings, as the blue variant inherits any omitted fields from the base product:

[
  {
    "prid": "ab1234",
    "vid": null,
    "curr": "USD",
    "n": "Festive jumper with dancing reindeer",
    "img": "https://media.example.com/i/ab1234_red_xl_2",
    "u": "https://store.example.com/product/ab1234_red_xl_2/",
    "uv": 19.99,
    "up": "$19.99",
    "stock": 32
  },
  {
    "prid": "ab1234",
    "vid": "blue",
    "curr": "USD",
    "n": "Festive jumper with dancing reindeer",
    "img": "https://media.example.com/i/ab1234_blue_xl_2",
    "u": "https://store.example.com/product/ab1234_blue_xl_2/",
    "uv": 14.99,
    "up": "£14.99",
    "stock": 60
  }
]

Multiple price lists

📘

Requires B2B module.

A customer group is a set of prices to allow different pricing by groups, so that you can offer different prices to customers based on their grouping.

For example, imagine you had scaled pricing based on a customer loyalty group:

  • Base price: £26.99
  • Gold Tier: £23.99
  • Silver Tier: £24.99
  • Bronze Tier: £25.99

You need to ensure these prices are contained within your product data source in this JSON format, with each pricing group defined, the group identifier needs to correlate with your customer records person.cg field :

{

"{Group identifier}": {

"uv": {Numeric price for group},

"ruv": {Original numeric price of product}

}

}

Example

[
  {
    "id": "ab1234",
    "sku": "ab1234_red_xl_2",
    "prices": {
      "basePrice": {
        "uv": 26.99
      },
      "goldTier": {
        "uv": 23.99,
        "ruv": 26.99
      },
      "silverTier": {
        "uv": 24.99,
        "ruv": 26.99
      },
      "bronzeTier": {
        "uv": 25.99,
        "ruv": 26.99
      },
    },
    "currency": "USD",
    "display_name": "Festive jumper with dancing reindeer",
    "description": "Keep warm and look fashionable this festive season with this warm, stylish and festive jumper. Made in Lapland by elves!",
    "thumbnail": "https://media.example.com/i/ab1234_red_xl_2",
    "store_link": "https://store.example.com/product/ab1234_red_xl_2/",
    "stock": 32,
    "color": "red",
    "styles": "Casual|Loose|Generous",
    "categories": "festive|women|jumper|wool"
  }
]

These prices are imported into the product catalog using the cg_prices field set to field type jsonpricelist.

A corresponding group code is imported to the field person.cg for each customer, to tell the system that that person should see the price for their customer group.

Example

{
  "cg_prices": {
    "source_field_name": "prices",
    "field_type": "jsonpricelist"
  }
}

Reviews

If using the Social Proof module, it is also possible to import product ratings in a product import. This can be useful if Personalization does not have an integration with your review provider.

🚧

Before using this feature you must create a Product Review Import channel on the Ratings & Review Providers settings page.

Learn more in Import review data.

The following fields are used to provide review details for a product:

  • rid - Product review ID field, if neither the product ID or SKU values are suitable for this purpose.
  • reviews.rating - The average review rating for a product.
  • reviews.ratingCount - The number of reviews collected.

Example field mapping:

{
  "rid": {
    "source_field_name": "review_id"
  },
  "reviews.rating": {
    "source_field_name": "review_score",
    "field_type": "double"
  },
  "reviews.ratingCount": {
    "source_field_name": "review_count",
    "field_type": "int"
  }
}

Product recommendations filtering

🚧

Before adding custom data for product recommendation filtering

You must review the documentation on filtering before designing data structures to upload for filtering Product Recommendations.

We recommend using one of the following types of data when uploading for product recommendation filtering:

  • Tag values and tag groups
  • Promotion flags
  • Site brands
  • Price
  • Product ID
  • Stock level
  • Language
📘

If you need to upload custom fields for product filtering, contact your Customer Success representative or client support to discuss your requirements.

Location information

For products that are location-centric, such as a track day, spa session, and so on, you can attach location information to a product. This can take the form of a latitude and longitude, or a country code and postal code. When using postcodes, these are automatically resolved to a latitude and longitude and attached to the product.

You can specify one or more locations for a product. When we need to filter by location, Personalization finds the nearest location within the provided locations; optionally, you can specify a maximum distance in metres.

The following fields must be used within an object called location_ids to provide location details for a product:

  • location_type - The type of location information, one of:
    • latlng - Using a latitude and longitude.
    • postcode - Using postcode / zip code.
    • None specified - If directly setting location IDs during a product import without resolving from a latitude/longitude or a postal code.
  • For location type latlng only:
    • latitude_field_name - The field name holding the latitude coordinates.
    • longitude_field_name - The field name holding the longitude coordinates.
  • For location type postcode only:
    • postcode_field_name - The field name holding the postcode / zip code.
    • country_code_field_name - The country code for the postcode; must be a 2 letter upper case ISO 3166-1 Alpha-2 country code, for example, GB, FR, US, AU.
  • Optional parameters:
    • location_sets - Which location sets to resolve to, note mystores, and uk-cities system are automatically provided sets.
    • list_separator - What separator character you are using to separate values in the location_sets value.
    • max_distance - What is the maximum distance to consider a nearest location in metres.

Example mappings for each location type:

{
  "location_ids": {
    "latitude_field_name": "lat",
    "longitude_field_name": "long",
    "location_type": "latlng",
    "location_sets": "mystores|template:uk-cities",
    "list_separator": "|",
    "max_distance": 10000
  }
}
{
  "location_ids": {
    "postcode_field_name": "postcode",
    "country_code_field_name": "country",
    "location_type": "postcode",
    "location_sets": "mystores|template:uk-cities",
    "list_separator": "|"
  }
}
{
  "location_ids": {
    "source_field_name": "product_locations",
    "list_separator": "|"
  }
}