Offer API

This API is currently in beta with limited availability. If you want to participate, you can look here. If you have any questions or remarks that can improve this API, mail us at retailerapi-beta@bol.com. Updates to this beta will be communicated via our developers portal.

The bol offer API allows you to execute the following actions on the bol marketplace:

  • Creating offer data

  • Retrieving offer data

    • Get an offer: this endpoint allows you to retrieve a single offer

    • Get offers: this endpoint allows you to retrieve your offer data by a given criteria in a paginated manner

    • Get not for sale reasons: this endpoints allows you to retrieve the reasons why an offer is not for sale

  • Updating offer data

  • Deleting offer data

In case you are looking for offer related events, please take a look at our Subscription API.

Please be aware that the offer API as of version 11 is processing data synchronously. This means that you do not need the process status flow anymore when using this version of the offer API.

Creating offer data

Creating an offer on the bol marketplace can be done via this POST endpoint, which will instantly return back a success or error. The following fields and objects are present when creating an offer:

Field Description

ean

The EAN number associated with this product. In case you provide an ISBN, the ISBN will be replaced with the actual EAN belonging to this ISBN.

unknownProductTitle

In case this product is not known to the bol marketplace you can use this field to identify this particular product. If a product is known to bol, this field will be ignored. A maximum of 500 characters is supported.

economicOperatorId

The economic operator entity. See the economic operator API for more information.

reference

An optional user-defined reference that help you identify this particular offer. A maximum of 100 characters is supported.

onHoldByRetailer

Temporarily pauses this offer from listing on the bol marketplace.

condition (object)

The condition details that apply to this offer.

pricing (object)

The pricing details that apply to this offer.

countryAvailabilities (object)

The country in which you want to sell this offer. This can be the Dutch market NL, the Belgium market BE or both.

fulfilment (object)

Fulfilment details on how you want to fulfil an order to the customer.

stock (object)

Information on your stock level.

The unique combination within the bol marketplace to create an offer is retailerId + ean+ condition + countryAvailabilities.countryCode. If you want to know which fields are mandatory to provide, you can check our ReDoc documentation page.

ean

The ean field is used to identify the item that you want to sell on bol. The ean is required and it is also allowed to provide an ISBN (International Standard Book Number) in this field. When you provide an ISBN, the bol marketplace will link it to the actual ean of that item. In that case, the ISBN is discarded. The ean is part of the unique key of an offer within the bol marketplace and can therefore not be changed if the offer is created successfully. If you want to change the ean of an offer, you need to delete the current offer and create a new one.

unknownProductTitle

In case the bol marketplace doesn’t know the provided ean for this offer, it might be difficult to find this product back in the bol systems. Therefore, you can provide an unknownProductTitle that allows you to easily find back this offer. If you want to know if the bol marketplace already knows this ean, you can use the GET product-ids endpoint for this. If this endpoint provides you a bolProductId, then the bol marketplace already knows this ean.

economicOperatorId

In accordance with the Digital Services Act, the bol marketplace must show consumers who is the responsible economic operator in the EU for a product before they purchase it. Every retailer is individually responsible for providing the required economic operator information. The economicOperatorId is the identifier of the created economic operator. If you do not have an economicOperatorId yet, then you need to create this first. You can do this by using our Economic Operator API. You can update the economic operator anytime.

The bol marketplace is required to provide the economic operator to customers by EU legislation. Therefore your offer will only become online if this data is provided. If you fail to provide this data, customers will never be able to purchase an item via this offer.

reference

The reference field can be used to define a custom reference. The bol marketplace only uses this reference to help you find data back within the bol marketplace. You can therefore use this for your own recognition. It is not mandatory to provide a reference but if you do so, then take into account that the field size is limited to 100 characters. It is always possible to update the reference afterwards.

onHoldByRetailer

