Bol.com Retailer API migration guide from v2 to v3

At bol.com we are working hard to help our partners grow their business every day. One way how we do that is by innovating on partner tooling functionalities in our seller dashboard, but also in the Retailer API channel. Our latest innovations are that significant that we introduce a new version, Retailer API v3.

So what’s in it for you?

  • Volume discount; use bundle pricing to sell multiple items at once
  • Returns
    • You can now see your handled returns and the Fulfilment by bol.com returns
    • You can create returns yourself
  • The offer flow has become much simpler and provides better feedback on your actions
  • Improved stock management
  • The possibility of independent stock, price and offer management
  • Partner Performance insights
  • Coming soon (summer 2020):
    • Product Content
    • Insights

Technically, the API has seen a complete overhaul to make it more consistent, user-friendly and ready for any future innovations.

Guide set-up

To guide you through the right steps and take important changes into account, you can use this  migration guide. Changes mentioned are compared to the v2/v2.1 versions. All information used is available on developers.bol.com, which is why we will link to several other pages in this guide.

We will first go through some general changes and will then guide you through all changes per component in prioritized order.

Components

1.      General changes

2.      Offers

3.      Orders / Shipments

4.      Cancellations

5.      Returns

6.      Invoices

7.      Lvb / FBB

8.      Partner Performance

9.      Insights (beta)

10.    Product content (beta)

 

1.      General changes

1.1 Process status

You can find all process status info here: https://developers.bol.com/apiv3processstatus/

1.2 Authentication

For v3 we changed to the Oauth 2.0 standard for authentication. Follow the steps mentioned on this page to get your new API credentials: https://developers.bol.com/apiv3authentication/

2. Offers

2.1  Offer Vision

The v3 doesn’t support bulk offer updates, but works with singles. Here we explain why we chose this route.

There’s an additional price to pay when it comes to large bulk updates, as they are heavier for our internal infrastructure, causing request and processing times to be considerably longer.

In addition, the semantics of a bulk request need to be well defined, something which isn’t always immediately clear when sending bulk updates. Meaning: how can you properly communicate failure/success scenarios? When is a bulk update considered successful, when all updates succeed or de we just check for individual update successes? We want to provide explicit feedback regarding offer updates/creations/deletions to be consistent with the rest of the API, whereas the v2 version was more of the fire-and-forget variety. This was easier to do in singles.

When dealing with consistency this is also something we wanted to keep in mind, we do not offer bulk updates anywhere else in the API at this time, so adding them for this particular case would be a departure from our conventions.

Finally, it is worth noting that we are aware that some updates are occurring more often than others. We see users create offers, and update the specifics far less than they are updating stock and/or price information. This is why we separated out these endpoints, so we can more efficiently handle these updates as stock and price updates are relatively cheap, where creation and structural updates of offers are not trivial. This is not the main reason for creating separate endpoints for these actions, there are also partners that integrate with the API that have requested these separate endpoints so they do not need to provide all offer details when they simply want to update stock.

2.2 Asynchronous process for offers on V3.

With the introduction of the Retailer API v3 we have added an asynchronous feedback flow for multiple Offer related requests. This asynchronous flow makes use of the process status request that allows you to poll the status and result of your request.

This flow allows you to check whether your requests have been successfully processed in our systems. If the request failed on our end then we provide an explanation. A ‘202 accepted’ response only indicates that the request was technically valid and that our systems are going to process the request. It in no way indicates if the requested process actually succeeded or not.

This is an improvement in regards to the Retailer API v1 and v2 as those versions did not provide the means to check the status of your requests.

The asynchronous flow is also vital in the Create Offer flow as it is needed to retrieve your Offer ID’s. These Offer ID’s are required for the update and delete offer requests. More information on the retrieval of Offer ID’s can be found below.

Suggested use:

We advise you to use the process status request for all requests which are aimed at creating, updating or deleting offers. Every request will return a Process Status ID with which you can poll the status.

2.3 Retrieval of Offer ID’s

A important change compared to the v2 is the (re-)introduction of Offer ID’s which are required to update or delete your offers. Without an offer ID you cannot alter or remove your offers on the Retailer API v3.

