Updating Prices
Overview
Use the Prices API to set or update the price of any article in the Zalando Catalog.
Prices must be specified for each product_simple or EAN. Prices are set separately for each sales channel in which the article is available for sale (such as zalando.de or zalando.co.uk).
You may optionally set a promotional price to alert customers that an article is on sale and you may also optionally provide schedules (with specific start and end times) for each article.
Price updates go through a pipeline that validates and eventually processes them, leading to the new prices being visible in the store. The Price API only performs basic pre-validation and a complete price validation is performed asynchronously. This means the Price API does not wait on the result of the validation to respond to requests, so having a price update accepted by the API does not mean it will pass the full set of validations.
To check the results of price validations we provide the Manage Prices UI in zDirect. It allows you to see the latest price updates that have been fully processed, which have raised warnings or errors, and those which are still waiting to be processed. Alternatively, you can connect to the Price Reporting API.
The Prices API is write-only. To get the current price of a product, use the Product Status Report in zDirect.
Price API specification
-
Prices API reference: Information on scopes, rate limiting, and sandbox behavior.
-
OpenAPI reference for the Prices API.
Non-Euro Currency
For all sales channels that use a currency other than the euro (EUR), you must convert all prices to the target currency yourself and submit the converted value as the price. The zDirect Platform does not perform any currency conversion.
Different currencies can be subject to a different set of rules on the validation pipeline. To guarantee a good customer experience, we recommend submitting EUR prices first before submitting non-EUR prices.
Czech Koruna (CZK)
Prices should not have decimal subunits other than ,00 (e.g. 750,00 or 1300,00).
Hungarian Forint (HUF)
Prices should be in incremental steps of 5 (e.g. 12000 or 20105) and not have decimal subunits other than ,00 (e.g. 12000,00 or 20105,00).
Update the Price of an Article
There are two steps to update article prices:
- Create a price update JSON to specify the updates you wish to make, and
- Submit the JSON file to zDirect with the Prices API.
If the price update is submitted for an EAN which already exists in the Zalando Catalog, the price update is immediately sent to be validated. If the EAN is not in the Zalando Catalog, the price update will be held and passed on to be validated once the article is associated with a Zalando SKU (waiting room concept). To check the status of an EAN, use the Products API as described in Checking if an Article Exists in the Zalando Catalog. After validation, prices are propagated to the fashion store if no problem was identified, otherwise, they must be fixed accordingly (see Price Validation System for more information).
Create a Price Update JSON
Prices may be set per article or in batch updates. A single price update JSON may include up to 1,000 EANs for a single Merchant ID.
This is the basic structure of the prices update JSON:
{
"product_prices": [
{
"ean": "$EAN_1",
"sales_channel_id": "$SALES_CHANNEL",
"regular_price": {
"amount": $AMOUNT,
"currency": "$CURRENCY_CODE"
}
},
{
"ean": "$EAN_2",
"sales_channel_id": "$SALES_CHANNEL",
"regular_price": {
"amount": $AMOUNT_1,
"currency": "$CURRENCY_CODE"
},
"promotional_price": {
"amount": $AMOUNT_2,
"currency": "$CURRENCY_CODE"
},
"scheduled_prices": [
{
"regular_price": {
"amount": $AMOUNT_3,
"currency": "$CURRENCY_CODE"
},
"promotional_price": {
"amount": $AMOUNT_4,
"currency": "$CURRENCY_CODE"
},
"start_time": "$START_TIME",
"end_time": "$END_TIME"
}
]
}
]
}
Price Update JSON Requirements
General Requirements
- One JSON may include a maximum of 1,000 price entries on
product_prices
. - The price updates must all be for a single Merchant ID.
- Except for the
promotional_price
andscheduled_prices
fields, all the other fields and values are mandatory. - Each combination of
ean
andsales_channel_id
in theproduct_prices
list must be unique.
EAN
The ean
of the article should already exist in the Zalando Catalog. In
case the ean
does not exist in the Zalando Catalog, the price update
is delayed until the ean
is added to the Catalog.
Sales Channel ID
Use the Sales Channels API to get the available sales channels for a merchant. For more information, and for a list of sales channels codes, see Sales Channels API.
Regular Price
- The value of
amount
must be greater than 0. - The value of
currency
must be one of the following ISO 4217 currency codes:
Currency | ISO 4217 Currency Code |
---|---|
Euro | EUR |
Swiss Franc | CHF |
Polish Złoty | PLN |
Norwegian Krone | NOK |
Swedish Krona | SEK |
Danish Krone | DKK |
Pound Sterling | GBP |
Czech Koruna | CZK |
Romanian Leu | RON |
Hungarian forint | HUF |
Warning
The currency MUST correspond to the country you are attempting to set the price in, otherwise your price update will be rejected on validation process!
Promotional Price
For each article per sales channel, you may set a promotional price
in addition to the regular price by including the promotional_price
field in addition to the regular_price
value.
Setting a value for promotional_price
makes the following changes to
how the article is displayed:
- The article shows the regular price crossed out with the sales price listed in red.
- The percentage reduction from the regular price is displayed near the price.
- The article will be visible in the "Sale" section of the Zalando Fashion Store.
If this price update was not part of a schedule, then when the promotional
period has ended, you must set the article back to its standard price by
submitting a new update with the regular_price
field entered as normal,
and with no promotional_price
field.
The promotional_price
field has the following requirements:
- The promotional price
amount
value must be greater than 0. - The difference between the promotional price and the regular price must be at least
0.01
. - The promotional price must be less than the regular price.
- The promotional price must have the same currency type as the regular price.
Scheduling
By using the scheduling feature you can steer when and for how long the
price of your article should be online. Each article in the request
can have a list of scheduled prices associated with it. A schedule
contains a regular_price
and an optional promotional_price
. It must
have a start_time
, but it is optional to provide and end_time
. If no
end_time
is provided, then the scheduled price will remain active until
it is replaced by another price update or overwritten by another schedule.
start_time
and end_time
must be in ISO-8601 extended date-time
format with an offset from UTC, as defined by RFC 3339, section
5.6, with a
resolution up to a microsecond. Examples: "2021-02-02T16:30:15.000Z"
,
"2021-02-02T17:30:15.000+01:00"
.
Submitting a new price update for an EAN overrides all the existing schedules with the ones provided in the new update. This means that sending a new price update without any schedules will remove any existing schedules for the EAN.
If the base price of the price update is rejected due to being invalid or if the update fails to be applied due to an internal error, then all the schedules will be rejected too and will not be applied.
If one schedule is rejected due to being invalid, then all the schedules will be rejected too and will not be applied.
- The maximum number of schedules per article is 3.
- The
regular_price
andpromotional_price
must follow the same rules described above. - The
start_time
must be a least 120 minutes after the price update request submission time. - There must be a minimum of 60 minutes between any 2
start_time
s provided. - As a
start_time
you can only use a date/time in the future, not from the past. - If an
end_time
is provided, there must be a minimum of 60 minutes between thestart_time
and theend_time
. - If an
end_time
is provided, it can't be younger than thestart_time
Price Update Results
Once our API has accepted your price updates, they will go through additional validations and their results can be retrieved using several methods. Please refer to Price Validations for more information.
Price Update JSON Example
This example illustrates a JSON that would update the price of two EAN in the same sales channel. The first EAN contains one schedule and the second EAN contains a promotional price:
{
"product_prices": [
{
"ean": "5901234123457",
"sales_channel_id": "01924c48-49bb-40c2-9c32-ab582e6db6f4",
"regular_price": {
"amount": 89.95,
"currency": "EUR"
},
"scheduled_prices": [
{
"regular_price": {
"amount": 89.95,
"currency": "EUR"
},
"promotional_price": {
"amount": 50,
"currency": "EUR"
},
"start_time": "2020-05-01T14:00:00Z",
"end_time": "2020-05-05T22:00:00Z"
}
],
"ignore_warnings": false
},
{
"ean": "6661234123457",
"sales_channel_id": "01924c48-49bb-40c2-9c32-ab582e6db6f4",
"regular_price": {
"amount": 59.95,
"currency": "EUR"
},
"promotional_price": {
"amount": 24.95,
"currency": "EUR"
},
"ignore_warnings": false
}
]
}
Use the Prices API to POST the JSON
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.
Submit the JSON
Use the Prices API to submit the JSON:
POST /merchants/{$MERCHANT_ID}/prices
The following httpie command will POST the file price_update.json
to zDirect:
http POST \
https://api-sandbox.merchants.zalando.com\
/merchants/e18e458a-de38-40ee-8119-4130eed7486a/prices \
"Authorization:Bearer $YOUR_ACCESS_TOKEN" \
< price_update.json
Response: Successful
After successful execution of the POST, you receive an HTTP 207
response code. This multi-status response provides a status
, code
,
and optional description
value for every price update in the request.
Note
A 207
response cannot be taken in itself as an indication of success.
You may receive a 207
response to submissions with errors.
The status
value following each entry on product_prices
field must be separately parsed.
Here is an example response:
{
"results": [
{
"product_price": {
"ean": "5901234123457",
"sales_channel_id": "01924c48-49bb-40c2-9c32-ab582e6db6f4",
"regular_price": {
"amount": 89.95,
"currency": "EUR"
},
"scheduled_prices": [
{
"scheduled_price": {
"regular_price": {
"amount": 89.95,
"currency": "EUR"
},
"promotional_price": {
"amount": 50,
"currency": "EUR"
},
"start_time": "2020-05-01T14:00:00Z",
"end_time": "2020-05-05T22:00:00Z",
"status": "ACCEPTED",
"code": 0,
"description": null
}
}
],
"ignore_warnings": false
},
"status": "ACCEPTED",
"code": 0,
"description": null
},
{
"product_price": {
"ean": "6661234123457",
"sales_channel_id": "01924c48-49bb-40c2-9c32-ab582e6db6f4",
"regular_price": {
"amount": 59.95,
"currency": "EUR"
},
"promotional_price": {
"amount": 24.95,
"currency": "EUR"
},
"scheduled_prices": [],
"ignore_warnings": false
},
"status": "ACCEPTED",
"code": 0,
"description": null
}
]
}
The status
value ACCEPTED
indicates that the price update is
queued, and will be applied if the EAN
exists in the Zalando Catalog and is valid,
otherwise it will be queued until the EAN
is added to the Catalog,
and then validated and applied.
Warning
Price updates can take up to 60 minutes to be applied, depending on the load. There might be situations when we are experiencing a higher load than usual, which causes the time for price updates to be applied to exceed 60 minutes. This happens approximately once or twice a month.
Response: Unsuccessful
400 (Bad Request)
You will receive an HTTP 400 (Bad Request)
response in the following circumstances:
- One or more required fields are missing
- The
product_prices
list in the request body is empty - The
product_prices
list in the request body includes more than 1,000 items - The JSON includes one or more duplicates of a combination of
ean
andsales_channel_id
.
207
Most other invalid submissions are rejected with a multi-status HTTP
207
response code which enumerates the reason for rejection.
In this example, a price update reuqest was rejected because the regular price amount was zero:
{
"results": [
{
"product_price": {
"ean": "5901234123457",
"sales_channel_id": "01924c48-49bb-40c2-9c32-ab582e6db6f4",
"regular_price": {
"amount": 0,
"currency": "EUR"
},
"scheduled_prices": [],
"ignore_warnings": false
},
"status": "REJECTED",
"code": 101,
"description": "Regular price amount 0 is not greater than 0."
}
]
}
In this example, a base price update request was accepted, but the schedules were rejected because one of the schedules had a duration that was too short:
{
"results": [
{
"product_price": {
"ean": "5901234123457",
"sales_channel_id": "01924c48-49bb-40c2-9c32-ab582e6db6f4",
"regular_price": {
"amount": 70,
"currency": "EUR"
},
"promotional_price": null,
"scheduled_prices": [
{
"scheduled_price": {
"regular_price": {
"amount": 70,
"currency": "EUR"
},
"promotional_price": {
"amount": 60,
"currency": "EUR"
},
"start_time": "2020-08-01T14:00:00Z",
"end_time": "2020-08-01T14:05:00Z",
"status": "REJECTED",
"code": 101,
"description": "Schedule duration is too short. Provided duration: 5 minutes. Minimum allowed schedule duration: 60 minutes."
}
},
{
"scheduled_price": {
"regular_price": {
"amount": 70,
"currency": "EUR"
},
"promotional_price": {
"amount": 50,
"currency": "EUR"
},
"start_time": "2020-08-01T16:00:00Z",
"end_time": "2020-10-05T17:00:00Z",
"status": "REJECTED",
"code": 101,
"description": "There was at least one invalid schedule, so all schedules will be rejected."
}
},
{
"scheduled_price": {
"regular_price": {
"amount": 70,
"currency": "EUR"
},
"promotional_price": {
"amount": 40,
"currency": "EUR"
},
"start_time": "2020-08-01T18:00:00Z",
"end_time": "2020-10-05T19:00:00Z",
"status": "REJECTED",
"code": 101,
"description": "There was at least one invalid schedule, so all schedules will be rejected."
}
}
],
"ignore_warnings": false
},
"status": "PARTIALLY_ACCEPTED",
"code": 105,
"description": "Update Partially Successful: Base Price accepted, check scheduled_prices field for scheduled price update results"
}
]
}
When price updates are rejected, it usually indicates there is something
wrong with the request (as specified in the description
field). However,
price updates can also sometimes be rejected with code 102
. This
indicates that an internal error occurred in the Prices API. In that
case, it is advised to wait at least an hour and then try to resubmit the price update.