The onHoldByRetailer field can be used to temporarily pause this offer. This only applies if your offer is online on the bol marketplace. If your offer is already marked as offline, pausing it will have no effect. If you want to pause an online offer, you can set this field to true. If you want to continue selling this offer, you can set this field back to false.

condition

The condition object contains information regarding the condition of the product that you want to sell on the bol marketplace. Depending on the type of the condition, logic applies to what data you need to provide. The type can only be any of the following:

  • NEW - indicates that the product being sold is new.

  • SECONDHAND - indicates that he product being sold is not new anymore. In case you provide SECONDHAND as the condition, you are also required to provide the attributes object:

    • You need to provide the state . The state refers to the state of the product. This can only be AS_NEW, GOOD, or MODERATE.

    • You can optionally provide a comment. The comment is an addition to the state of the product. You can provide any text here (for instance: "slightly used" or "scratch on side of the product") up to 2000 characters. E-mail addresses are not allowed in this field.

  • REFURBISHED - indicates that the item being sold is refurbished. In case you provide REFURBISHED as the condition, you are also required to provide the attributes object:

    • You need to provide grade. The grade can either be A, B, or C. The grade refers to the quality of the refurbished item, where grade A means "the best quality; near-mint condition." , grade B means: "second-best quality; light scratches" and grade C means: "low cosmetic quality".

    • You need to provide the margin. The margin can either be true or false and indicates whether there is a margin adjustment due to the condition.

The condition is part of the unique key of an offer within the bol marketplace. Therefore you cannot change the condition once the offer was created successfully. If you still want to make such a change you can create a new offer and delete the old offer.

pricing

The pricing object refers to the base pricing that applies to this offer. This price does not include any promotions. The bol marketplace allows you to use up to four prices. It is not required to use more than 1 price, but you do need to provide at least 1. You cannot set the pricing to null (as it is mandatory to provide) nor you can send an empty array.

You can set the price using the bundlePrices object. If you plan to provide more than 1 price, you need to reward your customers with a (small) discount if they buy more than 1 unit (volume discount). The quantity therefore needs to increase per element in the array, whereas the unitPrice needs to decrease. An example of selling an item with two prices is the following:

{
 "pricing": {
    "bundlePrices": [
      {
        "quantity": 1,
        "unitPrice": 9.99
      },
      {
        "quantity": 2,
        "unitPrice": 8.99
      }
    ]
  }
}

In this example, if a customer buys the product with a quantity of 2, the customer gets both products for 8,99 euro (17,98 euro in total). You can always adjust the price in the future if necessary.

The bol marketplace accepts a unitPrice that is at least 1 euro (to prevent price mistakes of zero euro), and with a maximum of 9999 euro.

countryAvailabilities

The countryAvailabilities object indicates in which country you want to sell this offer, via the countryCode field. You have four options to indicate where you want to sell this item:

  1. You omit this object entirely. If you do not provide a countryCode, the bol marketplace will use the default country setting that is attached to your retailer account. If it is set to Dutch, your offer will only be published in the Netherlands. If it is set to Belgium, it will only be published in Belgium. Be aware that if you change this setting on your account, all your offers will also be affected by this change.

  2. You add the countryCode with NL - in this case you overrule your account setting. Your offer will only be published on the Dutch marketplace.

  3. You add the countryCode with BE - in this case you overrule your account setting. Your offer will only be published on the Belgium marketplace.

  4. You add both country codes (NL and BE) to this array. You overrule your account setting. Your offer will be published to the Belgium and Dutch marketplace. If you change your account setting, this change will not affect these offers.

It is always possible to change the country availability afterwards. If you want to change the country availability back to your default account setting, you can send null or omit it from they payload (that will default to null). Note that sending an empty array is not allowed.

fulfilment

