Open API migration guide
bol.com webshop data now available in Retailer API
As bol.com we are constantly looking at ways to improve our retailing partner experience. As part of this track, we have explored to expose bol.com webshop related data to our retailing partners. Something that has been requested many times. For those who would like to start using this data, we would like to recommend the regular documentation of the bol.com Retailer API V9 release. The documentation will guide you through the process in a way you are familiar with.
Use of Open API versus Retailer API
We acknowledge that many of you have been using the bol.com Open API (also known as the 'Affiliate API') to retrieve webshop-related data. While Open API provides access to valuable information, it was not originally designed for this purpose and has resulted in challenges such as onboarding difficulties and different conventions than our Retailer API.
After years of providing support, we have determined that Open API no longer meets our internal quality standards. Therefore, the Open API will be phased out for our Retailing partners. To address this, we have prioritized the development of new endpoints in Retailer API to replace the data that was offered through Open API. With input from our partners, we have enhanced features and streamlined data to provide a better user experience.
Introduction
We understand that migrating to a new API can be challenging, so we have created this page to make the process as smooth as possible. The new endpoints are designed to align with the conventions and principles of Retailer API, and thus have a different setup compared to Open API. To assist you, we have included an endpoint mapping, object mapping, and a FAQ section to provide an overview of the key changes.
If you encounter any obstacles along the way, our frequently asked questions section below and our Technical Support team (openapi-migratie@bol.com) are here to help. Our experts will guide you through the migration process and provide assistance if needed. We value your feedback, so if you have any suggestions for improvement, please let us know.
Please note that this guide assumes a basic understanding of Retailer API. If you are new to Retailer API or have not worked with it recently, we recommend reviewing the conventions, the rate limits, and the lifecycle process to ensure a successful migration.
We are here to support you every step of the way. Good luck with your migration!
Endpoint mapping
Four endpoints of Open API are particularly interesting for our retailing partners, based on our data analysis and research.
Please note that GET /catalog/v4/recommendations
and GET /catalog/v4/relatedproducts
hardly have any usage and we therefore decided not to invest in a substitute.
The following sections provide details regarding the endpoint mapping. They also include examples of common requests made to Open API and their corresponding replacement requests for Retailer API.
Some notes regarding these examples:
- the IDs of products in Open API requests and Retailer API requests are different because Retailer API works based on EAN.
- the search and lists endpoints have many query parameters. Some are not included in this example.
Products endpoint
Open API endpoint | Main Usage | Replacement Retailer API endpoint |
GET /catalog/v4/products | Get detailed information about the products sold on the bol.com platform. | Get catalog product details by EAN, Get product ratings by EAN, Get product placement by EAN. |
Example Open API request: GET /catalog/v4/products/1001004011182718?includeattributes=true&offers=bestoffer&country=NL
Example Retailer API requests:
- product data:
GET /retailer/content/catalog-products/9780137081073
- offer data:
GET /retailer/products/9780137081073/offers?country-code=NL&best-offer-only=true
Offers endpoint
Example Open API request: GET /catalog/v4/products/1001004011182718?includeattributes=true&offers=bestoffer&country=NL
Example Retailer API requests:
- product data:
GET /retailer/content/catalog-products/9780137081073
- offer data:
GET /retailer/products/9780137081073/offers?country-code=NL&best-offer-only=true
Search endpoint
Open API endpoint | Main Usage | Replacement Retailer API endpoint |
GET /catalog/v4/search | Ranking tracker for search terms (understand the rank of a product for specific search terms). It is also used to covert EAN's to bol.com Product ID's. | Get Product List supported by: Get Product List Filters, Get Product Placement by EAN. |
Example Open API request: GET /catalog/v4/search?q=clean%20coder&dataoutput
=products&offers=bestoffer&sort=relevance&includeattributes=false&country=NL
Example Retailer API requests:
- search results, products:
POST /retailer/insights/product-list with body
{
"countryCode": "NL",
"searchTerm": "clean coder",
"sort": "RELEVANCE"
}
- offer data, per product:
GET /retailer/products/{ean}/offers?country-code=NL&best-offer-only=true
List endpoint
Open API endpoint | Main usage | Replacement Retailer API endpoint |
GET /catalog/v4/lists | Ranking tracker for lists (understand in rank of a product for a webshop specific list/category). | Get Product List supported by: Get Product List Filters, Get Product Placement by EAN. |
Example Open API request: GET /catalog/v4/lists?ids=40409&dataoutput=
products&sort=popularity&includeattributes=false&country=NL
Example Retailer API requests:
- search results, products:
POST /retailer/insights/product-list with body
{
"countryCode": "NL",
"categoryId": "40409",
"sort": "POPULARITY"
}
- offer data, per product:
GET /retailer/products/{ean}/offers?country-code=NL&best-offer-only=true
Object mapping
For each endpoint within Open API, we described the current fields and where to find the data in Retailer API.
The field names in Open API are from the JSON responses. The XML responses will be similar, but often different in how they are cased (lowerCamelCase vs UpperCamelCase).
Note: we would like to add additional markup to the text in the tables for improved readability, but this website's CMS does not allow it.
Products object
The following table shows the attributes of a Product object, which can be returned by the products
, search
and lists
endpoints of Open API.
Field in Open API | Specifics in Open API | Endpoint in Retailer API | Specifics in Retailer API |
id | Internal bol.com Product ID | Get product ids by EAN | Included as: bolProductId. Note: This bol.com Product ID (BPID) was needed in Open API but is currently not needed in Retailer API. Please be aware that the EAN to bol.com Product ID relationship may change if we make changes to correct issues in our product catalog. |
ean | EAN of the product | Get product ids by EAN | Included as: eans[] |
gpc | - | Get catalog product details by EAN | Included as: gpc.chunkId |
title | - | Get catalog product details by EAN | Included within the attributes, where attributes[].id="Title" |
subtitle | - | Get catalog product details by EAN | Included within the attributes, where attributes[].id="Sub Title" |
specsTag | Could contain one of the following: a product's Author, Artist, Brand, Manufacturer or Publisher | Get catalog product details by EAN | Change: There is no direct replacement for this field. This kind of data is now included as 'parties'. Also see "entityGroups". |
summary | A small summary of product data | - | Deprecated: The summary is a text composed by combining the most important attributes of a product. These attributes are already included under attributes[] in the response of 'Get product ratings by EAN'. In addition, it would require another service request to get this data. Therefore with little value and an extra cost, we chose not to include it. |
rating | Average product rating, scale of 00 –50, representing 0 to 5 stars | Get catalog product details by EAN | Change: The average rating can be calculated from the rating distribution. NEW: the rating distribution is added, which shows how many ratings there are for each star level. |
shortDescription | This was originally intended as a short description. When short description was no longer available, this field provided the product description, stripped from HTML tags | Get catalog product details by EAN | Deprecated: There no longer is a short description. We recommend removing this field from your integration. If you wish to do so, you can derive a short description from the regular description by stripping the HTML tags from the 'Description' which is included as an attribute, where attributes[].id = "Description". |
longDescription | A product description, which could include HTML tags | Get catalog product details by EAN | Included within the attributes, where attributes[].id = "Description" |
trackLists.discnumber | The disc number | Get catalog product details by EAN | Included as audioTracks[].discNumber |
trackLists.track.title | The title of the track | Get catalog product details by EAN | Included as audioTracks[].title |
trackLists.track.tracknumber | The tracknumber of the track | Get catalog product details by EAN | Included as audioTracks[].trackNumber |
attributeGroups (title and attributes with key, label and value) | A list of attributes that are logically grouped together | Get catalog product details by EAN | Included as: attributes[] Mapping from Open API to catalog-products: key > id, label > Deprecated: No longer included in the API. The key holds the English text. The label, which held the Dutch text, can be found by looking up the "id" of the attribute in the bol.com datamodel and retrieving the "name" attribute from that object in the datamodel, value > values[].value + values[].unitId. Warning: Grouping of attributes is deprecated and with that, the 'title' attribute of the group is no longer available. |
entityGroups (title and optionally entities with id and value) | Lists parties that are related to the product, like publisher, actors, etc. | Get catalog product details by EAN | Included as: parties, where type describes the type of data and name holds the value. The role attribute can be used to group parties together (multiple types map to one role). Warning: Grouping of entities is deprecated and with that, the 'title' attribute of the group is no longer available. Change: We are no longer exposing the ID of an entity. *Below this table there is a link to a list of party types and the corresponding 'role'. Determine it's value via ROLE, TYPE and NAME. |
urls | The URLs of this product | Get catalog product details by EAN | Included as url. NEW: The URL can now be retrieved per country and per language. Warning: The distinction for desktop and mobile URLs is deprecated. For a few years now, we don't have separate URLs for mobile. The regular website is geared towards both desktop and mobile use. |
images.type | The the type of the primary or cover image of the product | Get catalog product details by EAN | Change: The type attribute in Open API is replaced by productAssets[].usage in Retailer API. The usages 'primary' and 'additional' are used to categorize images. |
images.key | The size of the primary or cover image of the product | Get catalog product details by EAN | The images are now exposed in two sizes, which can be found in productAssets[].variants[].size. The values are: 'small', this size is always 250x200 pixels (width x height). 'medium', the image will fit a canvas of 550x840 pixels (width x height). This means there is some variance in the image size, as the image will get resized until it fits the canvas. This size is same as the 'XL' size of Open API Key, which was marked with "key": "XL". The fixed size of the 'small' image makes it ideal for list views. Warning: The other (mostly very small) sizes of the primary image are no longer exposed. |
images.url | The url of the of primary or cover image of the product, in this size | Get catalog product details by EAN | Included as productAssets[].variants[].url |
media (with type, key, url) | Additional media for the product, including secondary images, videos and manuals | Get catalog product details by EAN | Similarly to the primary image, (see above at 'images.key'), the secondary images of a product are exposed in two sizes: 'small' (exactly 250x200) 'medium' (fits within 550x840), which is the 'XL' size that was included in Open API. Warning: At this time, only images are offered in this endpoint. Upon demand we will investigate adding additional assets (like video) in the future. |
offerData: See Offer data object section | - | - | - |
parentCategoryPaths, holding parentCategories with id and name | The categories a product belongs to and the parents of those categories | Get catalog product details by EAN | Included under categories[]. Change: Open API listed the categories a product is in, with the category's parents, for each category a product is in. There would often be overlap in these 'branches'. The new endpoint provides the same data, though in a clean and rationalized form, without overlapping branches. |
* Regarding 'entityGroups' field: on this page, you will find a list of party types and corresponding roles.
Offer data object
The following table shows the attributes of an OfferData object, which can be returned by the products
, offers
, search
and lists
endpoints of Open API.
Attribute in Open API | Specifics in Open API | Endpoint in retailer API | Specifics in Retailer API |
bolCom | Counter for the number of bol.com offers on the product | Get a list of competing offers by EAN | Included under offers[]. Change: The number of bol.com offers can be calculated by counting the offers in the offers array where the retailerId equals "0". |
nonProfessionalSellers | Counter for the number of offers supplied by non-professional sellers | - | Deprecated: We no longer have non-professional sellers on our platform. |
professionalSellers | Counter of the number of offers supplied by professional sellers | Get a list of competing offers by EAN | Included under offers[]. Change: The number of offers from professional sellers now is simply the offers of retailers other than bol.com. This number can therefore be calculated by counting the offers in the offers array where the retailerId does not equal "0". |
offers.id | The offer ID on the bol.com platform | Get a list of competing offers by EAN | Included as offers[].offerId. Change: Retailer API uses our new offer ID. The offer ID used by Open API is being phased out and has no value in the context of Retailer API. |
offers.condition | The state the offer is in, e.g. “new” | Get a list of competing offers by EAN | Included as offers[].condition. Change: The condition of the product that the offer is for, is listed in English and according to the standards of Retailer API. Mapping from Open API to Retailer API: nieuw > NEW, als nieuw > AS_NEW, goed > GOOD, redelijk > REASONABLE, matig > MODERATE. Retailer API has one extra condition: BAD. |
offers.price | bol.com price, format 19.95 | Get a list of competing offers by EAN | Included as offers[].price |
offers.availabilityCode | Delivery promise code | Get a list of competing offers by EAN | Warning: The availability code is deprecated. It is replaced by the following delivery promise information: offers[].ultimateOrderTime, the latest order time in the day, for the delivery promise to be applicable. offers[].minDeliveryDate, the earliest possible delivery date for the delivery window promised by the retailer. offers[].maxDeliveryDate, the earliest possible delivery date for the delivery window promised by the retailer. NEW: the offer's fulfillment method is included as offers[].fulfilmentMethod. |
offers.availabilityDescription | Delivery promise description | Get a list of competing offers by EAN | Change: The description can now be composed based on: offers[].ultimateOrderTime, the latest order time in the day, for the delivery promise to be applicable. offers[].maxDeliveryDate, the earliest possible delivery date for the delivery window promised by the retailer. |
offers.comment | Copy of availability description | - | Deprecated: Offers no longer have comments. Already in Open API this data was a duplicate of the availability description. |
offers.seller, See Seller data object section | Data about the offer's retailer | - | - |
offers.bestOffer | Signals if the Offer is the best offer and has the 'buy box' | Get a list of competing offers by EAN | Included as offers[].bestOffer. Change: This attribute is now available for every offer. |
offers.releaseDate | Release date, if applicable for a product. | Get catalog product details by EAN | Included within the attributes, where attributes[].id="Original Release Date". |
Seller object
The following table shows the attributes of a Seller object, which can be returned by the products
, offers
, search
and lists
endpoints of Open API.
Note: the table describes the complete object with all its attributes. The products
endpoint in Open API returns less attributes.
Note: the XML encoded response includes "recentReviewCounts
" as "allReviewsCounts
".
Field in Open API | Specifics in Open API | Endpoint in Retailer API | Specifics in Retailer API |
id | ID of the seller | Get retailer information by retailer id | Included as retailerId |
sellerType | The type of seller, e.g. "Kleinzakelijke verkoper" | - | Deprecated: This attribute has been phased out together with the distinction between professional and non professional sellers. |
displayName | Name of the seller | Get retailer information by retailer id | Included as displayName |
url | An url describing the terms of a 3rd party seller | - | Deprecated: We are not exposing attribute through Retailer API because it is something that had little use by external partners. It was mostly included for the bol.com mobile app, which used Open API at its data source. |
topSeller | Indicates whether the seller is a 'topseller' | - | Included at topRetailer |
logo | An url to an image of the logo of the seller | - | Deprecated: We are not exposing attribute through Retailer API because it is something that had little use by external partners. It was mostly included for the bol.com mobile app, which used Open API at its data source. |
sellerRating.ratingMethod | Indicates whether the rating is based on all available reviews (ALL_REVIEWS) or on the last three months (THREE_MONTHS) | Get retailer information by retailer id | Included as ratingMethod |
sellerRating.sellerRating | The rating of the seller | Get retailer information by retailer id | Included as retailerRating.retailerRating |
sellerRating.productInformationRating | The rating of the seller based on his product information | Get retailer information by retailer id | Included as retailerRating.poductInformationRating |
sellerRating.deliveryTimeRating | The rating of the seller based on his delivery time | Get retailer information by retailer id | Included as retailerRating.deliveryTimeRating |
sellerRating.shippingRating | The rating of the seller based on his shipping performance | Get retailer information by retailer id | Included as retailerRating.shippingRating |
sellerRating.serviceRating | The rating of the seller based on his service | Get retailer information by retailer id | Included as retailerRating.serviceRating |
recentReviewCounts.positiveReviewCount | The number of positive reviews | Get retailer information by retailer id | Included as retailerReview.positiveReviewCount |
recentReviewCounts.neutralReviewCount | The number of neutral reviews | Get retailer information by retailer id | Included as retailerReview.neutralReviewCount |
recentReviewCounts.negativeReviewCount | The number of negative reviews | Get retailer information by retailer id | Included as retailerReview.negativeReviewCount |
recentReviewCounts.totalReviewCount | The total number of reviews | Get retailer information by retailer id | Included as retailerReview.totalReviewCount |
sellerInformation | A description of the seller | - | Deprecated: We are not exposing attribute through Retailer API because it is something that had little use by external partners, and could contain personal information. It was mostly included for the bol.com mobile app, which used Open API in the past. |
useWarrantyRepairConditions | Specific return warranty terms that the seller applies | - | Deprecated: See the clarification for 'sellerInformation' |
warrantyConditions | Specific return warranty terms that the seller applies | - | Deprecated: See the clarification for 'sellerInformation' |
repairConditions | Specific return warranty terms that the seller applies | - | Deprecated: See the clarification for 'sellerInformation' |
approvalPercentage | Percentage of reviewers that recommended the seller | Get retailer information by retailer id | Included as retailerReview.approvalPercentage. Change: The approval percentage is now provided in round numbers (as an integer). |
registrationDate | Registration date of the seller, as as timestamp | Get retailer information by retailer id | Included as registrationDate. Change: The registration date is now provided as a date and formatted as "yyyy-mm-dd". |
Frequently Asked Questions
General
- Why is support ending for Open API?
The core application behind Open API is at the end of its lifecycle and it no longer meets our quality norms for our retailing partners. Fixing the issues would require a substantial effort and we would rather direct that effort to Retailer API, which has a bright future ahead of it. - We will need to use multiple endpoints where we previously used to only use one. Can you include more data in an endpoint response?
In Retailer API we offer 'lean' endpoints that expose a specific type of data. This aligns with our product vision of keeping endpoints lean, fast and only offering data in one place. Retailer API provides lean endpoints to prevent serving data that might not be used by the API consumer. This ensures requested data actually gets used. Therefore, we won't add data of one endpoint into the response of another. However, if you feel some important data is missing, please reach out to our Technical Support via: openapi-migratie@bol.com. - What happens if we keep using Open API?
We strongly encourage partners to change their integrations and start using Retailer API. Using Open API will no longer be supported for our Retailing partners. Retailer API is fully supported, and future improvement will only be made in Retailer API. - Can we use both API's at the same time, to test or run shadow mode?
Yes, you can use both API's side by side. However, for applications like repricers that produce a high volume of requests, we ask that you use a subset of products to run these side by side with. Because of the load on our services we do ask that you try to keep this period of running side by side short and that you stop using Open API as soon as you can confidently do so. - When will the new endpoints go GA (General Available)?
Please keep an eye on the Open API migration page for the latest information on the timelines. - Is it safe to implement the v9 BETA endpoints?
Yes, the endpoints are tested, supported and run in our production environment, serving production data. We believe the endpoints are ready to be implemented by partners. The endpoints have BETA status to indicate something may change to further improve the endpoints, based on your feedback.
For example, Product Placement recently got an improvement where we added hierarchy to the category data.
Rate limits
- The rate limits on the new endpoints in Retailer API seem too low for our use cases. Can you please raise the rate limits?
With rate limits, we try to find the optimal balance between consumer needs and load on our backend services. Due to the different set-up of Open API and Retailer API, it is challenging to forecast the exact load per endpoint. In the coming months, we will monitor the usage and adjust the rate limits where needed and feasible. - What happens if the rate limits of the new endpoints in Retailer API are too low for our use cases?
We would appreciate it if you could contact our Technical Support via openapi-migratie@bol.com to explain your use cases and needs. This is valuable input for our capacity planning.
Data in responses
- Why is the total number of results for a search or a category not included in the product-list response?
In Retailer API the convention is not to expose total counts or data that can be calculated from the response with simple math. This keeps the endpoints lean and provides a consistent developer experience. - Why are no product details included in the product-list response?
Retailer API aims to provide lean endpoints that are fast and offer data in one place. Product data can be retrieved by using the 'Get catalog product details by EAN' endpoint. - I’m missing data that used to be in Open API, where can I retrieve it?
The object mapping tables on this page provide detailed information on where data can be found. In some cases, the data is no longer available. If you feel some important data is missing, please reach out to us using one of the methods provided below, so we can investigate adding this data to the API. - Can we get responses in XML, just like in Open API?
Retailer API does not provide XML encoding. Other differences to note are that endpoints in Open API support the "format" query parameter to request a response in JSON or XML, as well as an "Accept" header to indicate the same. The default encoding in Open API is JSON. Retailer API provides responses in JSON and the encoding is requested through providing an "Accept" header (see documentation).
Search & Lists
- Where is the replacement for the Lists endpoint of Open API?
The Search and Lists endpoints of Open API are using the same underlying service to get the results. And since both return the same type of data (a list of products), we decided to combine the two and offer one endpoint: 'Get product list'. This new endpoint uses the same internal source as the endpoints in Open API and should therefore provide the same results. The Product List endpoint can be used by itself for most simple use cases. For more advanced use cases, the Product List endpoint requires IDs that can be retrieved by using the Product Placement and Product List Filters endpoints. - How do I know which Category ID I should use?
The Category IDs can be found based on product, using the 'Get product placement' endpoint, or based on a search term using the 'Get list filters' endpoint. The 'Get list filters' endpoint can also be used to find subcategories for a category.
How can I ask a different question?
You can always get in contact with our Technical Support via: openapi-migratie@bol.com. Experts will guide you in your migration steps and it will give us the chance to update our documentation based on your feedback.
Version history
Version | Date | Description |
1.0 | 07-03-2023 | Initial version available |
2.0 | 04-05-2023 | Improved readability |