Subscriptions
Subscriptions are a mechanism that allows consumers to receive regular updates or notifications about specific services or applications. Subscription notifications are messages or alerts sent to users who have subscribed to a particular service or product. They enable you to receive relevant events via push notifications in real-time. By subscribing to events of your interest, you can ensure that you stay informed and promptly receive updates when these events occur.
Subscriptions that are not working correctly for an extended period of time, will be automatically disabled. You can re-enable the subscription yourself via the Update Event Notification Subscription endpoint. The conditions under which we disable subscriptions are as follows:
For all the above scenarios, we will retry delivery 10 times over a period of 10 minutes. Should the destination of the subscription be unreachable for that time frame, we will automatically disable the subscription. |
How can they help?
Subscribing to relevant events can enhance the functionality and user experience of your applications significantly benefiting you in the following ways.
Subscriptions helps you in:
-
Receiving near real-time updates ensuring that your application data and user interfaces are up-to-date.
-
Retrieving data efficiently thereby reducing the unnecessary data requests and optimizing the resource usage.
-
Simplified integration by reducing the complexity of handling data updates.
-
Scalability of applications by handling events asynchronously, leading to better performance and responsiveness.
Subscriptions API endpoints
The Subscriptions API offers the following endpoints:
Delivering subscription notifications
Subscriptions are delivered to users through the following communication channels, depending on the nature of the subscription and user preferences.
The delivery methods for subscription notifications include:
-
Webhooks - Signifies an endpoint on the user’s side that receives a message whenever a subscribed event takes place.
-
Google Cloud Platform (GCP) Pub/Sub - Enables the asynchronous queuing of messages on the partners' own GCP project, providing a safer, more efficient and reliable solution compared to webhooks.
Hosting Pub/Sub topics may incur additional costs. -
Amazon Web Services (AWS) SQS - Like Pub/Sub above, SQS enables asynchronous queing of notifications on the partner’s AWS project, providing an integrated, secure, efficient and reliable solution.
Subscription service features
The subscription service offers the following features:
-
At-least-once delivery - To ensure maximum reliability, we implement at-least-once message delivery. As a result, there is a possibility of receiving the same message multiple times.
Ensure that your system is equipped to accommodate such scenarios. To facilitate this, one approach is to maintain a record of processed messages on your side. This would allow you to track and avoid reprocessing duplicate messages, ensuring the efficiency of your system.
-
Retry mechanism - In cases where the first delivery attempt of the message fails, the system will initiate nine subsequent retries with an increasing accumulated interval between each retry. This strategy aims to improve the chances of successful message delivery. This mechanism is also known as "exponential backoff".
Following the ten retries, if the message still remains undelivered, further delivery attempts will not be made, and the message will be dropped. As an alternative approach, you can always use the respective GET endpoints provided by the Retailer API for retrieving the required information as a fallback scenario. |
-
Possible race conditions - There is a possibility of messages arriving in the incorrect order.
For instance, consider the scenario where Message A and Message B, both associated to the same process, encounter failures during delivery. The retries for Message A failed twice, while the retry for Message B failed once.
Later, assuming that your system becomes operational during this time, Message B may be retried after 2 minutes, while Message A will be sent after 4 minutes.
To facilitate verification of such situations, a timestamp is included in the message. This allows you to track and assess the timing of message deliveries.
The timestamp provided in the message represents the time of the event being processed within the landscape, and not the time when the message was sent.
Supported event types
Event types are the different categories or classifications of events that you can subscribe to receive notifications about. When subscribing you can customize the types of updates and notifications you wish to receive as per your requirements.
Different delivery methods support different types of events. The table below displays all the supported delivery methods for each event type.
Subscription event type | Supported delivery method |
---|---|
Webhooks GCP Pub/Sub AWS SQS |
|
Webhooks GCP Pub/Sub AWS SQS |
|
GCP Pub/Sub AWS SQS |
|
GCP Pub/Sub AWS SQS |
Process status subscription
The PROCESS_STATUS
subscription event provides information about the status of an asynchronous request towards Retailer API and offers the following types.
Event name | Description |
---|---|
|
The request was successfully completed. |
|
The request failed. Examine the process status error message for more information. |
|
The request timed out. This means the downstream service was unable to process all the requests in a specified timeframe, and therefore we timed out your request. |
An example of a push message after creating a process status subscription is provided below.
{
"retailerId":1234567,
"timestamp":"2020-02-02T23:23:23+01:00",
"event":{
"resource":"PROCESS_STATUS",
"type":"SUCCESS",
"resourceId":"1234567"
}
}
The event.resourceId
in this message is the processStatusId
from the call.
Shipment subscription
The SHIPMENT
subscription event allows you to monitor shipment status of the order, and has the following types.
Event name | Description |
---|---|
|
A shipment has changed its shipment status. |
The resourceId
in the message body is the shipmentId
which you can use with the Get a shipment by shipment id endpoint to see in detail what changed in the transport.transportEvents
element.
An example of a push message after creating an update transport event subscription is provided below.
{
"retailerId":1234567,
"timestamp":"2020-02-02T23:23:23+01:00",
"event":{
"resource":"SHIPMENT",
"type":"UPDATE_TRANSPORT_EVENT",
"resourceId":"0837872b-f805-45f3-8f60-3233ea933ed7"
}
}
Price star boundary subscription
The PRICE_STAR_BOUNDARY
event type sends a message whenever a retailer has a sellable offer for a product with updated price star boundaries.
In the notification, you receive the EAN of the product that has undergone changes in its price star boundaries. Use this EAN to retrieve the updated boundaries by using the Get price star boundaries by EAN endpoint.
For more information on price star boundaries, see the functional documentation.
This subscription event has the following types:
Event type | Description |
---|---|
|
Indicates that a change in price star boundaries has occurred for a product you are offering. |
An example of a push message after the price star boundary of a product has changed is given below:
{
"retailerId": 1234567,
"timestamp": "2020-02-02T23:23:23+01:00",
"event": {
"resource": "PRICE_STAR_BOUNDARY",
"type": "CHANGE",
"resourceId": "0045496429577"
},
"metadata": {
"BPID": "9300000079089746",
"country": "NL",
"ean": "0045496429577"
},
"links": [
{
"url": "https://api.bol.com/retailer/products/0045496429577/price-star-boundaries",
"method": "GET"
}
]
}
The event.resourceId
within the message corresponds to the EAN of the product for which the boundary has been updated.
The metadata.BPID
in the message corresponds to the bol product ID for this product.
Competing offer subscription
The COMPETING_OFFER
event type sends a message whenever a retailer has a sellable offer for a product, and any of the competing offers have undergone changes.
Every notification will include the corresponding EAN linked to the updated competing offers. Use this EAN to fetch the most recent competing offers using the Get a list of competing offers by EAN endpoint.
For more information on competing offers, see the functional documentation.
The following fields are subject to potential changes:
-
offerId
-
retailerId
-
countryCode
-
bestOffer
-
price
-
fulfilmentMethod
-
condition
-
ultimateOrderTime
-
minDeliveryDate
-
maxDeliveryDate
This subscription event has the following types:
Event type | Description |
---|---|
|
Indicates that a change in competing offers has occurred for a product you are offering. |
An example of a push message after the competing offers of a product have changed is given below:
{
"retailerId": 1234567,
"timestamp": "2020-02-02T23:23:23+01:00",
"event": {
"resource": "COMPETING_OFFER",
"type": "CHANGE",
"resourceId": "0045496429577"
},
"metadata": {
"BPID": "9300000079089746",
"country": "NL",
"ean": "0045496429577"
},
"links": [
{
"url": "https://api.bol.com/retailer/products/0045496429577/offers",
"method": "GET"
}
]
}
The event.resourceId
within the message corresponds to the EAN of the product for which the competing offers have been updated.
The metadata.BPID
in the message corresponds to the bol product ID for this product.
If your offer becomes unsellable, you still receive one final notification abut the competing offers that have undergone changes. |
Configuring the subscriptions
This section describes how to configure Webhooks and GCP Pub/Sub individually.
Webhooks
Requirements
For security purposes, only webhooks registered on the https domain are accepted.
Attempting to register a webhook without using SSL is not possible and will result in an error during the subscription process. |
Logical process flow
The following diagram describes the logical flow of connecting to the PROCESS_STATUS
webhook:

Configuring Webhooks
Follow the steps below to connect to the subscriptions:
1. Creating the webhook
Create a webhook using a http address that can effectively receive the events you wish to subscribe to.
Ensure that your constructed endpoint can handle and process the incoming events effectively. For more information on the supported events, see Receiving events.
2. Subscribing to events
After successfully implemented your webhook, subscribe your endpoint to the Subscription API.
For more information on how to create a subscription, see Create push notification subscription endpoint.
Alternatively, you could also choose to update your current subscription using the Update push notification subscription endpoint.
3. Receiving process status
The Create push notification subscription endpoint works asynchronously and returns the processStatusId
which can be used as an input parameter to the Get the status of an asynchronous process by process status id endpoint to retrieve the current processing status of the request.
The value of the entityId
field corresponds to the subscriptionId
.
4. Receiving events
Once you have created your endpoint and subscribed to an event, you will start receiving messages.
The shipment events will notify you whenever there is an update to a transport event.
There is a possibility of messages arriving in the incorrect order or experiencing non-delivery due to timeouts or other issues on either side. For more information, see here. |
GCP Pub/Sub
Requirements
To use Pub/Sub, a GCP (Google Cloud Platform) account is required. Additionally, the following prerequisites are necessary:
-
A Pub/Sub topic (or topics) that can receive messages from sources outside your Virtual Private Cloud (VPC).
-
Appropriate permissions to grant access to this topic (or topics).
Configuring GCP Pub/Sub
Follow these steps to start receiving event notifications on your Pub/Sub topic:
-
Create a standard Google Cloud Platform (GCP) Pub/Sub topic. To illustrate the process, henceforth, this topic is referred as
my-topic
. -
On the
my-topic
Pub/Sub topic, grant theroles/pubsub.publisher
permission to thepusher-service-account@bolcom-pro-pusher-69b.iam.gserviceaccount.com
service account. -
Create a subscription using the Create push notification subscription endpoint and perform the following:
-
Set the value of the
subscriptionType
field asGCP_PUBSUB
. -
Use the fully qualified name of your topic as the URL. For example,
projects/my-gcp-project-123/topics/my-topic
.
-
-
Once done, the notifications will start arriving within an approximate period of 15 minutes.
For more information on the subscription types, see Supported event types.
NOTE:
-
Much like with webhooks, messages coming in on Pub/Sub also contain a
Signature
andUser-Agent
in the message attributes. You can verify the signature in exactly the same way you currently do for webhooks. For more information, see this section. -
As Pub/Sub offers at-least-once delivery, it is essential to account for this in your application’s design and implementation.
-
After creating or deleting an offer, it may take a few minutes before notifications start or stop arriving.
AWS SQS (Beta)
Using AWS SQS subscription type is in Beta and may be subject to changes. |
Requirements
To use AWS SQS, an AWS account is needed. Additionally, the following permissions are necessary:
-
Permissions to
-
create a new role,
-
create an identity provider (IdP),
-
create an SQS queue that can receive messages from sources outside of your VPC perimiter (this queue must reside in one of the EU regions -
eu-central-1
,eu-central-2
,eu-west-1
,eu-west-2
,eu-west-3
,eu-north-1
,eu-south-1
oreu-south-2
.), and -
allow a role to publish to the SQS queue.
-
Configuring AWS SQS for use with Bol notifications
We highly recommend creating a role with either an inline policy or a purpose-built policy that restricts this role to only being able to publish to dedicated "Bol-specific" SQS queues. Do not grant this role access to any other resources, as Bol cannot be held responsible for potential misuse of this role. |
In order for Bol to be able to publish to your AWS SQS topic(s), you need to configure a trust relationship between your AWS IAM Role and the Bol GCP Service Account we use to publish these events. At a high level, the architecture looks like this:

Follow these steps to start receiving event notifications on your AWS SQS topic:
-
First, you can configure a trusted Identity Provider (IdP). This is optional, as you can also input the federation target (
accounts.google.com
) directly when creating the role in the next step.-
Navigate to
IAM
→Access Management
→Identity Providers
-
Click
Add Provider
-
Select
OpenID Connect
as theProvider Type
-
Input
https://accounts.google.com
as theProvider URL
-
Input
116790978013053194331
as theAudience
-
Note that these must be entered exactly as shown
-
-
-
Next, we’ll set up the IAM Role. This role will be assumed by Bol’s internal service in order to publish messages to your SQS queue.
-
Navigate to
IAM
→Access Management
→Roles
-
Click on
Create Role
-
In the
Trusted entity type
, selectWeb identity
. -
From the
Identity provider
dropdown, either select the IdP you created in the previous step, or simply selectGoogle
. -
If you selected
Google
, enter116790978013053194331
in theAudience
text box. This refers to the unique ID of the GCP Service Account in use by Bol, that will be used to publish notifications. -
Click
Next
. We’ll assign permissions later, but you can do it now if you already have a policy for the intended target SQS queue. -
Give the role a useful name and description.
-
Click
Finish
. -
Navigate to the newly created role and note down its
ARN
; you’ll need it in the next step.
-
-
Next, we’ll create the SQS queue.
-
Navigate to the
Simple Queue Service
(SQS
) -
Click
Create queue
on the top right -
The options here are unique to your use case. The only option we recommend is that the
Maximum message size
be set to at least 16KB. Our notifications (at the time of writing) should be no more than 1KB in size, but future changes may be introduced that could increase this size. You will of course be notified of any such change ahead of time. -
Scroll down to the
Access policy
section.-
Under
Define who can send messages to the queue
, selectOnly the specified AWS accounts, IAM users and roles
and enter the role’sARN
from the previous step. -
Ensure that you assign the appropriate read permissions, as is applicable to your application(s).
-
-
Click
Create queue
-
You should now be ready to register a AWS SQS subscription. Head down to the creating a subscription section for more details.
Request signing
Messages sent from bol through push notifications can be verified using digital signatures. This allows you to ensure that the messages were not tampered with through means such as man-in-the-middle attacks, and prevents abuses of your public endpoints by third parties flooding your endpoints with bad requests.
The signature header in webhook messages can be extracted to verify the origin and contents of the message. This signature is added by signing a request body with a public/private keyset. The private key is used by bol for creating the signature, while the public key is used by the partner for verification. You can use the public keys you retrieve from the bol API to verify the signature provided in requests to your public endpoints, after which you can commence with your transactions.
Signature header structure
An example of the signature header sent to you is provided below:
Signature: keyId=0, algorithm="rsa-sha256", signature=<SIG>
The three elements in the signature are:
-
keyId
- Specifies the ID for the keyset that is used to create the signature. We have built a method to create new keysets once the old ones become compromised through getting leaked or hacked. -
Algorithm
- Specifies the algorithm used to create the signature. In our case we use a static value ofrsa-sha256
. For more information see RSA-SHA256 signatures. -
Signature
- Specifies the created signature that can be verified by the recipient of the message. The signature is sent as a Base64 encoded UTF-8 string. Depending on the library doing the verification, the signature might need to be Base64 decoded before it is validated.
Retrieving public keys from the Subscription API
The keys referenced in the signature are available from the Subscription API.
For more information on how to retrieve them, see Retrieving public keys for signature validation.
Validating the signature
The SHA256 algorithm calculates a unique hash of the input data, then encrypts the hash with the private key. To verify the authenticity of the message, you should:
-
Calculate a hash of the same data using the public key.
-
Decode the hash from Base64 using the public key and load it as an X.509-spec key.
-
Compare the hash values. If they match, the signature is considered valid. If they don’t match, it either means that a different key was used to sign it, or that the data has been altered.
The following code sample validates the signature of a request to use as a baseline for the implementation - you can adapt it to your programming language of choice. No additional libraries beyond the standard JVM are required:
String subscriptionKey = "PUBLIC_KEY_STRING_RETRIEVED_FROM_SUBSCRIPTION_ENDPOINT";
// Retrieve the key from merchant, decode it with the Base64 decoder.
byte[] encodedKey = Base64.getDecoder().decode(subscriptionKey.getBytes(StandardCharsets.UTF_8));
// Load the public key, use the SHA256withRSA instance and load it as an X509KeySpec
PublicKey publicKey = KeyFactory.getInstance("SHA256withRSA").generatePublic(new X509EncodedKeySpec(encodedKey));
// Given the following extracted signature from the request header
String signature = "SIGNATURE_FROM_PUSH_NOTIFICATION_HEADER";
// And the message body sent to the push notification endpoint
String body = "Message body";
// Decode the signature and convert it to a byte array
byte[] signatureBytes = Base64.getDecoder().decode(signature.getBytes(StandardCharsets.UTF_8));
// Verify the signature using the public key created earlier
final Signature sha256RsaSignature = Signature.getInstance("SHA256withRSA");
// Initialize the signature with the publickey
sha256RsaSignature.initVerify(publicKey);
// Add the bytes string conversion of the signature header
sha256RsaSignature.update(signatureBytes);
// Verify the signature, this function will return true for valid signatures
boolean result = sha256RsaSignature.verify(body.getBytes(StandardCharsets.UTF_8));
Supported operations
Creating a subscription
Use the Create push notification subscription endpoint to create a subscription.
Make the following request:
POST /retailer/subscriptions
An example of the request is provided below:
{
"resources": ["PROCESS_STATUS"],
"url": "https://www.bol.com/webhook"
}
To create a GCP Pub/Sub subscription, make the following request
{
"resources": ["PROCESS_STATUS", "COMPETING_OFFER"],
"url": "projects/my-project-id/topics/bol-pubsub-topic", (1)
"subscriptionType": "GCP_PUBSUB"
}
1 | This is the full path to your Pub/Sub topic. |
To create an AWS SQS subscription, provider the following JSON:
The SQS Queue must reside in one of the EU regions. |
{
"resources": ["PROCESS_STATUS", "COMPETING_OFFER"],
"url": "https://sqs.eu-central-1.amazonaws.com/12341234/bol-sqs-queue", (1)
"subscriptionType": "AWS_SQS",
"identity": "arn:aws:iam::12341234:role/bol-sqs-role" (2)
}
1 | This is the URL to your SQS queue. It must reside in one of the European regions. |
2 | This is the ARN for the role you created for Bol to assume. |
This endpoint returns a response with a process status, as you are used to from our other API calls. Once it’s successfully processed you get the subscriptionId
that corresponds to the entityId
in the process status response with which you can do the following operations.
For more information on the request and response body, see the Redoc.
Receiving subscription notifications
Use the Get push notification subscriptions endpoint to retrieve a list of all the configured and active push notification subscriptions.
For more information on the request and response body, see the Redoc.
Receiving a subscription by ID
Use the Get push notification subscription by id endpoint to fetch a subscription by its subscription-id
and verify its details.
An example of the response is provided below:
{
"id": 1234,
"resources": ["PROCESS_STATUS"],
"url": "https://www.bol.com/webhook",
"enabled": true
}
For more information on the request and response body, see the Redoc.
Testing a subscription
Use the Send test push notification for subscriptions endpoint to test your subscriptions using your subscription-id
.
When a subscription exists for a retailer, a response message will be sent to the corresponding topic/URL.
For more information on the request and response body, see the Redoc.
Updating a subscription
Use the Update push notification subscription endpoint to modify an existing subscription by its subscription-id
.
For example, you can use this to change the address of your endpoint or the event types that you want to subscribe to.
An example of the request body is provided below:
{
"resources": "['PROCESS_STATUS']",
"url": "https://www.bol.com/webhook",
"subscriptionType": "WEBHOOK",
"enabled": true (1)
}
1 | Note that this field is optional and will be set to true if not provided. |
For more information on the request and response body, see the Redoc.
NOTE
-
To remove a specific resource from the subscription, submit the list of resources you want to subscribe to, excluding the one you wish to remove.
-
To add a new resource, submit the entire list of resources you wish to subscribe to, including the new one you intend to add.
Deleting a subscription
Use the Delete push notification subscription endpoint enables you to delete an existing subscription entirely by subscription-id
.
For more information on the request and response body, see the Redoc.
Retrieving public keys for signature validation
Use the Retrieve public keys for push notification signature validation endpoint to retrieve a list of public keys that should be used to validate the signature header for push notifications.
Upon making the request, you will receive a list of public keys. It is advisable to cache these keys since they do not frequently change. However, if you encounter a message signed with a new keyID that is not present in your cached list, you can request the keys again to obtain the public key that belongs to that specific keyset.
An example of the response from the Retailer API is provided below:
GET /retailer/subscriptions/signature-keys
{
"signatureKeys": [{
"id": "0",
"type": "RSA",
"publicKey":"PUBLICKEY"
}]
}
The contents of this response are:
-
id
- Specifies the ID of the keyset with the referencekeyId
in the signature header. -
type
- Specifies the type of key. In this case, it is an RSA public key. -
publicKey
- Specifies the Base64 encoded X.509 public key. To load it, first decode it from Base64 and then load it as an X.509-spec public key.
For more information on the request and response body, see the Redoc.
IP Whitelisting
These are the public IP addresses from which we publish messages that you can whitelist if needed. Although this list is static, it is not guaranteed that these IP addresses remain the same over time. IP addresses can either be removed or added to this list.
35.204.245.136
35.204.195.116
35.204.156.102
35.204.83.251
35.204.231.62
34.90.203.104
34.90.109.47
34.91.34.58
34.91.134.228
34.91.91.54