The fulfilment object indicates how you want to fulfil a potential customer order. Depending on the method of the fulfilment, logic applies to what data you need to provide. The method can only be any of the following:

  • FBB - indicates that the fulfilment is done by bol (via the logistics via bol proposition). If you provide FBB, you do not need to provide more data. Bol with handle the fulfilment based on the most optimal conditions towards the customer.

  • FBR - indicates that you do the fulfilment yourself. If you provide FBR, you also need to provide a schedule. This schedule can be one of the following types:

    • MY_DELIVERY_PROMISE - this schedule refers to your custom created delivery promise. You can create this delivery promise via the seller dashboard under "settings". If you did not create a custom delivery promise via the seller dashboard but do provide this value via the API, the bol marketplace will mark your offer as "offline" as the bol marketplace cannot find the corresponding schedule. As a consequence, it is unknown to provide the customer with a correct delivery promise.

    • SHIPPING_VIA_BOL - this schedule refers to the shipping via bol proposition. If you are using shipping via bol, you can use this option to mark this offer for shipping via bol. If you did not register for shipping via bol but are using this schedule, the bol marketplace will mark your offer as "offline" as you are not participating in this proposition.

    • BOL_DELIVERY_PROMISE. this schedule refers to delivery promises that are predefined by bol. If you use this schedule, you also need to provide the deliveryPromise object. The following combinations are possible:

      • Delivered within 24 hours with a cut-off order time of 12:00 PM: minimumDaysToCustomer = 0. maximumDaysToCustomer = 1. ultimateOrderTime = 12:00

      • Delivered within 24 hours with a cut-off order time of 11:00 PM: minimumDaysToCustomer = 0. maximumDaysToCustomer = 1. ultimateOrderTime = 23:00

      • NOTE: The ultimateOrderTime accepts the following values: 12:00, 13:00, 14:00, 15:00, 16:00, 17:00, 18:00, 19:00, 20:00, 21:00, 22:00, 23:00

      • Delivered within 1 to 2 days: minimumDaysToCustomer = 1. maximumDaysToCustomer = 2.

      • Delivered within 2 to 3 days: minimumDaysToCustomer = 2. maximumDaysToCustomer = 3.

      • Delivered within 3 to 5 days: minimumDaysToCustomer = 3. maximumDaysToCustomer = 5.

      • Delivered within 4 to 8 days: minimumDaysToCustomer = 4. maximumDaysToCustomer = 8.

      • Delivered within 1 to 8 days: minimumDaysToCustomer = 1. maximumDaysToCustomer = 8.

      • NOTE: If the delivery takes longer than 1 day, you do not need to provide the ultimateOrderTime.

Stock levels within the stock object are tied to the fulfilment method. If you change the fulfilment.method in the future, the primary source for your stock level will also change. This means that stock related data will be lost if you change from FBR to FBB. As a consequence, you will need to provide the stock level again when switching back from FBB to FBR.

stock

The stock object indicates the amount of products that you have. Whether you need to provide this object depends on the type of offer that you are creating:

  • fulfilment.method = FBB: if you are creating an offer for stock via our "Logistics via bol" proposition, the warehouse manages your stock levels and inventory. In that case you do not need to provide the stock object. If you want to know how much stock there is left in our warehouse, you can use the FBB inventory endpoint.

  • fulfilment.method = FBR: if you are creating an offer for stock that you are fulfilling from your own (or 3rd party) warehouse, then you need to provide the amount of stock you have left in your warehouse and determine whether you want to manage stock levels yourself (by using the managedByRetailer flag). If you want the bol marketplace to manage your stock levels, you can set this flag to false. In that case, the bol marketplace automatically takes open orders into account by (temporarily) reserving a part of your stock, to avoid overselling. In case you set the managedByRetailer flag to true, the bol marketplace will not reserve stock for your already placed orders. Be aware that if you manage it yourself, your performance indicator might be impacted if you oversell and -as a consequence- fail to meet your delivery promise towards the customer.

You can update the stock levels anytime in the future.

Offer response

In case of a successful request to the bol marketplace, you will receive a response code with code 201. In the response you will also find the assigned offerId to this offer. Save this offerId as it is the unique key tied to this offer. All subsequent requests to bol require this offerId.