There are several methods for the retrieval of your offer ID’s of which the V3 Offer Export is most suited for an initial load when you’re migrating to the v3 and already have offers in your assortment.

When you create new offers we advise the process status and GET single offer flow for the retrieval of the offer ID.

The steps needed for these two flows have been described here.

What not to do:

We have noticed that some retailers delete all their offers and create them again to retrieve the offer ID’s instead of simply retrieving the offer export and importing those Offer ID’s in your system.

Please use the v3 offer export for an initial load to retrieve the Offer ID’s of offers that are already active in your assortment instead of using a delete – create flow.

 2.4 Create/update flow instead of a upsert request

Unlike version 2 of the Retailer API it is no longer possible to use the ‘Upsert’ request which was both a update offer request (when the retailer already has an offer for that specific EAN) and a create offer request (when the EAN was not yet in the assortment of the retailer).

With the introduction of the Retailer API v3 we have split the Upsert request into four  different requests;

The format of this request has changed as compared to the V2. The most important changes are aimed at the Condition which has been split up into two distinct fields and pricing part which now allows several bundles to support volumediscount. Look at our redoc for the specific format of our messages.

The update offer request can be used to update the fulfillment portion and the reference of your offer and can also be used to (temporarily) put an offer on hold.

This specifically updates the price of your offer and can also be used to set a volumediscount for a single offer. It is only used for price updates, no other processes can be affected with this request.

This request can be used to update the stock of your offer and indicate if you want to use our newly added option ‘managedbyretailer’. More information on this feature is added in other portions of this guide.

The reason for these changes is that the old upsert request was inefficient for us to process as we needed to do all sorts of internal business checks which meant a long processing time even if it was a simple price or stock change.

The new requests clearly define which part of the offers needs to be updated which means that we can increase our efficiency and decrease the processing time for the most common request; stock and price updates.

