Onboarding New Products
Overview
If you 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:
- Determine which product outline to use.
- Use the Product Attributes API to get the outline.
- Begin creating a product submission JSON based on our template.
- Use the Product Attributes API to get details on the requirements for each attribute value that you will specify.
- Use the Product Submissions API to submit the product submission JSON to Zalando.
Warning
When you submit a product for (a) correcting mistakes or (b) adding new Variants/Sizes, you must always provide the entire product including all its new and existing Variants/Sizes.
- If we find any problems with your submission during validation, correct them and resubmit your product.
- Use the Product Status Report (PSR) to monitor the validation status of your product submissions.
- 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.
Legal and Regulatory Requirements
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.
For more information on the product data structure, see Understanding Products.
Restricted Attributes
Note
Each outline has a restriction on certain attributes that can be found under restricted_attributes
.
The restricted_attributes
is a dynamic object and not shown when all values of an attribute are allowed. For example, the attribute condition
allows 2 different values on a global level. Both of them can be used within sandals without 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
.
Validation Hints
Note
Currently, this feature is visible only for select merchants as a pilot.
validation_hints
is a field containing hints about attributes on a particular tier of the outline. Currently, it can hint on the "Mandatory If Applicable" attributes. Generally, "mandatory if applicable" attributes are mandatory, but depending on your product this attribute may not apply. In that case, a special value not_applicable
can be supplied, which will indicate this during the submission validation process.
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"
]
},
...
],
"validation_hints": {
"material.filling": {
"hint_type": "mandatory_if_applicable",
"description": {
"en": "Please specify the material composition if the product has filling."
},
"related_types": []
},
...
}
},
"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 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 has many steps. 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. 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.
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. Once you know which outline to use, you may get the outline using the Product Attributes API.
Step 2: Get One or All Outlines
To get a specific outline, use the Products API. 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. 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 a set 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 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"
}
],
"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. The attributes used for image submission and product size options are treated separately in their own sections below.
Note
The description
attribute at the config
level accepts plain text only. HTML tags are not supported.
Warning
The description
attribute map accepts only individual locale to description entries.
It can be in any of the supported languages and has to be keyed by its corresponding locale.
This description will only be displayed at Zalando stores from countries using this locale.
The description field is mandatory and looks like:
{
"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. |
Their responses will be JSON objects describing the attribute and they types using the following fields:
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 Requirements Examples
Basic Example: name
Here is an example for the simple attribute type name
using the httpie command:
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 asname
.name
: This attribute type should be referred to asname
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 isstring
.usage
: Any valid string may be used for this value. If a predefined value was required, this value would bereference_by_label
instead ofliteral
.
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, call the following endpoint to find out
what values may be used using httpie:
http \
https://api-sandbox.merchants.zalando.com/merchants/$YOUR_MERCHANT_ID/attribute-types/brand_code/attributes" \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"
Here is an abbreviation of the long response:
{
"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 color_code.secondary
attribute,
you can leave its 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 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 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"
}
Attribute 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"
}
Attribute 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"
}
Attribute 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"
}
Attribute 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"
}
Attribute 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_percentagehttp\
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 product_model size_group
attribute specifies which category of size the product belongs to. For example, watches and shoes use different size groups.
The product_simple size_code
attribute specifies the actual size of each EAN (such as "size 42" or "XXL"). The available size_code
values for your product will depend on what size_group
it uses for the product_model.
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:
- Get the attributes of the
size
attribute. - Find the appropriate size group for your product.
- Add the corresponding size_group.size value to the product_model tier of your product JSON.
- 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.
- 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
Click to see an example of 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": []
}
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 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.
Click to see a submission JSON from the example above
{
"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
, you can find the corresponding size codes. 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 can have only one set of images. Different merchants may not use different sets of images for the same product.
When submitting a new product to Zalando, you must submit the required set of images. This submission process consists of the following steps:
- Prepare images meeting Zalando requirements,
- Host the image files at any publicly-available URLs, and
- 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 and download the images from the provided URLs.
Image files cannot currently be uploaded directly to Zalando.
Image Requirements
In order to maintain a high-quality and consistent presentation, we have technical requirements that any product image must meet:
Requirement | Value |
---|---|
Minimum size | 762 * 1100 pixels |
Recommended size | 1524 * 2200 pixels |
Maximum size | 6000 * 9000 pixels |
Image type | JPEG |
Color mode | RGB |
Format | Upright |
For detailed information on more image requirements and business rules, see our Image and Content Guides in Zalando Partner University.
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 while the article is in In Review or Rejected ASO status.
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 in a single submission containing all size and color combinations.
In case you wish to sell a product model that already exists, but it does not contain product simples that you need, you will need to resubmit the whole product structure with the additional simples. See Products FAQ for assistance.
Click to see 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-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 a JSON file, navigate to the directory where it exists and use the Product Submissions API.
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
While handling a submission request, we perform the first validation steps to verify that the provided JSON object is well-formed and contains values for all mandatory attributes.
If you receive a 400 Bad Request
response, it means that your JSON does not pass our initial validation.
For example, if you neglect to specify a value for the mandatory name
attribute, you will receive:
{
"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"
}
]
}
From this response, entries in body_errors
explain why the submission was not accepted. You need to
address them, adjust the submission and retry.
If you receive a 422 Unprocessable Entity
response, then your grouping of Model / Config / Simple is not the same as that of existing products in the Zalando Catalog. Please reach out to our Support team with X-Flow-Id
header and the response body. For contact information, see Support.
If you obtain a 200 OK
response, it means your submission has passed initial validation and was received, but it does not mean that the product will be created yet. The Submission may later be rejected and assigned PS_ERR errors, which can be inspected in ZDirect Articles.
Product Submission Validation (Jan 2025 release)
From mid-January 2025, the Submission API will be updated. Although the overall behaviour will remain same, there will be bug fixes, and improvement to the error messages. There will also be warnings that will indicate if there is a problem with optional attributes that leads them to be ignored from the submission, or that a problem that will lead to PS_ERR errors.
In the response, in addition to body_errors
, body_warnings
may be present.
Please refer to the following documentation for detailed information: Submissions API Release 2025: Validation
Step 8: Resubmit the product, if necessary
Once submitted, your product will undergo additional validations. It can still be rejected and it will only be added to the Zalando Catalog when all validation steps succeed. Use the Product Status Report (PSR) to track the status of any submitted product along with information on any issues that may be detected with further validations. PSR is also available through the zDirect UI.
Once the product is added to the Zalando Catalog, you may use the Prices API to set prices, and the Stocks API to set available stock.
If your submission failed further validations and was rejected, you may correct any errors and repeat the submission process to re-submit it.
Warning
We not keep a history of your submission attempts. The complete submission object must be sent again and only data included in the last successful request will be sent for further validation.
Additional Resources
- Products Onboarding Cheatsheet: A reference with a summary of major topics, a description of all related APIs, a glossary of key terms, a product submission JSON template and full example, and example outline, and more.
- The API Reference provides information on scopes, rate limiting, and sandbox behavior, and an OpenAPI reference for each API.