To register a new application within a fresh Kaa server installation, you need to create users with the tenant administrator and tenant developer roles. The tenant administrator is responsible for creating new applications in Kaa, and the tenant developer configures and generates SDKs for those applications. We suggest that you use Kaa Sandbox, which has a tenant administrator and tenant developer users already created.

Adding application

To add an application, proceed as follows:

  1. Open the Kaa admin UI in your browser ( ) and log in as a tenant administrator (user/password: admin/admin123).
  2. Select Applications on the navigation panel on the left side and, in the Applications window that opens, click Add application.
  3. In the Add application window, enter the application name and then click Add.

After the application has been added, you may log out. We will not be using the tenant administrator role in this guide anymore.

Creating notification schema

The application that you have created in the previous step already includes the default versions of the profile, configuration, notification and log schemas ready for use. However, in this sample application, we will use a custom notification schema for demonstration purposes. To create and upload the schema, proceed as follows:

  1. Create the schema.json file on your PC with the following schema definition:

        "type": "record",
        "name": "Notification",
        "namespace": "org.kaaproject.kaa.schema.example",
        "fields": [
                "name": "message",
                "type": "string"
  2. Open the admin UI in your browser ( ) and log in as a tenant developer (user/password: devuser/devuser123).
  3. Open the relevant Notification schemas window (Applications => My First Kaa Application => Schemas => Notification) and click Add schema.
  4. In the Add notification schema window, enter the name and description of the new notification schema.
  5. Scroll down and use the Upload from file function to find the previously created json file with the schema.
    Alternatively, you can use the Schema Avro UI form to create the schema.
  6. Click Upload.
  7. Click Add at the top of the window.

As a result of this operation you will see two notification schemas in the list:

In this screenshot, version 2.0 is the notification schema that was just created. We will use this version for the SDK generation in the next step.

Generating SDK

To generate an SDK for the new application, proceed as follows:

  1. Select the My First Kaa Application application and click Generate SDK.

  2. Click Add SDK profile.

  3. In the Add SDK profile window, fill in the fields as shown in the following screenshot  and then click Add.

  4. Click Generate SDK for corresponding SDK profile. In the Generate SDK window select the target platform for your SDK and click Generate SDK.

After the SDK is generated, you will be presented with a window asking you to save a .jar file with the generated SDK (for Java) or an archive with the generated SDK (for C, C++ or Objective-C). Specify the file name and location on your computer and then click Save. The SDK is now downloaded to your computer. 

Note that in this example we are generating the SDK based on the default configuration, profile, and log schemas. These schemas are automatically populated during the creation of the application. If necessary, you can overwrite them using Admin UI.

Sample client application

Once you have downloaded the SDK, you can use it in your sample project. The following code block illustrates a simple desktop application that will receive notifications from the Kaa server and display them on the console.

NOTE: After generating the C/C++/Objective-C SDKs, you need to build them before creating the application.


import java.util.List;

import org.kaaproject.kaa.client.DesktopKaaPlatformContext;
import org.kaaproject.kaa.client.Kaa;
import org.kaaproject.kaa.client.KaaClient;
import org.kaaproject.kaa.client.SimpleKaaClientStateListener;
import org.kaaproject.kaa.client.notification.NotificationListener;
import org.kaaproject.kaa.client.notification.NotificationTopicListListener;
import org.kaaproject.kaa.common.endpoint.gen.Topic;
import org.kaaproject.kaa.schema.example.Notification;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NotificationSystemTestApp {

    private static final Logger LOG = LoggerFactory.getLogger(NotificationSystemTestApp.class);

    public static void main(String[] args) {
        new NotificationSystemTestApp().launch();

    private void launch() {
        // Create client for Kaa SDK
        KaaClient kaaClient = Kaa.newClient(new DesktopKaaPlatformContext(),
                new SimpleKaaClientStateListener() {
                    public void onStarted() {
              "Kaa SDK client started!");

        // Registering listener for topic updates
        kaaClient.addTopicListListener(new NotificationTopicListListener() {
            public void onListUpdated(List<Topic> topicList) {
      "Topic list updated!");
                for (Topic topic : topicList) {
          "Received topic with id {} and name {}", topic.getId(), topic.getName());

        // Registering listener for notifications
        kaaClient.addNotificationListener(new NotificationListener() {
            public void onNotification(long topicId, Notification notification) {
      "Received notification {} for topic with id {}", notification, topicId);

        // Starts Kaa SDK client
#include <cstdint>
#include <iostream>
#include <memory>
#include <kaa/Kaa.hpp>
#include <kaa/notification/INotificationListener.hpp>
#include <kaa/notification/INotificationTopicListListener.hpp>
using namespace kaa;

class SimpleKaaClientStateListener : public IKaaClientStateListener {
    virtual void onStarted() {
        std::cout << "Kaa SDK client started!" << std::endl;
    virtual void onStartFailure(const KaaException& exception) {}
    virtual void onPaused()  {}
    virtual void onPauseFailure(const KaaException& exception) {}
    virtual void onResumed() {}
    virtual void onResumeFailure(const KaaException& exception) {}
    virtual void onStopped() {}
    virtual void onStopFailure(const KaaException& exception) {}
class BasicNotificationTopicListListener : public INotificationTopicListListener {
    virtual void onListUpdated(const Topics& topics)
        std::cout << "Topic list was updated" << std::endl;
        for (const auto& topic : topics) {
            std::cout << "Received topic with id " << << " and name '" << << "'" << std::endl;

class BasicNotificationListener : public INotificationListener {
    virtual void onNotification(const std::int64_t topicId, const KaaNotification& notification)
        std::cout << "Received notification '" << notification.message << "'"
                  << "for topic with id '" << topicId  << "'" << std::endl;

int main()
    BasicNotificationTopicListListener topicListListener;
    BasicNotificationListener commonNotificationListener;
    // Create client for Kaa SDK
    auto kaaClient = Kaa::newClient(std::make_shared<KaaClientPlatformContext>(), 
    // Start Kaa SDK client
    std::cout << "Presss any key to stop Kaa SDK client" << std::endl;
    // Stop Kaa SDK client
    return 0;
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdbool.h>

#include <kaa/kaa_error.h>
#include <kaa/platform/kaa_client.h>
#include <kaa/utilities/kaa_log.h>
#include <kaa/kaa_notification_manager.h>

#define KAA_DEMO_RETURN_IF_ERROR(error, message) \
    if ((error)) { \
        printf(message ", error code %d\n", (error)); \
        return (error); \

static kaa_client_t *kaa_client = NULL;

void on_notification(void *context, uint64_t *topic_id, kaa_notification_t *notification)
    kaa_string_t *message = (kaa_string_t *)notification->message;
    printf("Notification for topic id '%lu' received\n", *topic_id);
    printf("Notification body: %s\n", message->data);
void on_topics_received(void *context, kaa_list_t *topics)
    printf("Topic list was updated\n");
    if (!topics || !kaa_list_get_size(topics)) {
        printf("Topic list is empty");

    kaa_list_node_t *it = kaa_list_begin(topics);
    while (it) {
        kaa_topic_t *topic = (kaa_topic_t *)kaa_list_get_data(it);
        printf("Topic: id '%lu', name: %s\n", topic->id, topic->name);
        it = kaa_list_next(it);

int main()
    printf("Kaa SDK client started\n");

    kaa_error_t error_code = kaa_client_create(&kaa_client, NULL);
    KAA_DEMO_RETURN_IF_ERROR(error_code, "Failed create Kaa client");

    kaa_topic_listener_t topic_listener = { &on_topics_received, kaa_client };
    kaa_notification_listener_t notification_listener = { &on_notification, kaa_client };

    uint32_t topic_listener_id = 0;
    uint32_t notification_listener_id = 0;

    error_code = kaa_add_topic_list_listener(kaa_client_get_context(kaa_client)->notification_manager
                                           , &topic_listener
                                           , &topic_listener_id);
    KAA_DEMO_RETURN_IF_ERROR(error_code, "Failed add topic listener");

    error_code = kaa_add_notification_listener(kaa_client_get_context(kaa_client)->notification_manager
                                             , &notification_listener
                                             , &notification_listener_id);
    KAA_DEMO_RETURN_IF_ERROR(error_code, "Failed add notification listener");

    error_code = kaa_client_start(kaa_client, NULL, NULL, 0);
    KAA_DEMO_RETURN_IF_ERROR(error_code, "Failed to start Kaa main loop");


    return error_code;
#import "ViewController.h"
@import Kaa;

#define TAG @"NotificationSystemTestApp >>>"

@interface ViewController () <KaaClientStateDelegate, NotificationTopicListDelegate, NotificationDelegate, ProfileContainer>

@property (nonatomic, strong) id<KaaClient> kaaClient;


@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //Create a Kaa client with default Kaa context.
    self.kaaClient = [KaaClientFactory clientWithContext:[[DefaultKaaPlatformContext alloc] init]];

    // A listener that listens to the notification topic list updates.
    [self.kaaClient addTopicListDelegate:self];

    // Add a notification listener that listens to all notifications.
    [self.kaaClient addNotificationDelegate:self];

    // Set up profile container, needed for ProfileManager
    [self.kaaClient setProfileContainer:self];

    // Start the Kaa client and connect it to the Kaa server.
    [self.kaaClient start];

- (void)onListUpdated:(NSArray *)list {
	NSLog(@"%@ Topic list updated!", TAG);
    if ([list count] == 0) {
        NSLog(@"%@ Topic list is empty!", TAG);
	for (Topic *topic in list) {
       	NSLog(@"%@ Received topic with id %lld and name %@", TAG,,;

- (KAAEmptyData *)getProfile {
    return [[KAAEmptyData alloc] init];

- (void)onNotification:(KAANotification *)notification withTopicId:(int64_t)topicId {
    NSLog(@"%@ Received notification %@ for topic with id %lld", TAG, notification.message, topicId);

- (void)onStarted {
    NSLog(@"%@ Kaa SDK client started", TAG);


You can find the project source code (including Java, C, C++ and Objective-C) in the attached archive.

  • For Java, the project is built using Apache Maven. Note that the downloaded SDK must be placed into the lib folder in order for the build to work. Import this project into your IDE as a Maven project and launch the NotificationSystemTestApp application. Once the application is launched, you will see the following output:

    [...  INFO  NotificationSystemTestApp]  Kaa SDK client started!
  • For C, C++ and Objective-C, place the downloaded SDK into the libs folder and then run or build.bat script depending on your platform. Launch the demo_client application. Once the application is launched, you will see the following output:

    Kaa SDK client started!

Creating notification topic

To send your first Kaa notification, you need to create a notification topic and assign this topic to the default endpoint group.

To create a notification topic, proceed as follows:

  1. Open the relevant Notification topics window (Applications => My First Kaa Application => Notification topics) and click Add notification topic.
  2. In the Add notification topic window, fill in the fields as shown in the following screenshot and then click Add.

NOTE: We set the topic as mandatory in order to automatically subscribe the client application to notifications on this topic.

Once the topic is created, we will assign it to the default endpoint group, which contains all endpoints, including endpoints with our application.

To assign a notification topic to the default endpoint group, proceed as follows:

  1. In the relevant Endpoint groups window (Applications=>My First Kaa Application=>Endpoint groups), select the All group.
  2. In the Endpoint group details window, click Add notification topic at the bottom of the window. 
  3. In the Add topic to endpoint group window, select the recently created notification topic and then click Add.

After the topic is added to the endpoint group, you will see the following output in the application:

[...  INFO  NotificationSystemTestApp]  Topic list updated!
[...  INFO  NotificationSystemTestApp]  Received topic with id X and name Notification Topic

This is the first update from the Kaa server that provides the client with the information about the changes in the topic list. Now you can send notifications on this topic, and they will be delivered to your application.

Creating notification

To create a notification, proceed as follows:

  1. Create a notification.json file on your PC with the following contents:

    {"message":"Hello from Kaa!"}
  2. Open the relevant Notification topics window (Applications => My First Kaa Application => Notification topics) and click Send notification in the Notification Topic row.
  3. In the Send notification window, fill in the fields as shown in the following screenshot and then click Send.

Once the notification is sent, you can see the following output in the application:

[...  INFO  NotificationSystemTestApp]  Received notification {"message": "Hello from Kaa!"} for topic with id X

Congratulations with your first Kaa application!

Next steps

To create a real-world IoT solution, you will most likely need to implement more features into your application. Kaa provides you with practically everything you might need. The following overview will help you grasp the scope of Kaa capabilities as well as get familiar with the essential documentation, such as Programming guide and Administration UI guide.

Profiling and grouping

During a new endpoint registration, Kaa creates an associated endpoint profile for the endpoint. An endpoint profile is basically some meaningful information about the endpoint which may be useful for specific applications. Profiles may contain things like an OS version, amount of RAM, average battery life, type of network connection, device operation mode – virtually anything. An endpoint profile structure in Kaa is configured using a client-side endpoint profile schema. Based on the defined profile schema, Kaa generates an object model to operate against the client side and handles data marshaling all the way to the database. Whenever the client updates its profile information, the endpoint SDK automatically sends these updates to the server as soon as the connection becomes available.

For programming practice, see collecting endpoint profiles.

The information collected in an endpoint’s profile can be used to group endpoints into independently managed entities called endpoint groups. On the back end, Kaa provides a profile filtering language for defining the criteria for group membership. An endpoint can belong to any number of groups. Grouping endpoints can be used, for example, to send targeted notifications or adjust software behavior by applying group-specific configuration overrides.

For programming practice, see using endpoint groups.


Kaa allows for delivery of events, which are structured messages, across endpoints. When endpoints register with the Kaa server, they communicate which event types they are able to generate and receive. Kaa allows endpoints to send events either to virtual “chat rooms” or to individual endpoints. Events can even be delivered across applications registered with Kaa – making it possible to quickly integrate and enable interoperability between endpoints running different applications. Some examples are: a mobile application that controls house lighting, a car’s GPS that communicates with the home security system, a set of integrated audio systems from different vendors that deliver a smooth playback experience as you walk from one room to another. Kaa events are implemented in a generic, abstract way, using non-proprietary schema definitions that ensure identical message structures. The schema provides independence from any specific functionality implementation details.

For programming practice, see messaging across endpoints.

Collecting data

Kaa provides rich capabilities for collecting and storing structured data from endpoints. A typical use-case is collecting various types of logs: performance, user behavior, exceptional conditions, etc.

Using a set of pre-packaged server-side log appenders, the Kaa server is able to store records to a filesystem, a variety of big data platforms (Hadoop, MongoDB, Cassandra, Oracle NoSQL etc.), or submit them directly to a streaming analytics system. It is also possible to create a custom log appender.

The structure of the collected data is flexible and defined by the log schema. Based on the log schema defined for the Kaa application, Kaa generates an object model for the records and the corresponding API calls in the client SDK. Kaa also takes care of data marshalling, managing temporary data storage on the endpoint, and uploading data to the Kaa server.

For programming practice, see collecting data from endpoints.

Using notifications

Kaa uses notifications to distribute structured messages, posted within notification topics, from the server to endpoints. A notification structure is defined by a corresponding notification schema.

Endpoint are subscribed to notification topics, which can be either mandatory or optional. Access to notification topics is automatically granted according to the endpoint’s group membership.Notifications can be sent either to every endpoint subscribed to a topic or to an individual endpoint.

Notifications can be assigned expiration timestamps to prevent their delivery after a certain period of time.

For programming practice, see using notifications.

Distributing operational data

Kaa allows you to perform operational data updates, such as configuration data updates, from the Kaa server to endpoints. This feature can be used for centralized configuration management, content distribution, etc. Since Kaa works with structured data and constraint types, it guarantees data integrity.

The Kaa server monitors the database for changes and distributes updates to endpoints in the incremental form, thus ensuring efficient bandwidth use. The endpoint SDK performs data merging and persistence, as well as notifies the client code about the specific changes made to the data. As a result, the client application knows exactly where in the data structure the changes occurred and can be programmed to react accordingly.

Based on the endpoint’s group membership, it is possible to control what data is available to the endpoint. This is achieved by applying group-specific data overrides, which make it possible to adjust the behavior of the client application based on operational conditions or usage patterns, fine-tune the algorithms according to feedback, implement gradual feature roll-out, A/B testing, etc.

For programming practice, see distributing data to endpoints.

Further reading

Use the following guides and references to make the most of Kaa.

GuideWhat it is for
Design reference Use this reference to learn about features and capabilities of Kaa (Endpoint profilingEventsNotificationsLogging, and other features).
Kaa SandboxUse this guide to try out Kaa in a private environment with demo applications.
Programming guideUse this guide to create advanced applications with Kaa
Installation guideUse this guide to install and configure Kaa either on a single Linux node or in a cluster environment.
Contribute to KaaUse this guide to learn how to contribute to Kaa project and which code/documentation style conventions we adhere to.

Copyright © 2014-2015, CyberVision, Inc.

  • No labels


  1. Where is the source for the stored? Is it in github? The reason I ask is that it is currently broken/out of date, line 38 of should be:

    Correct line 38

    There may be additional problems, as I have not fully tested the app.

  2. Hi everybody!

    I have tested it several times, by changing the "Endpoint groups" I get the feedback, but after sending notification from the panel, I wont get anything! Here is my log:

    2:53,868 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
    17:02:53,868 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
    17:02:53,868 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/Users/saeedsh/Downloads/kaa-first-app/kaa-first-app/java/target/classes/logback.xml]
    17:02:54,177 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
    17:02:54,505 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
    17:02:54,522 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [console]
    17:02:54,556 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
    17:02:54,683 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.kaaproject.kaa] to ERROR
    17:02:54,683 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [] to INFO
    17:02:54,683 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to INFO
    17:02:54,684 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [console] to Logger[ROOT]
    17:02:54,685 |-ERROR in ch.qos.logback.core.joran.action.AppenderRefAction - Could not find an appender named [fileLogAppender]. Did you define it below instead of above in the configuration file?
    17:02:54,685 |-ERROR in ch.qos.logback.core.joran.action.AppenderRefAction - See for more details.
    17:02:54,685 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
    17:02:54,693 |-INFO in [email protected] - Registering current configuration as safe fallback point
    2016-06-28 17:02:57,668 [main] INFO - Kaa SDK client started!
    2016-06-28 17:04:23,271 [pool-4-thread-1] INFO - Topic list updated!
    2016-06-28 17:04:23,271 [pool-4-thread-1] INFO - Received topic with id 1 and name New Topic


    I highly appreciate if you could give me any clue where to look.


  3. Hello!

    Thanks and congratularions for Kaa!

    I've had a problem with the client in Java and discovered it was due to the option I selected in the "Credentials service" field during Application creation.

    This was the problem on the client (Java): 

    Connection for channel [default_operation_tcp_channel] was rejected: REFUSE_VERIFICATION_FAILED

    The problem is that the client needs the Application to be created with the "Trustful" options at "Credentials service", and I've selected "Internal".

    Logging as "admin" and changing it to "Trustful" got it working.

    I suggest to edit the page stating about that field.


  4. I maybe found a bug in Kaa.

    1) I send notification to my endpoint successful in this article.

    2) I delete topic in Notification topics in "default Endpoint group".

    3) I add this the topic, but my endpoint do not accept notification info. why?

    1. Workaround, you can create two topic.