These requests can now be fast-tracked through our landscape and have a very short processing time. The processing time for create offer and update offer requests is higher as we have to do all sorts of validity and business checks (such as; whether you are authorized by bol.com to sell this product.

Our advice is to make sure your system is capable of defining which part of the offer is updated and only inserting that specific message to alter the value.

What not to do:

Delete – Create flow

Please make sure you don’t use a ‘Delete – Create’ flow which means that for every update you want to process, you delete the existing offer and create a new one. We realize this flow allows you to use the create offer request and  thus only requires one request instead of three separate requests to update the entire offer.

This however has a negative effect as these types of requests are far more costly for us to process and also greatly affects the processing times of your updates. The create offer request takes the longest to process and has a lower priority compared to update offer requests.

As a result of this flow your assortment will go offline for a period of time as a result of the delete request and stay offline until we have processed the following create request.

Updates without a delta-determination

The v3 flow is designed to be used in combination with systems which are aware of changes and can update very specific parts of the offer which allows for fast processing times within our systems.

Unfortunately we have also monitored a lot of retailer flows where it is not known to the retailer which offers specifically need to be altered. Instead they push their entire assortment to us and let us determine which offers need to be changed.

We expect retailers to be able to do the delta-determination for their own assortment and only send us relevant changes. This is something we will be monitoring more closely as it’s currently causing millions of unnecessary messages to be processed by our API’s.

These badly built processes cause a high load for our systems and thus have a negative effect on our processing time. This affects both your own updates but also those of other retailers and will be a important focus in future versions. Please make sure your systems are capable of their own delta-determination and use specific update messages for price, stock or delivery methods.

2.5 Single offer updates instead of a Bulk offer flow

With the introduction of the Retailer API v3 we no longer support a bulk flow for offers and only allow offers to be created and updated with the use of single offer requests. The v2 allowed for up to 50 offers to be included in a upsert offer request.

These fifty offers need to be split up into singles and specifically only for the part of the offer that needs to be updated. Our v3 design is aimed at a very fast processing time by keeping the updates as specific as possible. This means we expect single offer updates with a specific process. The v3 is not a bulk offer tool and as such it requires you to set up your system in such a way that you know which offers need an update and have those processed with a single offer update request, be it price, stock or delivery promise.

Also see ‘2.1 offer vision’ why we chose this approach.

2.6 Introduction of the stock-function ‘managedbyretailer’

With the release of the Retailer API v3 we have added an option which resolves issues several retailers encountered with our stock reservation flow for open orders. Our normal flow reserves stock for open orders which is why we have both Seller Stock and a Corrected Stock.

The corrected stock makes sure that customers can’t order stock that’s tied to an open order. Once a retailer ships the open order the Seller Stock is also adjusted (-1) to mirror the corrected stock.

Several retailers however count down for bol.com orders before shipping them. This resulted in a double count-down as is explained in the following stock scenario (3).

The easiest way to fix this is not to update the stock for bol.com offers until you’ve shipped the open order. In those cases our stock reservation flow works correctly and only one item is counted down.

In v3 we have added a different solution by adding the ‘ManagedByRetailer’ field. If you set this to ‘True’ for a specific offer we disregard any earlier updates when you send us a stock update. This means that reservations are also dropped and the updated stock becomes the new truth even if there are open orders.

We have described the specific flow on our developers page.

2.7 Offer export

With the introduction of the Retailer API v3 the composition of the Offer Export was changed to better serve the Offer ID flow that has been introduced. This means that the main function of the offer export is to return offer ID’s in bulk.

There are also some alterations because of the change in the function of the offer export;

stockAmount

The field stockAmount returns the latest stock we received from the retailer. This means that we do not return the current stock value that is tied to the offer nor the corrected stock (available for purchase).

This means you can use this field to validate we have your latest truth and that it can’t be used to retrieve the current stock for the offer. The stock amount can still be retrieved with the use of a GET single offer request.

Condition

The condition has been split up into two distinct fields, the conditionComment and the conditionCategory. At the moment we have two categories, NEW and SECONDHAND, but we are looking into adding other types of conditions. The conditionComment is used to further differentiate within a Category, for SECONDHAND this means you can have Category’s such as AS_NEW and GOOD.

You can find a specific example of the new offer export here.

2.8 Validity of offers

A impactful change compared to the retailer v2 is the way we communicate invalid offers, meaning offers that are not being published in the webshop because of reasons such as a lack of required product information or a price that is above a our benchmarks. A list of current reasons for an offer to not be published is available: API V3 – Offer request notPublishableReasons error-codes

In the v2 these reasons were part of the offer export but for the v3 this is no longer the case and invalid reasons can be retrieved by using the ‘GET single offer’ request.

This request returns the main reason why an offer is not valid for publication in our webshop. The reasons are no longer in our offer export but we are looking into exposing the same information with the use of a push API. We will be communicating the progress of the Push API development over the coming months on developers.bol.com.

2.9 Volume discount

This functionality is brand new in the v3. All info about volume discount can be found here.

3.      Orders / Shipments

3.1  Order retrieval flow

The biggest change in the orders and shipments endpoint is the smaller scope for the list request (less information is exposed in the list call) and the focus on the GET single order/shipment requests for the retrieval of the complete order/shipment information.

This means that we expose a paginated list of your open (orders endpoint) and shipped (shipments endpoint) orders. With this list you can retrieve the OrderID’s (for orders) and the shipment ID’s (for shipments) with which you can use single GET requests and retrieve the complete order or shipment information.

The reason for this change is that the v2 list calls combined with the increase in plaza traffic meant a heavy load on our systems which was not scalable and caused performance issues for the order and shipment retrieval processes. By reducing the scope of the list call we can ensure the performance of these vital processes.

These processes are explained here.

3.2  Addition of customer invoicing addresses

This also allowed us to expose more information in the orders, but more importantly, also the shipments endpoint. Up to now we weren’t able to expose the billing details of customers in the shipments endpoint which meant you needed to save the billing details based on the open orders endpoint. With the introduction of the new version we have been able to expose more fields (such as if the order relates to a business client) and add them to the shipments endpoint.

You can find our specific documentation here.

Suggested use

This addition is most suited for our FBB/LvB (Fulfillment by bol.com) partners as they are primarily interested in the shipped orders (open orders can still be cancelled by the customers) and until now you needed two separate calls, a GET orders call to retrieve billing details and a GET shipments call to ensure the order was actually shipped and not cancelled.

The flow for the FBB orders therefore should be aimed at the Shipments endpoint. Retrieve your shipments with the List and the single shipment calls and make sure the FBB orders are actually shipped.

For FBR (fulfillment by retailer) orders we advise you to use the list and single order calls.

What not to do when you’re a FBB retailer

We noticed that several retailers, but also intermediaries, didn’t use the get shipments request and as such could not conclude if all the open orders were actually shipped. This caused issues with their bookkeeping as they sometimes wrongly concluded that orders were paid and shipped while they were actually cancelled.

This means that for FBB you should focus on the GET shipments endpoint. This endpoint now also exposes the customer billing details and as such there is no reason to (solely) use the GET open orders endpoint for your FBB orders.

3.3  New order number type as of Q3 2020

Please be aware that the orderID that we expose via the Retailer API in the course of 2020 will include alphanumerical characters.

What is expected from you?

  • Verify if your system is able to cope with alphanumerical characters in the orderId field throughout the API.
  • Verify your code if you are able to process alphanumerical characters.

A detailed explanation of the upcoming changes can be found here.

3.4  Process status for shipment requests

The shipment request has an asynchronous process in our systems and as such a ‘202 accepted’ response does not mean the shipment request has actually been processed successfully. Only the retrieval of the process status will allow you to check if the orderitem has been shipped successfully.

There are several reasons why a shipment request might fail, such as an invalid Track & Trace code or a service interruption in our systems. If the shipment requests fails the orderitem will remain open and (if there’s not a new attempt to ship the orderitem) it will be cancelled and no payment will be provided to the retailer.

Please ensure you use the process status on v3 to make sure your orders have actually been shipped. If you do not and orders are eventually cancelled because of a failed shipment request then we can’t offer any support or payment to rectify the situation.

This is not a change regarding version 2 but we are emphasizing its importance as it’s still not being used by a lot of retailers.

4.      Cancellations

There are no functional changes in v3 on the cancellations endpoint.

Find the documentation in part 2b here and on redoc.

5.      Returns

5.1  Introduction

As of version 4 of the Retailer API, the concept of multi-item returns has been introduced. A multi-item return is a return that can contain 1 or more return items. Up till version 2, each return was always 1 return item. In version 4 a return is identified by a return-id and a return-item is identified by a rma-id. As of version 4, you therefore need to provide the return-id in case you want to fetch all the return related data of that specific return. In case you want to update or create a return, this action remains on rma-id identifier.

5.2  Major change between version 2 and version 4

Following the conventions of version 3 and version 4 of the Retailer API, a distinction has been made by fetching a list of returns and by fetching data of a single return. The list of returns provides you with a limited set of data fields related to a specific return. If you want more detailed information on this specific return, you need to use the return-id to fetch more details regarding a specific return.

5.3  Get an overview of all your returns

Endpoint version 2

GET /return-items/v2/unhandled

Replacement in version 4

GET /retailer/returns (for fetching general return information and the return-id)

GET /retailer/returns/{return-id} (for fetching detailed return information)

 

Changes

  • Requesting unhandled returns has moved from a fixed path to a query parameter called handled of type Boolean in /retailer/returns

Introductions

  • Requesting handled returns is now possible by using the query parameter called handled of type Boolean in /retailer/returns
  • The fulfilment-method is a new introduced query parameter of an enumeration type to filter on FBR or FBB returns in /retailer/returns.
  • The page query parameter is a new introduced query parameter to request a specific page of all your returns in /retailer/returns
  • The query parameter return-id is introduced to fetch specific details of a return in /retailer/returns/{return-id}

 

5.4  Handling a return

Endpoint version 2

PUT /return-items/v2/{ReturnNumber}/handle

Replacement in version 4

PUT /retailer/returns/{rma-id}

Changes

  • Field ReturnNumber (version 2) in the request body has been renamed to rma-id (version 4)
  • Field StatusReason (version 2) in the request body has been renamed to handlingResult (version 4)
  • Field QuantityReturned (version 2) in request body has been renamed to quantityReturned (version 4)
  • Updated handling results, see table below.
StatusReason (version 2) handlingResult (version 4) Remarks
PRODUCT_RECEIVED RETURN_RECEIVED Changed
FAILS_TO_MATCH_RETURN_CONDITIONS RETURN_DOES_NOT_MEET_CONDITIONS Changed
CUSTOMER_KEEPS_PRODUCT CUSTOMER_KEEPS_PRODUCT_PAID Changed
EXCHANGE_PRODUCT Introduced
REPAIR_PRODUCT Introduced
STILL_APPROVED Introduced
REPAIRED_OR_EXCHANGED Removed

 

5.5  Creating a return

Endpoint version 2

POST / return-items/v2

Replacement in version 4

POST /retailer/returns

 

Changes

  • The concept of OrderId and OrderItemSequenceNumber (version 2) in the request body has been removed and replaced with the field orderItemId (version 4)
  • quantity (version 2) in the request body has been renamed to quantityReturned (version 4)

Introductions

  • A new field called handlingResult has been introduced in the request body in version 4

 

5.6  Data model / Object changes

 

Note: in version 4, all fields follow the camel case convention.

Field version 2 Field version 4 Remarks
returnId New field
  fulfilmentMethod New field
ReturnNumber rmaId Renamed
OrderId
EAN
Title
Quantity expectedQuantity Renamed
ReturnDateAnnouncement registrationDateTime Renamed
ReturnReason
ReturnReasonComment returnReasonComments Renamed
trackAndTrace New field
transporterName New field
Handled New field
processingResults New object
  quantity New field
  processingResult New field
  handlingResult New field
  processingDateTime New field
CustomerDetails.
  SalutationCode
  FirstName
  Surname
  Streetname
  Housenumber
  HousenumberExtended
addressSupplement New field
extraAddressInformation New field
  ZipCode
  City
  CountryCode
  Email
deliveryPhoneNumber New field
  Company
vatNumber New field

 

6.      Invoices

There are no functional changes in v3 on the invoices endpoints.

Please find the documentation here. And the redoc info here.

7.      Fulfilment by bol.com

There are no functional changes in v3 on the FBB endpoints.

Documentation can be found here.

8.      Partner Performance

One of the new features in the v3 are the partner performance indicators.

In order to fulfill the expectations of our customers it is crucial to continuously strive for the best possible service. To jointly ensure this quality of service is met, a number of service standards apply on the bol.com platform.

The performance of bol.com’s partners with regards to these service standards is monitored on a daily basis and reflected in weekly scores. The resulting Performance Indicators can be reviewed on your Seller Performance Dashboard. For more background on the Service norms and our processes you can also refer to the Partner Platform page.

Now in beta phase, fully available from 01-04-2020

 

9.      Insights (beta)

Another new feature in the v3 is the insights component.

The main insights are listed below.

PRODUCT_VISITS The number of customer visits on the product page when your offer is shown in the buy box for the requested period.
BUY_BOX_PERCENTAGE Percentage of customer visits on the product page that your offer is shown in the buy box for the requested period.

Get sales forecast

 

The sales forecast endpoint can help you estimate the sales expectations on the total bol.com platform for the requested number of weeks ahead*. This is based on historical sales . You can use this for instance for purchasing and/or capacity planning.

 

Full details can be found here: https://developers.bol.com/retailer-api-offer-insights/

 

10. Product content (beta)

Until now there was no option to add product information via the API.

Finally, within the Retailer API v3 there will be the option to upload your product information.

Options:

  • Post product content according to the data model (endpoint: Post product content)
  • Request if upload has been successfully processed (endpoint: Get process status by ID)
  • Get validation feedback on the uploaded product content (endpoint: Get validation report)

Full details can be found here: https://developers.bol.com/api-v4-product-content/

 

 

bol.com Development Center