Onboarding New Products

Overview

If you have used the Products API and found that a product you wish to sell does not yet exist in the Zalando Catalog, you may add it using the Product Attributes API and the Product Submissions API.

The basic steps for onboarding a new product are:

  1. Determine which product outline to use.
  2. Use the Product Attributes API to get the outline.
  3. Begin creating a product submission JSON based on our template.
  4. Use the Product Attributes API to get details on the requirements for each attribute value that you will specify.
  5. Use the Product Submissions API to submit the product submission JSON to Zalando.

Warning

When you have submitted the product for (a) correcting mistakes or (b) by adding new Variants/Sizes to the Product, you must always resubmit the entire Product including all previous parts

  1. If we find any problems with your submission during validation, correct them and resubmit your product.
  2. Use the Product Status Report (PSR) to monitor the validation status of your product submissions.
  3. Once your product is approved, you may set price and available stock.

Note that this process may be run concurrently for many products at the same time. As soon as a product is approved, you may set its price and stock, and you do not need to wait for all products to be approved.

There are a lot of details to track in this process, so we have prepared a Products Onboarding Cheatsheet as a reference. It includes summaries of most of the main ideas and useful charts and resources.

It is important to note that in some cases a product attribute may be optional in the zDirect API, but you may be legally required to specify its value.

For example, some product specifications are required by law in the EU, such as declaring the use of certain material types in garments. The attributes that define those values may be optional.

Be sure that you understand the regulations pertaining to the products that you are selling, and that you are in compliance with all applicable laws.

Key Concepts

Product Outlines

A product outline (or product silhouette) is a JSON that enumerates all of the mandatory and optional attributes that are used to define a product of a particular type.

Each type of Zalando product (such as shirt or sandals) has a corresponding outline that includes all of its attributes. This allows us to set requirements for each product definition that are appropriate to its type. For example, the shirt outline includes neckline, while sandals outline includes heel_from.

The attributes in each outline are organized into three tiers: product_model, product_config, and product_simple.

Note

Each outline has a restriction on certain attributes that can be found under restricted_attributes.

restricted_attributes is a dynamic object and not shown when all values of an attribute are allowed. e.g. the attribute condition allows 2 different values on a global level. Both of them can be used within sandals. There's no restriction. The attribute washing_instructions allows 20 different values on a global level. However, within the outline sandals only 4 of them should be used. These 4 are shown in restricted_attributes.

For more information on the product data structure, see Understanding Products.

Product Outline Example

The following is the outline for the product model sandals:

  Click to show all sandals details

{
  "label": "sandals",
  "tiers": {
    "model": {
      "optional_types": [],
      "mandatory_types": [
        "target_age_groups",
        "target_genders",
        "name",
        "brand_code",
        "size_group"
      ],
      "restricted_attributes": []
    },
    "config": {
      "optional_types": [
        "condition",
        "color_code.secondary",
        "color_code.tertiary",
        "width",
        "shape",
        "decksohle",
        "material.filling",
        "futter",
        "heel_form",
        "insole_technology",
        "material_construction",
        "non_textile_but_animal_parts",
        "occasion",
        "padding_type",
        "pattern",
        "shoe_detail",
        "shoe_toecap",
        "shoe_width",
        "size_fits",
        "sole_material",
        "sport_qualities",
        "sport_shoe_details",
        "sport_shoe_insole",
        "sport_shoe_outer_sole",
        "sport_shoe_outer_sole_technology",
        "sport_type",
        "upper_material",
        "washing_instructions"
      ],
      "mandatory_types": [
        "color_code.primary",
        "media",
        "season_code",
        "supplier_color",
        "description"
      ],
      "restricted_attributes": [
        {
          "type": {
            "label": "washing_instructions",
            "version": "1.0.0"
          },
          "values": [
            "washing_instructions_4106",
            "washing_instructions_4107",
            "washing_instructions_6999",
            "washing_instructions_7858"
          ]
        },
        ...
      ]
    },
    "simple": {
      "optional_types": [
        "metric.heel_height",
        "metric.platform_height",
        "metric.schafthoehe",
        "metric.schaftweite"
      ],
      "mandatory_types": [
        "ean",
        "size_codes"
      ],
      "restricted_attributes": []
    }
  }
}

Product Submission JSON

Each product is submitted as a JSON payload or file with the Product Submissions API. Each product submission JSON must specify a single product with all of its product_config and product_simple variants.

The product outline shown above is similar to a submission JSON, but there are some differences in formatting and layout. For more information on the requirements for creating a product submission JSON, see Create a product submission JSON below.

Images

Each product submission requires a set of product images. Each product in the Zalando Catalog has one set of images. Different merchants may not use different sets of images for the same product.

For more information, see Images below.

Implementation Best Practice

The current process for submitting new products is somewhat complicated. It is possible to manually construct a product submission JSON, but doing so may be time consuming, especially if you have a large number of products to onboard.

We recommend building a UI layer on top of the Product, Product Attributes, and Product Submissions API to simplify the process. Reading through this section will help you understand how the process works, and how the APIs can be used in a custom solution.

Improvements to the product onboarding experience are currently in development.

Note

We recommend updating all attributes once a month, since they might change. For breaking changes though, we will reach out beforehand to your technical contacts in zDirect.

Sandbox Testing

The Products Attributes and Product Submissions APIs support sandbox mode.

Warning

Read operations in the sandbox and production environments will return different data. Regardless of the merchant, the sandbox environment provides all available outlines and attribute types, but only generic attribute values.

For more information, see the Sandbox section of the Product Attributes API Overview in our API Reference.

Warning

Product submissions made in the sandbox environment are not persisted or propagated. New products submitted in the sandbox will not be visible in your Product Status Report, and they will not be added to the Zalando Catalog.

