Hybrid Messaging SDK


Guide for developers

Hybrid Messaging API


Apps that register with and retrieve messages from CM’s Hybrid Messaging platform use a REST API to communicate. This document is a guide on how to use the API. There are some prerequisites (like authorization) for every request. These are explained in chapter 2.

In chapter 3 we explain how to register and chapter 4 is all about receiving messages. As this API is a RESTful interface, we use HTTP verbs to define an action:

  • GET - Retrieve something
  • POST - Create something new
  • PUT - Update something existing
  • DELETE - Delete something

More information on REST: http://en.wikipedia.org/wiki/Representational_state_transfer#Applied_to_web_services

The data format is JSON. More information on JSON: http://www.json.org

A recommended alternative to implementing this API is using one of our easy to use libraries instead.

  • Android Gradle Package
  • iOS CocoaPod

Request requirements


The Authorization header is used to verify requests from your app are originating from the app. The app 'signs' the request with a calculated OAuth 2.0 Message Authentication Code (MAC) signature and the REST API will check this by calculating the same signature itself and comparing this calculated signature with the mac value in the Authorization header.

The Authorization header needs three values:

  • The appKey identifies your app. You get the appKey from us.
  • ts is the timestamp of the request.
  • mac is the message authentication code, the signature of the request. It is the hash of the request signed with the appSecret. You get the appSecret from us.

The value of the Authorization header will look like this:

MAC kid="8eda08f7-5249-40c2-9ef7-ce573f3a8dca" ts="1464242891" mac="dkViwAV9Pi5xiab39VRUq+gU4Co="

The message authentication code (mac) is calculated by using hmac-sha-1 on a string representing the request. The string representing the request looks like this:

POST /v1.0/deviceregistrations HTTP/1.1

The query string, if used, should also be included:

POST /v1.0/messages?$top=100 HTTP/1.1

If authorization fails, the server will respond with HTTP Status 401 Unauthorized.

User Agent

Your app also needs to include a User-Agent header. This contains information about the app, the hybrid messaging library used and the device. It should at least contain the mobile platform (iOS, Android or WindowsPhone). Other information is optional. It is useful to include the operating system, app name, user name, device brand name, device model name, user language and/or the app version.

Android example:

MyApp/1.0 (Android 6.0.1; LGE; Nexus 5X; en_US)

If the UserAgent is not correct or missing, the server responds with HTTP Code 400 Bad Request.


To uniquely identify the app install on the device, the Hybrid Messaging platform generates a globally unique identifier (GUID). After you’ve retrieve a DeviceID as reply on the first device registration request, you need to include a DeviceID header on every request with this GUID as its value. It’s mandatory for every request, except when creating a new device registration.

If the DeviceID is not correct, the server responds with HTTP Code 400 Bad Request.

Do not mistake the DeviceID with the deviceID from your phone.

Date and time format

The API uses the ISO 8601 Date/Time format, with a T between the date and the time. In short, this is the format:


Do not use local time, but always use UTC time.


A full HTTP request will look like this:

PUT /v1.0/deviceregistrations HTTP/1.1
Host: api.cmtelecom.com
Authorization: MAC kid="8eda08f7-5249-40c2-9ef7-ce573f3a8dca" ts="1464242891" mac="dkViwAV9Pi5xiab39VRUq+gU4Co="
Content-Type: application/json
User-Agent: MyApp/1.0 (Android 6.0.1; LGE; Nexus 5X; en_US)
DeviceID: 0c6bf13c-8d1c-474c-ab66-74dadb1c3d7d
	"Msisdn": "0031600000000"

Device Registrations

A "device registration" in the context of this API is an install of an app on a device.

Get device registration information

To get information about the apps device registration, simply send a GET request to /v1.0/deviceregistrations and you get the following response:

	"UserAgent":"MyApp/1.0 (Android 6.0.1; LGE; Nexus 5X; en_US)"

RegistrationStatus can have the following values:

  • Unverified – registration without MSISDN (phone number)
  • WaitingForPin – verification code has been sent to the MSISDN
  • LastPinVerificationFailed – verification code was incorrectly verified
  • PinVerified – MSISDN is known and verified

When the device registration is not found, the server returns HTTP Code 404 Not found.

New device registration

To register a new device registration, you send a POST request to /v1.0/deviceregistrations. You can even send a request without any field, but you still have to provide an empty object:


You can also choose to include the push token and/or MSISDN already:


PushToken is the token that the app retrieves from a push notification cloud service like Windows Notification Services, Google Cloud Messaging or Apple Push Notification Server.

Update device registration

To update an existing device registration, you send a PUT request to /v1.0/deviceregistrations with any field you want to update. You can leave out any field you don’t want to update.


Msisdn is the mobile subscriber identification number. A internationally formatted phone number starting with the country prefix with leading zeroes.

Verification process

When a device registration request contains an MSISDN (phone number) which is not verified yet, the platform will automatically send a verification SMS message to that MSISDN.

You need to give your user a way to put in the verification code, after which your app sends a PUT request to /v1.0/deviceregistrations with the appropriate code:


If the code is correct, the server will respond with:


If the code is not correct, the server responds with:



Get messages

To retrieve all messages for the app, send a GET request to /v1.0/messages. The response looks like this:

		"Body":"Your first message!", 

Status can contain the following values:

  • Cancelled – the platform cancelled the message, it is not sent
  • Sent – the platform did not cancel the message and will try to send it
  • Rejected – the carrier or cloud rejected the message
  • Accepted – the carrier or cloud accepted the message
  • Failed – the carrier or cloud failed to deliver the message
  • Delivered - the message has been delivered on the device

The ID is a globally unique identifier (GUID) that uniquely identifies the message. The UpdateID is only guaranteed to be unique for 24 hours. This ID is needed to notify the platform that a message is retrieved by an app or read by the user, which is explained in the next paragraph.

DateTime is the time the message arrived at the Hybrid Messaging platform.

The messages API supports the ODATA Query language. You can specify $select, $top, $skip, $filter and $orderby to make your result set more specific.

See chapter 5 of this page for more information: http://www.odata.org/documentation/odata-version-3-0/url-conventions

Update messages

When your app retrieve a message as a push notification, it should notify the platform about this event. To do so, send the following PUT request to the server:


When your app displayed the message to a user, it should notify the platform using a Date/Time in the ReadByRecipient field.


Ack android messages

Messages sent from the HybridMessaging platform make use of the XMPP Android protocol. This allow us to monitor if a message is received on the device of the user. When receiving the message a connection from Google will be made with the phone of the user. This connection can be reused to send an ACK back to the originated address. In order to make HybridMessaging properely work on Android we need to know if a notification is received on the phone. If not a message will be send twice since we don't know for sure if the message was received correctly or on time. Follow the steps below to send back ACKS when succesfully receiving messages.

To receive messages from hybrid messaging you should first create a WakefulBroadcastReceiver with an IntentService capable of listening to incoming notifications.

In the IntentService you are able to retrieve the contents of the message and send an Ack back to the server over the XMPP protocol. In order to send the Ack back to the server you have to instantiate a GoogleCloudMessaging object and retrieve the message type.

final GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);

Also retrieve the bundle from the intent to retrieve the message

Bundle extras = intent.getExtras();

To send a message back to the server, make sure you wait a very short time. Let the Thread sleep for a very short while otherwise the Ack will not be send back to the server. Afterwards retrieve the bundle contents from the Extras received through the Intent. Important are time_to_live and messageId that need to be send back to the server. Send an ACK back to the server over the same GCM connection with as destination your Google project ID including an address as following: YOUR_PROJECT_ID + "@gcm.googleapis.com


public class GCMNotificationIntentService extends IntentService {