Get an offer

In order to retrieve your offer data, you can use this endpoint. Provide the offerId in the path and the bol marketplace will retrieve all your corresponding offer data if the provided offerId is known and valid to bol. The response includes all the data that you have provided upon creating this offer. See this section for an explanation of all the fields and object when creating an offer. Next to that data you will find the following additional data in the response:

Field Description

offerId

The unique identifier of this offer.

lastModifiedDateTime

The date and time when this offer was last modified, including an offset from UTC. The datetime is based on ISO-8601 standard.

stock.correctedStock

The amount of stock minus handled order items and minus open order items. When this reaches 0, your offer will be marked as "offline".

countryAvailabilities.forSale

Indicates if this offer is for sale in the corresponding country.

product.bolProductId

The bol marketplace identifier of the product.

offerId

The offerId is the unique bol identifier that is assigned to this offer. It is not possible to change the offerId.

lastModifiedDateTime

The lastModifiedDateTime is the timestamp in which this offer was updated last according to the bol marketplace. Be aware that the bol marketplace will update this timestamp if any change has impacted this offer. For instance, an offer is marked as offline initially, but right after that it becomes online again. It would mean like the offer itself hasn’t changed but this change can cause the lastModifiedDateTime to be updated.

The datetime is according to the ISO-8601 standard and includes an offset from UTC time.

stock

Within the stock object you will find the correctedStock field. The field applies to both an FBB and FBR offer. The value of this field will always be calculated, unless the stock.managedByRetailer flag is set to true for fulfilment.method = FBR offers. As the correctedStock field is calculated by the bol marketplace, it is not possible to update this field yourself. If you make a change to your stock level (stock.aoumt), the bol marketplace will recalculate the correctedStock. This might take some time.

In order to understand how the correctedStock is calculated, take a look at the examples below.

Table 1: FBR offer stock management where managedByRetailer = false

Event stock.amount stock.correctedStock Explanation

Retailer updates stock (@10:00:00)

10

10

Reservation (orderId=1) on bol marketplace (@10:10:00)

10

9

correctedStock -1

Retailer decreases stock (@11:00:00)

9

8

orderId=1 taken into account (no shipment/cancellation)

Customer cancellation (orderId=1) (@11:15:00)

9

9

correctedStock +1

Reservation (orderId=2) on bol marketplace (@11:20:00)

9

8

correctedStock -1

Retailer decreases stock (@11:30:00)

2

1

cancelled order (orderId=1) no longer taken into account. Open order (orderId=2) taken into account (no shipment/cancellation)

Shipment (orderId=2) (@11:40:00)

2

1

shipping an order does not change the correctedStock

Retailer decreases stock (@11:50:00)

1

1

cancelled order (orderId=1) no longer taken into account. Shipped order (orderId=2) also no longer taken into account. Shipped and cancelled orders are no longer taken into account after update

Table 2: FBR offer stock management where managedByRetailer = true

Event stock.amount stock.correctedStock Explanation

Retailer updates stock (@10:00:00)

10

10

Reservation (orderId=1) on bol marketplace (@10:10:00)

10

9

correctedStock -1

Retailer decreases stock (@11:00:00)

9

9

open order (orderId=1) not taken into account

Customer cancellation (orderId=1) (@11:15:00)

9

9

customer cancellation (orderId=1) not taken into account

Reservation (orderId=2) on bol marketplace (@11:20:00)

9

8

correctedStock -1

Retailer decreases stock (@11:30:00)

2

2

cancelled order (orderId=1) not taken into account. Open order (orderId=2) not taken into account

Shipment (orderId=2) (@11:40:00)

2

2

shipping an order does not change the corrected stock

Retailer decreases stock (@11:50:00)

1

1

cancelled order (orderId=1) not taken into account. Shipped order (orderId=2) also not taken into account

countryAvailabilities