Product submissions made during sandbox testing will be subjected to the first stage of automated validation as described in Submission and Validation. If you receive an HTTP 200 OK response upon sandbox submission, you can be confident that your JSON is well formed, that you did not omit any required attributes, and so forth. Additional validation only takes place in the production environment.

For more information, see the Sandbox section of the Products API Overview.

Step 0: Authentication

The zDirect API requires OAuth 2.0 authentication for all API calls. Use the Authentication API to generate access tokens as described in the Authentication section.

Step 1: Determine Which Outline to Use

The first step to product submission is deciding which product outline to use. We recommend starting with the Silhouette Guide Introduction in Zalando Partner University. From that page, you can also access specific guides.

Once you know which outline to use, you may get the outline using the Product Attributes API. If you are not certain which outline to use, you may get all outlines in one large file and browse through it to find the best fit.

Step 2: Get One or All Outlines

To get a specific outline, use the Products API:

GET /merchants/{merchant_id}/outlines/{outline_label}

An httpie request for the sandals outline looks like this:

http \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/outlines/sandals" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

You will receive the sandals model outline shown above in response.

You may also use the Product Attributes API to request all outlines available to your merchant account:

GET /merchants/{merchant_id}/outlines

Using httpie, you would send the following command:

http \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/outlines" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

The reply is a large JSON with dozens of outlines for different product models.

Step 3: Create a product submission JSON

Once you have the correct outline, you will build a JSON defining the product attributes.

The product outline enumerates all optional and mandatory attributes for your product type. Add each attribute that you specify to the submission template in the product_model_attributes, product_config_attributes, and product_simple_attributes tiers, as appropriate.

You will then use the Product Attributes API to gather more data on the requirements of each attribute value. For several examples of how to do this, see Examples below.

Warning

Any string values in the submitted JSON might have leading/trailing whitespace characters trimmed off.

This is to avoid scenarios where duplicate submissions are created because one of them has an extra space at the beginning/end.

Product Submission JSON Template

This template illustrates the basic structure of a product submission JSON. You may use it as a basis for constructing your submission file, or as a reference in writing your own code to generate submission JSON files.

  Click to show all JSON Template

{
  "outline":"$MODEL_LABEL",
  "product_model":{
    "merchant_product_model_id":"$YOUR_MERCHANT_PRODUCT_MODEL_ID",
    "product_model_attributes":{
      "name":"$MODEL_NAME",
      "brand_code":"$MODEL_BAND_CODE",
      ...
    },
    "product_configs":[
      {
        "merchant_product_config_id":"$YOUR_MERCHANT_PRODUCT_CONFIG_ID",
        "product_config_attributes":{
          "color_code.primary":"$CONFIG_COLOR_CODE.PRIMARY",
          "media":[
            {
              "media_path":"URL",
              "media_sort_key":"$SORT_KEY"
            },
            {
              "media_path":"URL",
              "media_sort_key":"$SORT_KEY"
            },
            {
              "media_path":"URL",
              "media_sort_key":"$SORT_KEY"
            }
          ],
          "season_code":"fs20",
          "supplier_color":"white",
          ...
        },
        "product_simples":[
          {
            "merchant_product_simple_id":"$YOUR_MERCHANT_PRODUCT_SIMPLE_ID",
            "product_simple_attributes":{
              "ean":"$EAN",
              ...
            }
          }
        ]
      }
    ]
  }
}

To see a full example of a valid submission, see Sample Submission JSON in our Products Onboarding Cheatsheet.

Step 4: Specify Attribute Values

Use the product outline to add all of the mandatory attribute types and any optional attribute types you wish to specify to your product submission JSON. Be sure to enter all mandatory types, and do not include any attribute type that is not in the outline you are using.

To provide attribute values, you have to first learn what the requirements are for the various types. Some values must be strings, for example, or integers, or values chosen from a list. Some attributes allow multiple values.

To find out more about those requirements, use the Product Attributes API.

Note

The description attribute at the config level accepts plain text only. HTML tags are not supported.

The attributes used for image submission and product size options are treated separately in their own sections below.

Warning

The description attribute map accepts only one a single entry (locale to description). This string description can be in any of the supported languages and has to be under the corresponding locale key This description will be displayed on zalando's website only in the country using this locale and no description will be displayed in all other sales channels. The description field is mandatory. Example of usage:

{ 
  "description": 
    { 
      "it": "..." 
    } 
}

Get Attribute Requirements

The Product Attributes API provides endpoints for learning more about each attribute.

Type Path Main Uses
GET ​/merchants​/{merchant_id}​/attribute-types​/{type_label} Return the schema for the specified attribute type.
GET ​/merchants​/{merchant_id}​/attribute-types​/{type_label}​/attributes Return all attributes of the specified attribute type.
GET ​/merchants​/{merchant_id}​/attribute-types​/{type_label}​/attributes​/{attribute_label} Return the specified attribute of the specified attribute type.

Begin with the following endpoint:

/merchants​/{merchant_id}​/attribute-types​/{type_label}

This will return a JSON schema that describes the attribute type in the following fields:

{
    "cardinality": "",
    "definition": {
        "type": ""
    },
    "description": {
        "en": ""
    },
    "label": "",
    "name": {
        "en": ""
    },
    "type_variants": [],
    "usage": ""
}

The fields can be interpreted as follows:

Field Description
cardinality Indicates if one or many responses are allowed.
definition The expected data type of the value.
description Any additional information about the attribute type.
label Other calls may reference the attribute type by referencing the value of this field.
name A human-readable description of the field for use in referencing the attribute type in front ends or UIs.
type_variants Some attribute types have variants that are independently defined, such as color_code.primary and color_code.secondary. An outline may only allow some of the possible variants.
usage Either literal or reference_by_label. For literal, enter a value. For reference_by_label, the specification takes a label value to specify the value.

