Step-by-step instruction for Cumulocity Notification 2.0


Cumulocity Notification 2.0 is the latest version of the notification API. It is an improved version of Cumulocity real-time notification API with stronger delivery semantics and ordering guarantees. To be able to receive the real-time notifications, a consumer application or microservice needs to first create a subscription and obtain a token from the messaging service hosted by Cumulocity IoT.

In this article, you will learn some relevant definitions and how to use the Cumulocity Notification 2.0 API.


Before you start, please confirm:

  • your user account has ADMIN permission for the permission type “Notification 2”
  • Cumulocity Messaging Service needs to be enabled (only need to check when the cloud instance older than 10.13, dedicated and self-hosted instances older than 10.11)
  • Shared token only supported from 10.16



The subscription defines the scope (context and source ID) and type (API) of notifications that will be forwarded to the specific topics. The subscripition is created by sending a request to the Notification 2.0 subscription API /notification2/subscriptions with the JSON format definition in the request body.
A subscription is identified by a subscription name, which must be declared in the request body. The request body also requires the value of ‘context’ to be specified. This determines whether the subscription is for a single device or for the entire tenant. If the value of the context is ‘tenant’, which means the subscription is for the whole tenant, then the device ID is not required. If the value of the context is mo, which represents managedObject, then the device ID must be given in the source. Optionally, you can filter the notifications for specific APIs or types using subscriptionFilter. For more information please check the OpenAPI Specification of Cumulocity.

Consumer client

Consumer client can be an application or microservice that you build. With a valid token, the consumer client will receive messages that match the scope specified in the subscription. When you establish the WebSocket connection, you can name the consumer clients in the request header of consumer protocol as an optional parameter to distinguish them. E.g. notification2/consumer?token=xyz&consumer=instance1. If a consumer client uses the shared token, it is a client of shared consumer.


When a token is created using the Token API, a consumer is created in the Cumulocity messaging service at the same time. Subscriber field in the request body identifies the consumer. When unsubscribing a subscriber, the appropriate token is required in the request parameters. If the token is the type of shared, one token can be used by multiple clients of one shared consumer.


The token is used to authorize the consumer to ensure that the holder is allowed to connect and receive the subscription notifications. It has a dedicated Rest API to create the token:
The subscriber name and subscription name must be specified in the body of the request. The subscription name should be the same as the name used to create the subscription.
You can also set the expiration time and type of token in the request, as well as whether the token is signed and whether it is persistent.
Starting from Cumulocity IoT 10.16, C8Y Notification 2.0 supports the creation of shared tokens. Shared tokens allow one important pattern: The parallelization of the consumer client workload for a notification subscription. When a shared token used by multiple consumers, every notification will be sent to one of the consumers based on a implemented shared algorithm according to the ID of the source. All notifications for a given ID will be delivered to the same consumer. This can be helpful when the consumer can’t process notifications faster than they arrive for multiple IDs.


A secure WebSocket connection is used to consume notifications by a consumer client. The C8Y tenant domain is the endpoint for the WebSocket connection, but the URI schema https:// or http:// should be replaced by wss:// or ws://. The URL path for creating connection is /notification2/consumer/ . There is one required argument, the token collected from the platform. You can also add the customer client’s name here as an argument. To keep the WebSocket connection alive for a long time, you should let the client send a ping message to the server regularly. In case of connection interruption the client should implement a reconnect function.

Get started with Notification 2.0

Here I will show you the basic steps to create the Notification 2.0 connection using a Python script. Of course, you can follow these steps with any other programming language. First, let’s see how to collect notifications using an exclusive consumer.

Create a subscription

The first step is to create a subscription using subscription API of Notification 2.0:

POST /notification2/subscriptions

In the request payload, you need to define the scope of notifications that you would like to receive. It is achieved by the context and subscription filter in the payload. You can subscribe to a specific device using context = mo, or create a subscription across the entire tenant scope with context = tenant. When the context is mo, the device ID is required in the request body. And the subscription filter is available for “alarms”, “alarmsWithChildren”, “events”, “eventsWithChildren”, “managedobjects”, “measurements” and “operations” when context is mo, while tenant context supports “alarms”, “events” and “inventory” subscription filter.
You can appoint the type of data to subscribe to. typeFilter further narrows the scope of a subscription. You can specify one type or use operator or to specify multiple types.

Here is an example of subscription payload with tenant context and filters:

subscription_json = {
    "context": "tenant",
    "subscription":  "SubscriptionA",
    "subscriptionFilter": {
        "apis": [
        "typeFilter": "'c8y_BootEvent' or 'c8y_UnavailabilityAlarm'"

Here is an example subscription payload for mo context:

subscription_json = {
    'context': 'mo',
    'subscription': 'SubscriptionB',
    'subscriptionFilter': {
        'apis': [
        'typeFilter': 'c8y_Measurement'
    'source': {
        "id": "12345"

When you create the subscription successfully, you will get a response with the id of the subscription. It’s useful for the following steps.

Create a token

To be able to receive the notifications, a token should be first obtained from the token API of Notification 2.0:

POST /notification2/token

The payload of this request requires subscription name and subscriber name. The subscription name must match the name of the subscription created earlier.

Here is an example of token request payload:

token_json = {
    'subscription': 'SubscriptionA',
    'subscriber': 'Subscriber1'

If you create the token successfully, you will receive a response containing a token string.

Establish the connection

Now you should have all you need to establish the WebSocket connection. First don’t forget to check the URI schema to ws:// or wss://. I used Python library websocket-client to create a long-lived connection.

ws_client = websocket.WebSocketApp(
    C8Y_BASEURL_WEBSOCKET + '/notification2/consumer/?token=' + token_response['token'],
    on_open = open_handler,
    on_message = message_handler,
    on_error = error_handler,
    on_close = close_handler
ws_client.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE}, ping_interval=30)

As you can see in the example above, a WebSocket client has been created using the consumer API of Notification 2.0 with the token. If there are new data generated by REST or MQTT APIs and they meet the subscription scope, the web socket client will get the notifications. The message_handler function will send acknowledgement and get notifications.

Stop the connection

If you only close the WebSocket connection, the subscription will still exist. Then the notifications come after the disconnection will buffered on the platform. So to prevent unnecessary usage of the platform resources, don’t forget to delete the subscription and unsubscribe the subscriber when you stop the connection.
First, delete the subscription. It will stop the buffering of the new notifications. The ID here is the subscription ID you reserved when you created the subscription.

DELETE /notification2/subscriptions/{id}

Then, unsubscribe the subscriber. It will delete the buffered notifications. Note, that the token does not have to match the token you’ve used to initially connect. You can just create a new token with the same payload for that purpose if desired.

POST /notification2/unsubscribe/?token={{the-token}}

Notification 2.0 with shared token

Here you will need two Python scripts to subscribe to Notification 2.0 to simulate two consumers. The shared token for now only supports the mo context.
Notifications are delivered to all consumers based on the device ID. Notifications with the same device ID are sent to the same consumer. This means that the more devices there are, the more evenly the notifications will be distributed.
Then you might ask if you need to create separate subscriptions and tokens for each device. The answer is yes, you need to send separate requests to create subscriptions for each device but with the same subscription name and same subscription settings (context and subscription filter). Then you only need to create one subscriber for all the subscriptions and obtain the token. When this token is shareable, multiple consumers will receive the notifications from different devices.

Create the subscriptions and the first consumer

In this case, you need to prepare some more devices and create subscription for each device with the same subscription name.
Compared to creating a exclusive consumer, creating the first consumer with a shared token requires an additional declaration of the shareable property of the token. For this you need to add a key-value pair 'shared': True in the request payload for creating the token. You can follow the instruction above and add the following parts.

token_json = {
   'subscription': 'SubscriptionA',
   'subscriber': 'Subscriber1',
   'shared': True

In order to identify the consumer and keep the notifications with their consumers when the connection is broken, it is recommended to define the consumer name when you connect the WebSocket.

wss: {{cumulocity-domainname}}/notification2/consumer/?token={{shared-token}}&consumer={{uniqueconsumername}}

You need to keep the shared token for other consumers.

Create the second consumer

As the subscriptions and token have been created during the creation of the first consumer, this consumer (or more other consumers) only need to establish the WebSocket connection with its name and the same shared token. As the first consumer covers the subscription deleting and subscriber unsubscribing, it’s not required to perform them here.

Test the consumers

Now, when you create some data that covered by the subscriptions using REST or MQTT APIs, both of the consumers will receive notifications from different devices.


Now you should know how to use the Notification 2.0 API. You can check the full scripts for subscribing to Notifications 2.0 with and without a shared token here:

Useful links | Relevant resources


@yiz This is really great article and provided a very good insights. Please add this in article. While running the Notification2.0 microservice locally we must set the C8Y_MICROSERVICE_ISOLATION=‘MULTI_TENANT’ always.

Vachaspati Diwevedi

1 Like

Can we add multiple notification callback for different type of API’s in microservice implementation. For example in my filter if I have filter set for 2 API’s like alarms and events, can I have different notification call backs one for alarms and one for events??

Hi @sandeep.viswanatha, you can achieve this after receiving the notifications. The notifications include information about APIs (alarms, events…) and action (create, update…). You can define different functions for different APIs in the message_handler function based on this information. Here is a Notification 2.0 example in Java you can have a look:

1 Like

Hi Sandeep, you can also do this by creating multiple subscriptions with different subscription names (for example, one for alarms and one for events) and attaching separate consumers to each named subscription. A disadvantage of this approach is that there is no ordering guarantee across the different subscription names (each named subscription is a separate parallel channel in the messaging service) which may or may not be a problem for your use case. If you need to maintain ordering then Yishu’s suggestion would be better.

1 Like

Thank you @yiz this one helped us

It works with PER_TENANT subscription as well provided we must add the below parameters in the microservice properties file along with boot strap credentials to run this locally.