Within the countryAvailabilities object you will find the forSale field. The forSale field will indicate if this offer is for sale in the corresponding country, based on the countryCode. The forSale flag is only present for the countries this offer is listed in. It is also not possible to update this field yourself.

Note that changes in the bol marketplace might cause your offer to be reevaluated at certain times. If you want to know when a change has taken place you can use our Subscription API and subscribe to our FOR_SALE and NOT_FOR_SALE events.

product

Within the product object, you will find the bolProductId field. This field refers to the product id of the bol marketplace. It cannot be changed and is the uniquely assigned identifier for each product at bol.

Get offers

This endpoint allows you to search offer related data from the bol marketplace. To do this efficiently, you can use any of the following query parameters.

Query parameter Description

offer-ids

Search offers based on a set of `offerId’s. A maximum of 100 `offerId’s is supported.

eans

Search offers based on a set of `ean’s. A maximum of 100 `ean’s is supported.

reference

Search offers based on a reference that you defined yourself when creating an offer.

for-sale

Search for offers that are for sale in the Netherlands, Belgium or both.

last-modified-date-time

Search for offers that have changed since the last modified date time with an offset from UTC. The datetime is according to ISO-8601 standard.

page-size

The number of offers per page.

cursor

The cursor token to retrieve the next page of this search.

In the response, you will find the following additional metadata.

Field Description

page (object)

Metadata that describes the page size and provides the nextCursor.

page

Within the page object, you will find two fields:

  • pageSize - refers to the page size you provided in the page-size query parameter.

  • nextCursor - refers to the cursor token to retrieve the next page of this search. If you have reached the last page, the nextCursor is null.

Get not for sale reasons

When you create or update an offer on the bol marketplace, this offer will be validated against the platform policies of bol. When this process is done, and the offer is marked as offline (not for sale), you can fetch the details via this endpoint. The offerId must be provided in the path.

If you want to know when the processing of your newly created (or updated) offer is completed you can use our Subscription API. Subscribe to our FOR_SALE and NOT_FOR_SALE event.

Field Description

offerId

The unique identifier of this offer.

countries (object)

The countries in which this offer is potentially offline.

reasons (object)

The reasons why your offer is marked offline.

offerId

The offerId is the bol identifier that is uniquely assigned to this offer. You cannot change the offerId.

countries

With the countries object, you will find the countryCode field and the corresponding reasons for for this country. The countryCode field refers to the country in which you want to sell this offer (NL for the Netherlands and BE for Belgium). You provided this when creating an offer, or it is taken from you Retailer account setting.

Not-for-sale (offline) reasons apply per country. This means that, when you create an offer for both NL and BE, your offer can be offline within Belgium (forSale = false), but online within the Netherlands (forSale = true). In this endpoint, you will only see reasons if there is at least one offer offline in any of the two countries. In this case, you will therefore only find reasons for countryCode with NL.

In case your offer is online completely, you will not receive any content in this endpoint. Also it is not possible to update or change the data in this endpoint.

reasons

The reasons object contains a code field, and a description field. The code field is a unique number assigned to this reason. Based on this code, you can define a solution that could automatically resolve this reason. The code is explained functionally by the description field, which can be used to understand why this offer is offline. If all the reasons are resolved, your offer should normally go online.

When it comes to offline reasons, it is good to take note of the following:

  1. Not all reasons can be resolved by the retailer itself. This can for instance happen because your offer contains a product that is not allowed to be sold on the bol marketplace. In such a situation, there is no way for you, as a retailer, to resolve this reason.

  2. Different resolutions can resolve the same reason. For instance, if an offer runs out of stock, you can either choose to switch to another fulfilment method or increase the stock levels for this offer. Both will likely resolve this offline reason.

  3. Reason A is more important than reason B. The bol marketplace stops processing an offer if a specific reason is considered more important than another reason. When this reason is resolved, the bol platform will continue processing as usual. However, if, during that process, a new reason pops-up, you will encounter a new offline (not-for-sale) reason that was previously not visible.

Updating an offer