Attribute Requirement Examples

Basic Example: name

Here is an example for the simple attribute type name:

GET merchants/$YOUR_MERCHANT_ID/attribute-types/name

This httpie command returns the type schema for name:

http \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types/name \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

The response:

{
  "label": "name",
  "name": {
    "en-gb": "name"
  },
  "type_variants": [],
  "cardinality": "one",
  "definition": {
    "type": "StringDefinition"
  },
  "usage": "literal"
}

Based on the schema information seen in the previous section, we can deduce the following:

  • label: API calls may reference this attribute as name.
  • name: This attribute type should be referred to as name in any UI or front end.
  • type_variants: The empty array tells us that no type variants exist for this attribute type.
  • cardinality: A single value is expected rather than a list.
  • definition: The expected data type of this attribute type is string.
  • usage: Any valid string may be used for this value. If a predefined value was required, this value would be reference_by_label instead of literal.

Based on this information, we can conclude that the expected attribute value for this type is free text. The following example shows a valid value for name in a submission JSON:

"name": "AIR FORCE SANDALS 1 '07 LV8 UTILITY"

reference_by_label Example: brand code

Many attribute values must be selected from a defined set or the JSON will fail validation. Such attributes always include "usage": "reference_by_label" in their schema.

brand_code is one example of a reference_by_label attribute. It is a product_model attribute that identifies the product brand.

As with name, we begin by using the following httpie command to request the schema:

http \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/brand_code" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

This is the response:

{
  "label": "brand_code",
  "name": {
    "en": "brand code"
  },
  "description": {
    "en": "Brand code is used to identify the Brand of the product"
  },
  "type_variants": [],
  "cardinality": "one",
  "definition": {
    "type": "StringDefinition"
  },
  "usage": "reference_by_label"
}

Note that the usage value is reference_by_label.

When you are working with a reference_by_label attribute, use the following endpoint to find out what values may be used:

​/merchants​/{merchant_id}​/attribute-types​/{type_label}/attributes

Using httpie:

http \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/brand_code/attributes" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

This sample reply is shortened for the sake of brevity:

{
   "items":[
      {
         "label":"ns1",
         "name":{
            "en":"Nike Sportswear"
         },
         "value":{
            "string":"ns1"
         }
      },
      {
         "label":"A55",
         "name":{
            "en":"adidas Consortium by Y's"
         },
         "value":{
            "string":"A55"
         }
      },
      {
         "label":"A56",
         "name":{
            "en":"adidas by Raf Simons"
         },
         "value":{
            "string":"A56"
         }
      },
      ...
   ]
}

To specify a brand_code in your product submission JSON, enter one of the available label values as the value. For example, to specify the Nike Sportswear brand, enter the following:

"brand_code": "ns1"

Example: target genders

The product_model attribute target_genders is also reference_by_label, so the attribute value must be selected from a list.

To request the type schema with httpie:

http \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/target_genders" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

In this case, our response is:

{
  "label": "target_genders",
  "name": {
    "en": "target genders"
  },
  "description": {
    "en": "Target genders"
  },
  "type_variants": [],
  "cardinality": "many",
  "definition": {
    "type": "StringDefinition"
  },
  "usage": "reference_by_label"
}

Note that the value of "cardinality" is "many". This tells us that a list of attribute values is required, although the list may contain only one member.

To get possible label values with httpie:

http \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/target_genders/attributes" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

That gives us the following response:

{
  "items": [
    {
      "label": "target_gender_male",
      "name": {
        "en": "target gender male"
      },
      "value": {
        "string": "target_gender_male"
      }
    },
    {
      "label": "target_gender_female",
      "name": {
        "en": "target gender female"
      },
      "value": {
        "string": "target gender_female"
      }
    }
  ]
}

To specify that a product is intended for any gender, enter the following into your submission JSON:

"target_genders": [
  "target_gender_male",
  "target_gender_female"
]

Type Variants Example: color_code.primary

The next mandatory config attribute attribute is color_code.primary.

We can immediately tell from the . in the type label that color_code.primary is a variant of the color_code type. All type variants of one attribute type uses the same schema, and differ only in the label.

To get the type schema with httpie:

http \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/color_code.primary" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

The response:

{
  "label": "color_code",
  "name": {
    "en-gb": "color_code"
  },
  "type_variants": [
    {
      "label": "primary",
      "name": {}
    },
    {
      "label": "secondary",
      "name": {}
    },
    {
      "label": "tertiary",
      "name": {}
    }
  ],
  "cardinality": "one",
  "definition": {
    "type": "LocalizedStringDefinition"
  },
  "usage": "reference_by_label"
}

Note that the API returned the schema for the more general color_code, which includes an array of type variants including color_code.primary, color_code.secondary, and more.

To use httpie to get more information on the attributes of this schema:

http \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/color_code/attributes" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

Here is an abbreviation of the long response, which contains the entire set of colors. Response filtering for attribute requests is not currently supported.