    public GCMNotificationIntentService() {

    protected void onHandleIntent(Intent intent) {

        Bundle extras = intent.getExtras();
        final GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
        String messageType = gcm.getMessageType(intent);

        if (extras != null) {
            if (!extras.isEmpty()) {
                if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {

                    for (int i = 0; i < 5; i++) {
                        try {
                        catch (InterruptedException e) {}

                    String messageId = null;
                    long ttl = 30L;

                     Bundle bundle = intent.getExtras();
                     messageId = bundle.getString("message_id");
                     String notificationId = bundle.getString("from");
                     String message = bundle.getString("message");
                     String tempttl = bundle.getString("time_to_live");
                     if(tempttl != null) {
                         ttl = Long.valueOf(bundle.getString("time_to_live"));

                    // ## Send ACK back to server containing the following KEY and VALUE ## //
                    Bundle dataBundle = new Bundle();
                    dataBundle.putString("message_type", "DLR");

                    try {
                        if(tempttl != null) {
                            gcm.send(PROJECT_ID + "@gcm.googleapis.com", messageId, ttl, dataBundle);
                    } catch (IOException e) {
        GcmBroadcastReceiver.completeWakefulIntent(intent); // Close the service


important: Make sure to send "message_type" along with "DLR" back to the server

Hybrid Messaging Android SDK

SDK guide for Android developers

Version 1.2.5


Important step!
At first make sure you’ve included Google Play Services in your project. More info about including Google Play Services here: http://developer.android.com/google/play-services/setup.html



Put the following permissions in the manifest outside the application tags in order to use the HybridMessagingSDK.

<!--Necessary for all outgoing internet connections-->
<uses-permission android:name="android.permission.INTERNET" />
<!--Necessary for connecting with the play store and retrieving registration id--> 
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!--Keep the service awake during processing incoming notifications--> 
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!--Receive notifications from the CCS/GCM platform of google-->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />


<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

Include READ_PHONE_STATE when including the following options of the SDK:

  • if you want to retrieve the MSISDN of the user by getMsisdn(). It's not gauranteed this will work. The simcard can be masked and so impossible to retrieve the number.
  • Detect if the user changed his simcard after installing and registering with your application.

Configure receiving hybrid messages

Put this receiver inside your application tags of your manifest.

<receiver android:name="com.cm.hybridmessagingsdk.receivers.GcmBroadcastReceiver" 
		<action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
		<action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 
		<category android:name="com.cm.hybridmessaging" />

<service android:name="com.cm.hybridmessagingsdk.GCMNotificationIntentService"></service>

Configuring meta data

	android:value="your_hybridmessaging_key" />
	android:value="your_hybridmessaging_secret" />
	android:value="@string/project_id" />

In your Strings.xml (project_id must be in your strings.xml)

<string name="project_id">your_project_id</string>

Include HybridMessagingSDK

Depending on the Development Environment being used there are different ways to include the HybridMessagingSDK. You can simply add the SDK as a jar file to your project but this also requires to download the Support Library of Android. When having Gradle Support you can easily add the SDK as a dependency to your project. Both methods are explained below.

Android Studio with Gradle support

When using Android Studio with Gradle support, use the following dependency to sync the SDK with your project.

compile (com.cm.hybridmessagingsdk:hybridmessagingsdk:1.2.5@aar) { 
	exclude group: 'com.android.support', module:'support-v4'

Eclipse with ADT or Intellij

Download the HybridMessagingSDK jar file from the link below and include it in your project http://docs.cm.nl/hybridmessaging/sdk/android/hybridmessagingsdk-1.2.5.jar

Include Support Library in Eclipse with ADT or Intellij

If you are using Intellij or Eclipse include the Android v4 Support Library jar file in your project.
Download the Android Support Library here: http://docs.cm.nl/hybridmessaging/sdk/android/android-support-v4.jar


Basic usage

To communicate with the SDK only the class HybridMessaging is needed. All methods in this class are static and can be used for registering, messaging and the notification settings.


Make sure to initialize the HybridMessagingSDK as early as possible. For example in the first onCreate of the first activity that will be created.



The SDK uses some objects to make it easy to access data from the SDK. For example: Registration, Message and VerificationStatus.



void onReceivedRegistration(Registration registration);
void onError(Throwable throwable);


void onReceivedMessages(int statusCode, Header[] headers, Message[] messages);
void onError(Throwable throwable);


In order to receive the notification data or show your own notification use onReceiveHybridNotification. For implementing this listener see: setHybridNotificationListener

void onReceiveHybridNotification(Notification notification);

By default the SDK will always show a notification. To turn this off see: fireNotificationsByDefault


void onVerificationStatus(VerificationStatus status); 
void onError(Throwable throwable);



Check if an user is verified.

  • Verified: The user is registered also the phonenumber of this user is verified
  • Unverified: The user is unknown for HybridMessaging. The user must first register and validate his number.
  • LastPinVerificationFailed: The last pincode was invalid
  • WaitingForPin: Pin is needed to finish the registration

HybridMessaging.getVerificationStatus(new OnVerificationStatus());


Register the user by msisdn.

registerNewUser(String msisdn, new OnRegistrationListener());


Confirm msisdn by submitting the pincode send to the number given during registration. The deviceId is a result in the Registration object from registerNewUser and will only change when the user has to register again.

registerUserByPincode(String deviceId, String verificationCode, new OnVerificationStatus());


requestNewVerificationPin(String msisdn, new OnRegistrationListener())


Reset the HybridMessagingSDK



Get all messages

getMessages(new OnMessageListener()); 

Get messages with limit

getMessages(int amount, new OnMessageListener());

Get messages with limit and offset

getMessages(int offset, int amount, new OnMessageListener());

Get all messages between now and certain date

getMessagesFromDate(long dateInMillisec, new OnMessageListener());

Get messages with Filter

getMessagesWithFilter(Filter filter, new OnMessageListener()) 

You can add one or more options to the Filter object. The Filter object works with OData and for more information check their docs.

Creation of a Filter (Example)

Filter filter = new Filter();
filter.addFilter(Filter.OPTION_SKIP, String.valueOf(offset));

The Available options are:

public static String OPTION_EXPAND; 
public static String OPTION_FILTER; 
public static String OPTION_ORDER_BY; 
public static String OPTION_SELECT; 
public static String OPTION_SKIP; 
public static String OPTION_TOP;


The SDK will automatically generate notifications in the statusbar with a couple of default settings.

Title: The name of the app
Icon: The icon specified in the Manifest.xml

If no icon is available notifications will not be generated since this is a requirement of Android.

Set custom title for default notifications

setNotificationTitle(String title);

Set custom icon for default notifications

setNotificationIcon(int resourceId);

Receive the notifications in your application

The SDK has the option to receive the notifications in your own application and generate your own notifications. Do this by setting the HybridNotificationListener. You can do this for example when you want to customize the notification or if you want to fire an action when the user taps the notification.

setHybridNotificationListener(HybridNotificationListener hybridNotificationListener);

Turn off default notifications

If you do not want the SDK to generate default notifications you can turn this off

fireNotificationsByDefault(Boolean fire);

Simcard detection

In some use cases it would be quite handy to detect if a simcard of the phone has been replaced after a user registered through your application. The SDK provides a mechanism to detect this behavior. We recommend to reset the login of the user when a new simcard is replaced in the phone so the user could relogin with their new number.

In order to detect this behavior first add a service to your manifest inside the <application> tag. This will allow the SDK to listen to any simcard changes happening on the phone.

<receiver android:name="com.cm.hybridmessagingsdk.receivers.SimChangedReceiver">
		<action android:name="android.intent.action.SIM_STATE_CHANGED"/>

In any activity, recommend is the activity after logging in which the application will allways open, override the onResume and onPause. Call the static methods HybridMessaging.onResume() and onPause in the designated locations.

After attaching above activity lifecycle methods with SDK you are able to receive any Sim changes by defining the following listener:

HybridMessaging.setOnSimChangedListener(new OnSimcardChangedListener() {
	public void onSimcardChanged(boolean isChanged, String simState) {

And that's it. Call for example HybridMessaging.resetLogin(); if isChanged is true.

Hybrid Messaging iOS SDK

SDK guide for iOS developers



  • Apple iOS development environment (Xcode 6.0+, SDK, etc.)
  • Hybrid Messaging Application Key / Application Secret Key
  • Push enabled provisioning profile
  • Basic knowledge of iOS app development

Package Contents

The iOS SDK contains the following things:


Installation with CocoaPods (recommended)

CocoaPods is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like HybridMessaging in your projects. See http://cocoapods.org for more information on how to install and use CocoaPods.


platform :ios, '7.0'

pod 'HybridMessagingSDK', '~> 1.2'

Installation via Static Library

The HybridMessaging SDK can be added to your application by dragging the HybridMessaging.h and libHybridMessaging.a file into your project in Xcode. Make sure to enable “Copy items if needed” in the “Choose options for adding these files” dialog.


  1. Open the Info.plist and add a new item with the key “Required background modes” and select “App downloads content in response to push notifications”
  2. Open your AppDelegate class and import the HybridMessaging header: #import <HybridMessaging.h>
  3. Add the following lines in the application:didFinishLaunchingWithOptions: method
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
	[HybridMessaging configureWithKey:@"YOUR_APPLICATION_KEY"
	[HybridMessaging enable];

Notes: the "enable" method triggers a dialog to the user to request permission to sent push notifications. You may want to call the method at a later time to increase the likelihood that the user will accept the notifications. The permission dialog is only triggered once. When the user has denied the request it can be enabled again from the Settings menu.

Set development mode (optional)

Set the device development mode (defaults to production)

+ (void)setDevelopment:(BOOL)yesOrNo;

When this value is set to YES, the device registration is marked as a development device, and our server automatically uses the development push certificate (if configured) while sending a push notification to the device.

Set this value before calling any device verification methods, preferably at the start of the application in - (BOOL)application:didFinishLaunchingWithOptions:

Note: Remember to set this value to NO in a production build or remove the method call

Basic usage

The central class in the Hybrid Messaging SDK is called HybridMessaging and holds references to methods for notifications and authentication functionality. All methods calls are static.

The HybridMessaging class also contains a method for the Device ID and Push Token:

+ (NSString *)deviceId;
+ (NSString *)pushToken;
+ (NSString *)msisdn;
+ (NSString *)version;

Phone number verification


+ (void)requestPhoneVerification:(NSString *)msisdn 
						 handler:(void (^)(HMDeviceRegistrationStatus status))statusHandler;

+ (void)requestPhoneVerificationVoiceCall:(NSString *)msisdn 
						 handler:(void (^)(BOOL success))statusHandler;

+ (void)requestPinVerification:(NSString *)pin 
						handler:(void (^)(HMDeviceRegistrationStatus status))statusHandler;

+ (void)requestVerificationStatus:(void(^)(HMDeviceRegistrationStatus status))statusHandler;

The device registration status can have one of the following values:

- HMDeviceRegistrationStatusUnknown
- HMDeviceRegistrationStatusUnverified
- HMDeviceRegistrationStatusWaitingForPin
- HMDeviceRegistrationStatusLastPinVerificationFailed
- HMDeviceRegistrationStatusPinVerified
- HMDeviceRegistrationStatusInvalid

Notes: Phone number is in MSISDN format and must start with the country code: e.g. 0031 for the Netherlands.


[HybridMessaging requestPhoneVerification:phoneNumberTextField.text 
								  handler:^(HMDeviceRegistrationStatus status) {
	if (status == HMDeviceRegistrationStatusWaitingForPin
		|| status == HMDeviceRegistrationStatusLastPinVerificationFailed) {
		// Show PIN view
	} else {
		// Handle error

Push notifications


Set the user notification types (optional). Defaults to Alert, Badge and Sound.

+ (void)setUserNotificationTypes:(HMUserNotificationType)types;

Get the current notification types

+ (HMUserNotificationType)userNotificationTypes;

All available notification types:

- HMUserNotificationTypeNone // the application may not present any UI upon a notification being received
- HMUserNotificationTypeBadge // the application may badge its icon upon a notification being received
- HMUserNotificationTypeSound // the application may play a sound upon a notification being received
- HMUserNotificationTypeAlert // the application may display an alert upon a notification being received

Notes: Make sure to set the notification types before calling the +enable method.


[HybridMessaging setUserNotificationTypes:(HMUserNotificationTypeBadge | 
										   HMUserNotificationTypeAlert | 

Enable push notification.

+ (void)enable;

Disable push notification.

+ (void)disable;

Push notification blocks

You may set the following blocks in your application to react to the push notification events.

[HybridMessaging setDidReceiveRemoteNotificationBlock:^(NSDictionary *userInfo) { 
	NSLog(@"%@", userInfo);

Called when a push notification is received

[HybridMessaging setDidRegisterForRemoteNotificationsWithDeviceTokenBlock:^(NSData *deviceToken) { 
	NSLog(@"%@", [deviceToken description]);

Called when a push token is received

[HybridMessaging setDidFailToRegisterForRemoteNotificationsWithErrorBlock:^(NSError *error) { 
	NSLog(@"%@", error);

Called when the push registration fails


Methods to receive the messages that have been sent by the Hybrid Messaging.

+ (void)messages:(void (^)(NSArray *messages, NSError *error))handler;
+ (void)messagesWithLimit:(NSInteger)limit handler:(void (^)(NSArray *messages, NSError *error))handler;
+ (void)messagesWithLimit:(NSInteger)limit offset:(NSInteger)offset handler:(void (^)(NSArray *messages, NSError *error))handler;


Get the last 100 messages

[HybridMessaging messagesWithLimit:100 handler:^(NSArray *messages, NSError *error) { 
	if (error) {
		// Handle error
	} else {
		for (NSDictionary *message in messages) {
			NSString *id = message[@"ID"];
			NSString *body = message[@"Body"]; 
			NSString *dateTime = message[@"DateTime"]; 
			NSString *sender = message[@"Sender"];
			// Do something with message


Get geolocation information about the app user.

+ (void)requestGeoIpInfo:(void(^)(NSDictionary *info))handler;

Carrier update notification

Sets a callback to be executed when the carrier has changed.

+ (void)setDeviceDidUpdateCarrierBlock:(void(^)(CTCarrier *carrier))block;