There can be several reasons to update an offer. The most common use cases to update (parts of) an offer is usually price or stock related. To update an offer, you will need to add the offerId to the path in this endpoint.

Please read this page carefully before continuing to avoid possible data loss.

The PATCH implementation can vary per marketplace. Below it is described how a specific payload is interpreted at the bol marketplace. It is good to follow these conventions:

  • Omitting an attribute: not specifying an attribute in the PATCH endpoint means the fields won’t be updated.

  • Sending null within your payload is treated as:

    • For fields: "empty this field". If a previous value was present, it will be cleared.

    • For (nested) objects: not possible.

    • For arrays: not possible, except for the countryAvailabilities field.

  • Sending an empty string "" within your payload is treated as:

    • For fields: "" is considered a value. If a previous value was present, it will be overwritten with this new value.

    • For arrays: not possible.

Keep in mind that:

  • Arrays are interpreted as a full replace. If you want to add or remove an element to the array, you are required to send all elements in the array, even if they already existed before.

  • A boolean field can never be set to null.

  • Enumerations can never be set to null.

  • Required fields can never be set to null.

bol either accepts or rejects the whole request. If a part of the payload is correct and a part of the payload is incorrect, the whole request will be rejected. See our Offer API use case guide for specific use cases.

Update a field

If you want to update a field with a new value, like the reference field, you can send this new value to the PATCH endpoint. For instance, if the value for the reference field is currently This is my first reference and you want to update it to This is my second reference, you can send the following payload to this PATCH endpoint:

{
 "reference": "This is my second reference"
}

If you want to delete the value for the reference field, you can send the following payload:

{
 "reference": null
}

If you want to remain the value of the reference field you omit this field from your payload. If the field is defined as an enumeration, you cannot set this field to null or "".

Update a boolean

If you want to update a boolean field like the onHoldByRetailer, you send a new value. For instance, if you want to set the onHoldByRetailer flag to true, you send the following payload:

{
 "onHoldByRetailer": true
}

If you want to remain the value of the onHoldByRetailer field you omit this field from your payload. You cannot set this field to null or "".

Update an array

If you want to update an array, like the countryAvailabilities, you are required to send the whole array. This array will replace the previous array. For instance, you want to sell this offer in both the Netherlands (countryCode = NL) and Belgium (countryCode = BE). Currently, this offer is only available in Belgium (countryCode = BE). To achieve this, you need to send the following payload:

{
  "countryAvailabilities": [
    {
      "countryCode": "NL"
    },
    {
      "countryCode": "BE"
    }
  ]
}

It is not possible to send null or "" to bundlePrices (a price is always required), but for countryAvailabilities object this is allowed.

Update an object

If you want to update an object, you can send the fields within that object that you want to update. Whether a field is within an object or not, does not affect the way they are processed. If a field (or nested object) is required within the object you want to update, you are required to send it as well.

For instance, you want to update the fulfilment schedule. Within this schedule, the method field is required. Therefore, you need to send the method field as well:

{
  "fulfilment": {
    "method": "FBR",
    "schedule": "MY_DELIVERY_PROMISE"
  }
}

Updating more than one field at the same time

If you want to update your stock level as well as your selling price, you can provide both objects in one single request. For instance, you want to set the price per piece to 9.99 euro and your amount of stock needs to be adjusted to 46. The quantity and unitPrice fields are mandatory, so they need to be present in the payload.

To achieve this, you can send the following payload to the bol marketplace:

{
  "pricing": {
    "bundlePrices": [
      {
        "quantity": 1,
        "unitPrice": 9.99
      }
    ]
  },
  "stock": {
    "amount": 46
  }
}

Deleting an offer

If you want to delete an offer, you only need the offerId and this endpoint that allows deletion of an offer. The offerId can be attached to the path parameter. When the offerId is known to bol and successfully delete, you will receive a 204 code. From that moment, you cannot update this offer anymore or retrieve it from the bol marketplace.