{
  "items": [
    {
      "label": "001",
      "name": {
        "en-gb": "001"
      },
      "value": {
        "localized": {
          "se": "vit",
          "fr": "blanc",
          "pt": "branco",
          "cs": "bílá",
          "it": "bianco",
          "nl": "wit",
          "de": "weiss",
          "sv": "vit",
          "da": "hvid",
          "en": "white",
          "es": "blanco",
          "fi": "valkoinen",
          "no": "hvit",
          "pl": "bialy"
        }
      }
    },
  ...
}

To set your primary color code to white in your submission JSON, add the following value, taken from the label field:

"color_code.primary": "001"

Optional Attribute Example: color_code.secondary

In many cases, the product outline includes optional attributes that you may not wish to specify. For example, assume you do not wish to specify the optional optional attribute color_code.secondary.

To decline to specify an optional type, simply leave the attribute type definition out of your submission JSON.

Complex Attribute Example: material.upper_material_clothing

The product_config attribute type material.upper_material_clothing defines the type of material that makes up the upper part of the product.

Like color_code, this attribute has multiple type variants. Using httpie, we could request its schema with this command:

http \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/material.upper_material_clothing" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

Or like this:

http \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/material" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

Either way, we will get the same long response with many type variants. This is an abbreviation:

{
    "cardinality": "many",
    "definition": {
        "type": "StructuredDefinition",
        "types": [
            {
                "label": "material_percentage",
                "optional": false
            },
            {
                "label": "material_code",
                "optional": false
            }
        ]
    },
    "label": "material",
    "name": {
        "en-gb": "material"
    },
    "type_variants": [
        ...
        {
            "label": "upper_material_clothing",
            "name": {
                "cs": "Materiál vnější látky",
                "da": "Materiale",
                "de": "Material Oberstoff",
                "en": "Outer fabric material",
                "es": "Material exterior",
                "fi": "päällikankaan materiaali",
                "fr": "Composition",
                "it": "Composizione",
                "nl": "Materiaal buitenlaag",
                "no": "Overmateriale",
                "pl": "Materiał",
                "pt": "material do tecido exterior",
                "ru": "",
                "sv": "Material",
                "tr": ""
            }
        },
        ...
        }
    ],
    "usage": "literal"
}

Note that the types field includes material_percentage and material_code. The attribute type material is a complex attribute type which consists of these two attributes.

Both of these component attributes are typical attribute types, and we can request their individual schemas like any other:

http \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/material_percentage" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

From the response we can see the attribute type material_percentage is simply a decimal:

{
  "label": "material_percentage",
  "name": {
    "en-gb": "material_percentage"
  },
  "type_variants": [],
  "cardinality": "one",
  "definition": {
    "type": "DecimalDefinition"
  },
  "usage": "literal"
}

To request the schema for the other component attribute material_code using httpie:

http \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/material_code" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

The response:

{
  "label": "material_code",
  "name": {
    "en-gb": "material_code"
  },
  "type_variants": [],
  "cardinality": "one",
  "definition": {
    "type": "LocalizedStringDefinition"
  },
  "usage": "reference_by_label"
}

And to request the attributes for material_code with httpie:

http \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/material_code/attributes" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

An abbreviated example response:

{
  "items": [
    {
      "label": "li",
      "name": {
        "en": "Linen"
      },
      "value": {
        "localized": {
          "fr": "lin",
          "pt": "linho",
          "cs": "len",
          "it": "lino",
          "nl": "linnen",
          "de": "Leinen",
          "sv": "lin",
          "da": "hør",
          "en": "linen",
          "es": "lino",
          "fi": "pellava",
          "no": "lin",
          "pl": "len"
        }
      }
    },
  ...

This is a valid example entry for material.upper_material_clothing in a product submission JSON:

"material.upper_material_clothing": [
  {
    "material_code": "li",
    "material_percentage": 97.50
  },
  {
    "material_code": "el",
    "material_percentage": 2.50
  }
]

Complex Attribute Example: sustainability certificate

Note

For more information on the sustainability certificate have a look at Sustainability.

Another complex attribute is sustainability certificate. It's composed of five fields:

  • certificate_info
  • certificate_test_institute
  • certificate_approval_number
  • certification_tier
  • product_component

Some are associated with strings, and others are associated with structured values. Some fields are mandatory and others are optional. To get to know the field types and their optionality, you need to query the Merchant Attributes service.

From the Merchant Attributes information (see sections below), it can be deduced that the certificate attribute's value is a json object with the following structure:

{
  "certificate_info": string,
  "product_component": {
    "variant": string,
    "certified_percentage": number
  },
  "certification_tier": string,
  "certificate_test_institute": string,
  "certificate_approval_number": string
}
click to show an example request body (to Submission Service) with a certificate attribute
{
  "outline": "shirt",
  "product_model": {
    "merchant_product_model_id": "...",
    "product_model_attributes": {},
    "product_configs": [
      {
        "merchant_product_config_id": "...",
        "product_config_attributes": {
          "media": [],
          "certificate": {
            "certificate_info": "home_labels_7848",
            "product_component": {
              "variant": "non_material_variant:full_product",
              "certified_percentage": 100
            },
            "certification_tier": "assembly_factory",
            "certificate_test_institute": "Control Union Certifications B.V.",
            "certificate_approval_number": "CU811380GRS-2021-00000000"
          },
          "description": {},
          "season_code": "",
          "supplier_code": "...",
          "color_code.primary": ""
        },
        "product_simples": []
      }
    ]
  }
}
certificate
click to see `attribute-types` request for `certificate`
http\
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/certificate\
"Authorization:Bearer $YOUR_ACCESS_TOKEN"
click to see `attribute-types` response for `certificate`
{
  "cardinality": "one",
  "definition": {
    "type": "StructuredDefinition",
    "types": [
      {
        "label": "certificate_info",
        "optional": false
      },
      {
        "label": "certificate_test_institute",
        "optional": true
      },
      {
        "label": "certificate_approval_number",
        "optional": true
      },
       {
        "label": "certification_tier",
        "optional": true
      },
      {
        "label": "product_component",
        "optional": true
      }
    ]
  },
  "label": "certificate",
  "name": {
    "hr": "Održivost",
    "lv": "Ilgtspējība",
    "et": "Jätkusuutlikkus",
    "de": "Nachhaltigkeit",
    "en": "Sustainability",
    "sk": "Udržateľnosť",
    "lt": "Tvarumas",
    "sl": "Trajnostnost"
  },
  "type_variants": [],
  "usage": "literal"
}
certificate.certificate_info:
click to see `attribute-types` request for `certificate_info`
http\
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/certificate_info\
"Authorization:Bearer $YOUR_ACCESS_TOKEN"
click to see `attribute-types` response for `certificate_info`
{
  "cardinality": "one",
  "definition": {
    "type": "LocalizedStringDefinition"
  },
  "label": "certificate_info",
  "name": {
    "fr": "Développement durable",
    "pt": "Sustentabilidade",
    "cs": "Udržitelnost",
    "it": "Sostenibilità",
    "nl": "Duurzaamheid",
    "de": "Nachhaltigkeit",
    "pl": "Produkt przyjazny dla środowiska"
  },
  "type_variants": [],
  "usage": "reference_by_label"
}

From the response you can see that certificate_info has definition of LocalizedStringDefinition, and it's usage is reference_by_label. This means that certificate_info can be assigned only certain values. These are returned by the attribute-types/certificate_info request:

click to see `attribute-types/attributes` request for `certificate_info`
http\
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types/certificate_info/attributes\
"Authorization:Bearer $YOUR_ACCESS_TOKEN"
click to see `attribute-types/attributes` response for `certificate_info`
{
  "items": [
    {
      "label": "home_labels_8311",
      "name": {
        "en": "home_labels_8311"
      },
      "value": {
        "localized": {
          "cs": "LENZING™ ECOVERO™",
          "da": "LENZING™ ECOVERO™",
          "de": "LENZING™ ECOVERO™",
          "pl": "LENZING™ ECOVERO™",
          "sk": "LENZING™ ECOVERO™",
          "sl": "LENZING™ ECOVERO™",
          "sv": "LENZING™ ECOVERO™"
        }
      }
    },
    {
      "label": "home_labels_5115",
      "name": {
        "en": "home_labels_5115"
      },
      "value": {
        "localized": {
          "cs": "Fairtrade Cotton",
          "da": "Fairtrade Cotton",
          "de": "Fairtrade Cotton",
          "sl": "Fairtrade Cotton",
          "sv": "Fairtrade Cotton"
        }
      }
    }
  ]
}

For example

    "certificate_info": "home_labels_8312"

Notice that the value for certificate_info is a label that represents a LocalizedStringDefinition.

certificate.certification_tier:

click to see attribute-types request for certification_tier

http\
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types/certification_tier\
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

click to see `attribute-types` response for `certification_tier`
{
  "cardinality": "one",
  "definition": {
    "type": "StringDefinition"
  },
  "label": "certification_tier",
  "name": {
    "en": "Certification tier"
  },
  "type_variants": [],
  "usage": "reference_by_value"
}

From the response you can see that certification_tier has definition of StringDefinition, and its usage is reference_by_value. This means that certification_tier can be assigned only certain values. These are returned by the attribute-types/attributes request:

click to see `attribute-types/attributes` request for `certification_tier`
http\
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types/certification_tier/attributes\
"Authorization:Bearer $YOUR_ACCESS_TOKEN"
click to see `attribute-types/attributes` response for `certification_tier`
{
  "items": [
    {
      "label": "assembly_factory",
      "name": {
        "de": "Assembly factory",
        "en": "Assembly factory"
      },
      "value": {
        "string": "assembly_factory"
      }
    }
  ]
}
certificate.certificate_test_institute:
click to see `attribute-types` request for `certificate_test_institute`
http\
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types/certificate_test_institute\
"Authorization:Bearer $YOUR_ACCESS_TOKEN"
click to see `attribute-types` response for `certificate_test_institute`
{
  "cardinality": "one",
  "definition": {
    "type": "StringDefinition"
  },
  "label": "certificate_test_institute",
  "name": {
    "hr": "Ispitivačko/certifikacijsko tijelo",
    "fr": "Institut de contrôle / certifié par",
    "sl": "Ustanova za preskušanje/certifikat izdal",
    "pl": "Instytut / certyfikat wydany przez"
  },
  "type_variants": [],
  "usage": "literal"
}

From the response you can see that certificate_test_institute has definition of StringDefinition, and its usage is literal. This means that any string value could be assigned to that attribute.

certificate.certificate_approval_number:
click to see `attribute-types` request for `certificate_approval_number`
http\
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types/certificate_approval_number\
"Authorization:Bearer $YOUR_ACCESS_TOKEN"
click to see `attribute-types` response for `certificate_approval_number`
{
  "cardinality": "one",
  "definition": {
    "type": "StringDefinition"
  },
  "label": "certificate_approval_number",
  "name": {
    "hr": "Broj certifikata/licence",
    "fr": "Certification / numéro de licence"
  },
  "type_variants": [],
  "usage": "literal"
}

From the response you can see that certificate_approval_number has definition of StringDefinition, and its usage is literal. This means that any string value could be assigned to that attribute.

certificate.product_component:

click to see attribute-types request for product_component

http\
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/product_component\
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

click to see `attribute-types` response for `product_component`
{
  "cardinality": "one",
  "definition": {
    "type": "StructuredDefinition",
    "types": [
      {
        "label": "variant",
        "optional": false
      },
      {
        "label": "certified_percentage",
        "optional": false
      }
    ]
  },
  "label": "product_component",
  "name": {
    "en": "Certified product component"
  },
  "type_variants": [],
  "usage": "literal"
}
certificate.product_component.variant:
click to see `attribute-types` request for `variant`
http\
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/variant\
"Authorization:Bearer $YOUR_ACCESS_TOKEN"
click to see `attribute-types` response for `variant`
{
  "cardinality": "one",
  "definition": {
    "type": "StringDefinition"
  },
  "label": "variant",
  "name": {
    "en": "Material or Non-Material variant"
  },
  "type_variants": [],
  "usage": "reference_by_value"
}

From the response you can see that variant has definition of StringDefinition, and its usage is reference_by_value. This means that variant can be assigned only certain values. These are returned by the attribute-types/attributes request:

click to see `attribute-types/attributes` request for `variant`
http\
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types/variant/attributes\
"Authorization:Bearer $YOUR_ACCESS_TOKEN"
click to see `attribute-types/attributes` response for `variant`
{
  "items": [
    {
      "label": "decksohle",
      "name": {
        "en-gb": "decksohle"
      },
      "value": {
        "string": "material_variant:decksohle"
      }
    },
    {
      "label": "full_product",
      "name": {
        "en-gb": "full_product"
      },
      "value": {
        "string": "non_material_variant:full_product"
      }
    }
  ]
}

Example:

    "variant": "non_material_variant:full_product"

Note, that for each product outline, only a subset of variants is allowed.

certificate.product_component.certified_percentage:

click to see attribute-types request for certified_percentage
http\
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types/certified_percentage\
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

click to see `attribute-types` request for certified_percentage
{
  "cardinality": "one",
  "definition": {
    "type": "DecimalDefinition"
  },
  "label": "certified_percentage",
  "name": {
    "en": "Certified percentage"
  },
  "type_variants": [],
  "usage": "literal"
}

Retrieve certificate

The submitted certificate can be retrieved using the PSR API.

Step 5 - Sizes

Sizes Overview

Use the size_group and size_code attributes to set all available sizes of your product.

The size_group product_model attribute specifies which category of size the product belongs to. For example, watches and shoes use different size groups, and indeed, different types of shoes use different size groups.

The size_code product_simple attribute specifies the actual size of each EAN (such as "size 42" or "XXL"). The size_code values available for your product will depend on what size_group it uses.

Both size_group and size_code are complex attribute types which consist of a mandatory size attribute and an optional length attribute.

The length attributes are only required for certain products like pants, which often have a waist size and a length. See size_group.length and size_code.length below for more information.

Size and length are both reference_by_value, and are therefore take label values.

The basic steps for setting sizes for your submission are:

  1. Get the attributes of the size attribute.
  2. Find the appropriate size group for your product.
  3. Add the corresponding size_group.size value to the product_model tier of your product JSON.
  4. For all simples in your submission JSON, find the appropriate size_code.size value in the size_group you chose and add the appropriate value to the product_simple tier of your JSON.
  5. If necessary, add the size_group.length value to the product_model tier of your product JSON, and size_code.length values to each EAN in the product_simple tiers.

Get the attributes of the size attribute

A key source of information for entering size values is the enumeration of attributes of the size attribute type. To get it with httpie, send the following call:

http \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/size/attributes" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

This call returns a large schema which defines all available size categories and size options for every available product type.

You may wish to write the returned JSON to a file for easier reference, as in this example:

http \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/attribute-types\
/size/attributes" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN" >> size_attributes.txt

This example shows a small part of the returned JSON:

{
  "items": [
    {
      "_meta": {
        "active": true,
        "dimension": {
          "value": "Shoe size",
          "type": "size",
          "name": "Shoes",
          "group": "Female",
          "comment": "Shoes, socks, knee socks, shoe trees",
          "category": "Shoes"
        },
        "sizes": [
          {
            "conversions": [
              {
                "cluster": "eu",
                "raw": "42"
              },
              {
                "cluster": "us",
                "raw": "11"
              }
            ],
            "supplier_size": "42",
            "sort_key": 18
          },
          {
            "conversions": [
              {
                "cluster": "eu",
                "raw": "44.5"
              },
              {
                "cluster": "us",
                "raw": "13"
              }
            ],
            "supplier_size": "44.5",
            "sort_key": 22
          },
          ...
        ]
      },
      "label": "4FE1000E0A",
      "name": {
        "en-gb": "4FE1000E0A"
      },
      "value": {
        "string": "4FE1000E0A"
      }
    },
    {
      "_meta": {
        "active": true,
        "dimension": {
          "category": "Clothing",
          "comment": "Pants, leggings, jeans, ...",
          "group": "Male",
          "name": "Clothing",
          "type": "size",
          "value": "Confection"
        },
        "sizes": [
          {
            "conversions": [
              {
                "cluster": "eu",
                "raw": "M"
              },
              {
                "cluster": "us",
                "raw": "M"
              }
            ],
            "sort_key": 7,
            "supplier_size": "M"
          },
          {
            "conversions": [
              {
                "cluster": "eu",
                "raw": "L"
              },
              {
                "cluster": "us",
                "raw": "L"
              }
            ],
            "sort_key": 9,
            "supplier_size": "L"
          },
          ...
        ]
      },
      "label": "4MU1000E2A",
      "name": {
        "en-gb": "4MU1000E2A"
      },
      "value": {
        "string": "4MU1000E2A"
      }
    },
    ...
  ]
}

This schema enumerates all size types for all size categories of products. Note that some size groups are brand specific.

Json can contain an empty array:

{
  "items": []
}
In this case attribute values are not configured. In case you might need any support, please reach out to partner-care@zalando.de

size_group.size

You must select a size_group for your product before setting the size_codes. The available size_codes options depend on which size_group you use.

First, use the dimension attributes meta-data in the size attributes enumeration to find the right size group for your product. We recommend beginning by searching for key words that describe your product, such as "pant" or "shoe", and look for corresponding values in fields such as dimension.name and dimension.comment.

Unfortunately, different manufacturers use different size chart conventions, so the set of size groups is not systematically organized. As a result, it is important to check the size attributes list carefully. If you believe you have found the right group, check the other remaining options anyway, just to verify that there is no better match.

Be sure that you select size values, and not length values. Size group enumerations look very similar to length group enumerations, except thedimension.type value is size instead of length, as in this example:

"_meta": {
        "active": true,
        "dimension": {
          "category": "Clothing",
          "comment": "Pants, leggings, jeans, ...",
          "group": "Male",
          "name": "Clothing",
          "type": "size",
          "value": "Confection"
        },

Once you have found the best possible match, enter the value of the label attribute of the group as the value of size_group.size in your submission JSON. For example, for the following size group:

 {
    "value": {
    "string": "4FA0AD5U5A"
    },
    "name": {
    "en-gb": "4FA0AD5U5A"
    },
    "label": "4FA0AD5U5A",
    "_meta": {
      "sizes": [
          {
        "supplier_size": "2",
        "sort_key": 10
          },
          {
        "supplier_size": "3",
        "sort_key": 11
          },
          {
        "supplier_size": "4",
        "sort_key": 12
          },
          ...
      ],
      "dimension": {
          "value": "Confection",
          "type": "size",
          "name": "Sport",
          "group": "Female",
          "comment": "",
          "category": "Sport"
      },
      "descriptions": {
        "en": "Sports, Women, sandals, adidas Performance, UK[2-10]"
      },
      "brand_code": "AD5",
      "active": true
    }
},

Enter the following label value to the product_model tier in your submission JSON:

"size_group": {
  "size": "4FA0AD5U5A"
}

size_code.size

Now that you have identified the size_group, it is easy to find the corresponding size codes. Simply add the value for the supplier_size field to the corresponding product_simple in your product submission JSON as shown below.

"size_codes": {
  "size": "2"
}

For example, suppose you have a size 2 sandals with the EAN 9780679762881. You would add the following definition to your submission JSON:

"product_simples": [
  {
    "merchant_product_simple_id": "sandals-1105AA",
    "product_simple_attributes": {
      "ean": "9780679762881",
      "size_codes": {
        "size": "2"
      }
    }
  },

Repeat this step for all product_simples in your submission.

size_group.length and size_code.length

Some products have more than one size code per simple. Many pants, for example, have a waist size and a length.

For these cases, there are additional size_group.length and size_code.length attribute types.

The process for entering the correct values for the size_group.length and size_code.length attribute types is basically the same as the process for finding the size attributes described above, except you will use length groups instead of size groups.

To begin, find the appropriate length group that matches your size group. Be sure that you select length values, and not size values. Length group enumerations are identical to size group enumerations, except the value of dimension.type is length instead of size:

"dimension": {
  "value": "Length",
  "type": "length",
  "name": "Pants/ trousers",
  "group": "Unisex",
  "comment": "Pants, leggings, jeans, sports pants ...",
  "category": "Clothing"
}

Once you have selected the best length group, enter the value of the label attribute of the group as the value of size_group.size in your submission JSON.

Here is an example product_model entry:

"size_group": {
  "size": "4MU1000E2A",
  "length": "5AAU000012"
}

For each product_simple, add the appropriate supplier_size value from the size enumeration as the value of size_codes.length.

Here is an example product_simple entry:

"size_codes": {
  "size": "42",
  "length": "52"
}

Size Attributes Reference Chart

Value Where it is defined in the size attributes enumeration
size_group.size For any size group where dimension.type = size, the value of label
size_code.size For any size group where dimension.type = size, the value of supplier_size
size_group.length For any size group where dimension.type = length, the value of label
size_code.length For any size group where dimension.type = length, the value of supplier_size

Step 6 - Images

Each product in the Zalando Product Catalog must have an accompanying set of required images, and each product must have one and only one set of images. Different merchants may not use different sets of images for the same product.

When submitting a new product to the Zalando Product Catalog, you must submit the required set if images.

The image submission process consists of the following steps:

  1. Prepare images meeting Zalando requirements,
  2. Host the image files at any publicly-available URLs, and
  3. In the product submission JSON, specify the image URLs as an array in the mandatory Config attribute type media.

During product submission validation, we will validate any provided links and download the pictures.

Image files cannot currently be uploaded directly to Zalando.

Image Requirements

Business Image Requirements

In order to maintain a high-quality and consistent presentation, we have provided a list of requirements that any product image must meet.

For detailed information on image requirements and business rules, see our Image and Content Guides in Zalando Partner University.

Technical Image Requirements

Value Requirement
Minimum size 762 * 1100 pixels
Recommended size 1524 * 2200 pixels
Maximum size 6000 * 9000 pixels
Image type JPEG
Color mode RGB
Format Upright

Host image files at any public URL

You may host your images at any public location (e.g. a public Dropbox).

Each image must be hosted at a unique URL. Do not enclose images in an archive.

Note

Do not remove images until the article is created (ASO status Blocked or Live).

Add image URL to the media field

The mandatory product_config attribute type media is a complex attribute type that consists of the attributes media_path and media_sort_key.

The media_path value takes a single valid URL, and the media_sort_key value takes a single integer that will be used to define the sort order of the image.

The following example illustrates a valid media field in a product submission JSON:

"media": [
  {
    "media_path": "https://hosting_of_your_choice/media/7b077fc4-fde3-47d4-8b25-97af8792/pic-1.jpg",
    "media_sort_key": 1
  },
  {
    "media_path": "https://hosting_of_your_choice/media/7b077fc4-fde3-47d4-8b25-97af8792/pic-2.jpg",
    "media_sort_key": 2
  }
]

Step 7 - Submission and Validation

Once you have completed constructing the submission JSON, use the Product Submissions API to submit it.

It is important that you add all product_config and product_simple tiers that exist for the product. For example, all size and color combinations must be included in your submission.

It is possible that a product model that you wish to sell already exists, but not every product simple of that model. In this case, you would need to resubmit the whole product structure with additional simples. See Products FAQ for assistance.

This is an example of a complete and valid product submission:

{
  "outline":"sandals",
  "product_model":{
    "merchant_product_model_id":"MODEL_ID_123",
    "product_model_attributes":{
      "name":"AIR FORCE SANDALS 1 '07 LV8 UTILITY",
      "brand_code":"ns1",
      "size_group":{
        "size":"4MU1000E2A"
      },
      "target_genders":[
        "target_gender_male",
        "target_gender_female"
      ],
      "target_age_groups":[
        "target_age_group_adult"
      ]
    },
    "product_configs":[
      {
        "merchant_product_config_id":"7b077fc4-fde3-47d4-8b25-97af8792",
        "product_config_attributes":{
          "color_code.primary":"001",
          "description":{
            "en":"Nice sandals"
          },
          "material.upper_material_clothing":[
            {
              "material_code":"li",
              "material_percentage":97.5
            },
            {
              "material_code":"el",
              "material_percentage":2.5
            }
          ],
          "media":[
            {
              "media_path":"https://hosting_of_your_choice/media/7b077fc4-fde3/pic-1.jpg",
              "media_sort_key":1
            },
            {
              "media_path":"https://hosting_of_your_choice/media/7b077fc4-fde4/pic-2.jpg",
              "media_sort_key":2
            }
          ],
          "season_code":"fs20",
          "supplier_color":"white"
        },
        "product_simples":[
          {
            "merchant_product_simple_id":"white-shoes-1105AA",
            "product_simple_attributes":{
              "ean":"9780679762881",
              "size_codes":{
                "size":"42"
              }
            }
          },
          {
            "merchant_product_simple_id":"white-shoes-2216BB",
            "product_simple_attributes":{
              "ean":"9780679763992",
              "size_codes":{
                "size":"44.5"
              }
            }
          }
        ]
      },
      {
        "merchant_product_config_id":"7b077fc4-fde3-47d4-8b25-97af8793",
        "product_config_attributes":{
          "color_code.primary":"608",
          "description":{
            "en":"Nice sandals"
          },
          "material.upper_material_clothing":[
            {
              "material_code":"li",
              "material_percentage":87.5
            },
            {
              "material_code":"el",
              "material_percentage":12.5
            }
          ],
          "media":[
            {
              "media_path":"https://hosting_of_your_choice/media/7b077fc4-fde3-47d4-8b25-97af8793/pic-1.jpg",
              "media_sort_key":1
            },
            {
              "media_path":"https://hosting_of_your_choice/media/7b077fc4-fde3-47d4-8b25-97af8793/pic-2.jpg",
              "media_sort_key":2
            }
          ],
          "season_code":"fs20",
          "supplier_color":"mint"
        },
        "product_simples":[
          {
            "merchant_product_simple_id":"mint-shoes-3326CC",
            "product_simple_attributes":{
              "ean":"9813752182012",
              "size_codes":{
                "size":"44.5"
              }
            }
          }
        ]
      }
    ]
  }
}

To submit the file, navigate to the directory where it exists and use the Product Submissions API:

POST /merchants/{merchant_id}/product-submissions

This httpie command submits the file product.json in the local directory:

http POST \
https://api-sandbox.merchants.zalando.com\
/merchants/$YOUR_MERCHANT_ID/product-submissions" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN" < product.json

Submission Validation and Product Status Reports

Immediately upon submission, the zDirect API will perform the first step of validation to verify that it is well formed and contains values for all mandatory attribute types.

If your JSON submission is valid, you will receive the following response:

200 OK

This is the only confirmation you will get at this stage, but if you receive a 200 response, you can be certain that the submission has been received and has passed initial validation.

Once submitted, your product will undergo additional automated and manual validation. It will only be added to the Zalando Catalog when all validation steps are successfully completed.

Use the Product Status Report (PSR) to track the status of any submitted product. PSRs provide realtime status for all products, and will provide information on any issues that may be found during validation. PSRs are available through the zDirect UI.

Once the product is added to the Zalando Catalog, you may use the Prices API to set your price per item per sales channel, and the Stocks API to set available stock.

If your JSON does not pass the initial validation, you will receive an error code with additional information.

For example, if you neglect to specify a value for the mandatory name attribute, you will receive the following reply:

{
    "title": "Bad Request",
    "flow_id": "rihm6p+EBC3G0Bxc",
    "detail": "Wrong body format",
    "contact": "zdirect-tech-support@zalando.de",
    "code": 400,
    "body_errors": [
        {
            "path": "product_model/product_model_attributes/name",
            "expected": "String",
            "actual": "Undefined"
        }
    ]
}

Step 8: Resubmit the product, if necessary

If your submission is rejected, you may correct any errors and repeat the submission process to re-submit it.

Warning

It is important to highlight that the service does not keep a history of your submissions, therefore, all information needs to be sent over again. Only product_configs or product_tiers included in the last successful request will be submitted for evaluation.

If you receive the error response code 422, then your grouping of Model / Config / Simple is not the same as that of existing products in the Zalando Catalog. Please reach out to zDirect Technical Support team with X-Flow-Id header and the response body. For contact information, see Support.

Additional Resources

Contact Support