Messaging
Kumulos has a RESTful API that allows you to send or schedule push notifications, report on open rates / conversions and manage channels from any other backend system.
Targeting¶
You can use the API to send a broadcast to all users or target segments, channels, users or installs.
User IDs¶
If you use the User Association feature to identify your users to Kumulos from device SDKs, you can make use of the userIds targeting option. For example, if you identify your users by a 'membership number', you can associate that number with each installation when a user logs in.
Then once associated, you can send push notifications to the users identified by their membership number instead of the Kumulos install ID.
Install IDs¶
Alternatively, if do not use User Association, you can still target the installs users are active on via installIds, the unique identifiers within your app used by all the Kumulos services to cluster requests by the originating device. They are not used to authenticate your app, or a specific user of the app.
When it is initialized for the first time the Kumulos SDK will automatically generate a unique identifier for the device your App is installed on and will use this identifier for every subsequent interaction with our services.
If you want are using your own backend solution you will need to manage your own lookup to pair an installId with whatever identifier your app models devices or users with, an example of this interaction is shown in the diagram below.
Checking Push Registrations¶
When you run your app on a simulator or install your app on a device, you can check that the install has successfully registered for push notifications by selecting the app and clicking the Installs
tab to see the ten most recent installs of your app. Click on any install and then click on Push
tab.
Headers¶
Please ensure that you set the following headers in your request:
Content-Type: application/json
Accept: application/json
Authentication¶
The Kumulos Messaging API authenticates other back-end services via HTTP Basic Auth using your app's API Key as the username and your Server Key as the password (in the Authorization
header). Both of these are available from the App Dashboard in your Agency Console.
This is for the latest version of the API. Please see the Changelog for previous versions.
Sending notifications¶
POST https://messages.kumulos.com/v2/notifications
¶
Payload¶
The request payload must be provided as a JSON object, with the following fields and validation rules met. If you are not using any optional fields, do not include them in the request.
{
target: {
broadcast: Boolean, when true the message will be sent to all registered devices
installIds: Array of installIds to send the notification to
userIds: Array of user identifiers to send the notification to
segmentUuid: Unique identifier of the segment to target
channelUuids: Array of unique identifier(s) of the channel(s) to target
geofenceIds: Array of integer ids of the geofence(s) to target
geofenceTags: Array of string tags of the geofence(s) to target
geofenceBroadcast: Boolean, target all installs in any geofence
excludeInstallIds: Install Ids to be excluded from the results of a channel or segment target
}
content: {
title: String, required
message: String, required
url: String, set a url for the message to open in the device browser
data: Optional object of additional key / values to be passed in the notification payload for your app to consume
}
collapseId: String, sets the apns-collapse-id and the collapse_key options for APNS/FCM respectively.
runBackgroundHandler: Boolean, when true the message will be sent for processing in the background (content-available flag in iOS)
ios: {
category: String, this will trigger your UNNotificationContentExtension whose ID matches this category.
badge: {
type: String, either "incrementBy" or "setTo"
count: Positive or Negative integer. Set to 0 to clear badge.
}
sound: String, sound file to play instead of the default device notification sound. Pass 'none' to disable vibration and sound for the notification.
media: {
pictureUrl: String, URL for image to include in notification
}
relevanceScore: iOS15+, float between 0 and 1
interruptionLevel: iOS15+, String, one of: "passive", "active", "time-sensitive", "critical"
}
android: {
highPriority: Boolean, sets priority flag to wake up Android devices
sound: String, sound file that is included in your app to play instead of the default device notification sound.
pictureUrl: String, URL for image to include in notification
notificationType: String, either "general" or "important", general will use the default channel on device and drop into the notification tray. Important will present a heads-up notification. Cannot be combined with notificationChannel.
notificationChannel: String, the ID of the notification channel on the device to put the notification into, must exist on the device or will fallback to kumulos "general". Cannot be combined with notificationType.
}
schedule: { //Schedule the message. Omit to send immediately.
sendAt: DateTime of format "Y-m-d" (for strategy "intelligent") or "Y-m-d H:i" otherwise, required if schedule is set
strategy: String, either "local", "utc", "timezone" or "intelligent", required if schedule is set
pastTimes: String, either "ignore" or "nextDay", required if schedule is set
timezone: IANA Time Zone string, required if strategy is "timezone"
},
intelligentDelivery: Boolean, when true the message will be sent as soon as possible at user preferred time. Mutually exclusive with schedule.
userMeta: Object keyed by user identifier of meta-data for each user
reportingMeta: Object of arbitrary meta-data about this notification
buttons: [
{
id: String, identifier of the button available in handler as 'actionId'. Required if buttons are set.
text: String, label for the button. Required if buttons are set.
},
...
]
ttl: Integer, number of seconds the message should be held at the messaging gateways for delivery attempts if the device is not currently online. Maximum of 2419200s (28 days), defaults to 3 days if not set.
releaseWindowMinutes: Integer, when set the message will be sent in batches equally split over the specified period. Allowed values are between 60 (1 hour) and 1440 (24 hours) inclusive.
}
POST https://messages.kumulos.com/v1/templated-notifications
¶
Payload¶
The request payload must be provided as a JSON object, with the following fields and validation rules met. If you are not using any optional fields, do not include them in the request.
{
target: {
broadcast: Boolean, when true the message will be sent to all registered devices
installIds: Array of installIds to send the notification to
userIds: Array of user identifiers to send the notification to
segmentUuid: Unique identifier of the segment to target
channelUuids: Array of unique identifier(s) of the channel(s) to target
geofenceIds: Array of integer ids of the geofence(s) to target
geofenceTags: Array of string tags of the geofence(s) to target
geofenceBroadcast: Boolean, target all installs in any geofence
excludeInstallIds: Install Ids to be excluded from the results of a channel or segment target
}
template: Unique identifier (uid) for the template, required
content: Object of dynamic content tags keyed by their respective title, required if template contains dynamic tags
schedule: { //Schedule the message. Omit to send immediately.
sendAt: DateTime of format "Y-m-d" (for strategy "intelligent") or "Y-m-d H:i" otherwise, required if schedule is set
strategy: String, either "local", "utc", "timezone" or "intelligent", required if schedule is set
pastTimes: String, either "ignore" or "nextDay", required if schedule is set
timezone: IANA Time Zone string, required if strategy is "timezone"
},
intelligentDelivery: Boolean, when true the message will be sent as soon as possible at user preferred time. Mutually exclusive with schedule.
userMeta: Object keyed by user identifier of meta-data for each user
releaseWindowMinutes: Integer, when set the message will be sent in batches equally split over the specified period. Allowed values are between 60 (1 hour) and 1440 (24 hours) inclusive.
}
At least one of broadcast or installIds/userIds or segmentUuid/channelUuids or geofence tags/ids must be provided to send a message and you cannot mix targeting options. i.e. You can broadcast to all users or target individual installs/users or target segments/channels or target users in a geofence. However, you can always exclude installs if required. You can find the UUIDs for channels and segments and the IDs for geofences in the Audience tab in your console.
If you target a segmentUuid, channelUuid(s) and geofenceId(s), then an install must match all of the filters in the segment, be subscribed to any of the channel(s) and be in one of the geofence(s) at the time the notification is scheduled to be sent in order for the notification to be sent to that install.
Sample cURL¶
curl -X POST
-H "Content-Type: application/json"
-H "Accept: application/json"
-u API_KEY:SERVER_KEY
-d '{
"target": { "broadcast": true },
"content": {"title": "Hello World", "message": "from Kumulos Push" }
}' "https://messages.kumulos.com/v2/notifications"
Sample PHP¶
<?php
$postData = json_encode(array(
"target" => [
"broadcast" => true,
],
"content" => [
"title" => "Test Broadcast",
"message" => "Test from PHP"
]
));
$curl = curl_init();
curl_setopt_array( $curl, [
CURLOPT_URL => "https://messages.kumulos.com/v2/notifications",
CURLOPT_HTTPHEADER => array (
'content-type: application/json',
'accept: application/json',
'content-length: ' . strlen($postData),
),
CURLOPT_USERPWD => 'API_KEY:SERVER_KEY',
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $postData,
CURLOPT_RETURNTRANSFER => true
] );
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
}
else {
echo $response;
}
?>
Responses¶
401 Unauthorized¶
Your request was rejected because the authorization header was not provided or poorly formed. Check your API Key, Server Key and that you have followed the HTTP Basic authentication strategy.
422 Unprocessable Entity¶
Your request was either unparsable / invalid JSON, was missing required fields, or had provided invalid values for a given key.
The response body will return a JSON object describing what keys were not present or had invalid values.
400 Bad Request¶
Your request was valid but all of the targeted users or installs do not exist or have unsubscribed from push notifications. No notification has been queued and the errors payload will describe the errors.
{
notification: null,
errors: {
unknownInstallIds: ["uuid1"]
unsubscribedInstallIds: ["uuid2"]
unknownUserIds: [123]
unsubscribedUserIds: [456]
}
}
202 Accepted¶
Your request was accepted and queued.
The response body will contain a JSON object describing the notification object that was created as a result, along with an errors key which when present describes any users or installs that were targeted but do not exist or have unsubscribed.
{
"notification": {
"appId":1,
"source":1,
"status":1,
"filters": { "broadcast":true },
"title":"Hello World",
"message":"from Kumulos Push",
"data":null,
"updatedAt":"2017-01-01T00:00:00+0000",
"createdAt":"2017-01-01T00:00:00+0000",
"id":1
},
"errors": {
unknownInstallIds: ["uuid1"]
unsubscribedInstallIds: ["uuid2"]
unknownUserIds: [123]
unsubscribedUserIds: [456]
}
}
Sending in-app messages¶
POST https://messages.kumulos.com/v1/in-app-messages
¶
Payload¶
The request payload must be provided as a JSON object, with the following fields and validation rules met. If you are not using any optional fields, do not include them in the request.
{
target: {
broadcast: Boolean, when true the message will be sent to all registered devices
installIds: Array of installIds to send the notification to
userIds: Array of user identifiers to send the notification to
segmentUuid: Unique identifier of the segment to target
channelUuids: Array of unique identifier(s) of the channel(s) to target
geofenceIds: Array of integer ids of the geofence(s) to target
geofenceTags: Array of string tags of the geofence(s) to target
geofenceBroadcast: Boolean, target all installs in any geofence
excludeInstallIds: Install Ids to be excluded from the results of a channel or segment target
}
template: Unique identifier (uid) for the template, required
content: Object of dynamic content tags keyed by their respective title, required if template contains dynamic tags
presentedWhen: String, required, either "immediately", "next-open" or "never"
data: Arbitrary data object accessible on an in-app message
ttl: { Time to live, required if presentedWhen is not "never"
expiresIn: Integer, required, time after which in-app message is not shown. Between 1 and 365
units: String, required, units for "expiresIn". Can be days ('d') or hours ('h')
}
notification: {
title: String, required if notification is set
message: String, required if notification is set
ios: { Optional
media:{
pictureUrl: String, URL for image to include in notification
}
relevanceScore: iOS15+, float between 0 and 1
interruptionLevel: iOS15+, String, one of: "passive", "active", "time-sensitive", "critical"
}
android: { Optional
pictureUrl: String, URL for image to include in notification,
notificationType: String, either "general" or "important", general will use the default category on device and drop into the notification tray. Important will present a heads-up notification. Cannot be combined with notificationChannel.
notificationChannel: String, the ID of the notification category on the device to put the notification into, must exist on the device or will fallback to kumulos "general". Cannot be combined with notificationType.
}
ttl: Integer, number of seconds the message should be held at the messaging gateways for delivery attempts if the device is not currently online. Maximum of 2419200s (28 days), defaults to 3 days if not set.
}
schedule: { //Schedule the message. Omit to send immediately.
sendAt: DateTime of format "Y-m-d" (for strategy "intelligent") or "Y-m-d H:i" otherwise, required if schedule is set
strategy: String, either "local", "utc", "timezone" or "intelligent", required if schedule is set
pastTimes: String, either "ignore" or "nextDay", required if schedule is set
timezone: IANA Time Zone string, required if strategy is "timezone"
},
userMeta: Object keyed by user identifier of meta-data for each user
reportingMeta: Object of arbitrary meta-data about this notification
intelligentDelivery: Boolean, when true the message will be sent as soon as possible at user preferred time. Mutually exclusive with schedule.
inbox: { If present in-app is stored in inbox
title: String, required if inbox is set
subtitle: String, required if inbox is set
availability: { Optional
from: DateTime of format "Y-m-d H:i:s", from when inbox is visible
to: DateTime of format "Y-m-d H:i:s", until when inbox is visible. Should be after "availability.from"
}
imageUrl: String, optional, URL for image to include in the inbox configuration available via the SDK APIs
}
releaseWindowMinutes: Integer, when set the message will be sent in batches equally split over the specified period. Allowed values are between 60 (1 hour) and 1440 (24 hours) inclusive.
}
At least one of broadcast or installIds/userIds or segmentUuid/channelUuids or geofence tags/ids must be provided to send a message and you cannot mix targeting options. i.e. You can broadcast to all users or target individual installs/users or target segments/channels or target users in a geofence. However, you can always exclude installs if required. You can find the UUIDs for channels and segments and the IDs for geofences in the Audience tab in your console.
If you target a segmentUuid, channelUuid(s) and geofenceId(s), then an install must match all of the filters in the segment, be subscribed to any of the channel(s) and be in one of the geofence(s) at the time the message is scheduled to be sent in order for the message to be sent to that install.
Sample cURL¶
curl -X POST
-H "Content-Type: application/json"
-H "Accept: application/json"
-u API_KEY:SERVER_KEY
-d '{
"target": { "broadcast": true },
"presentedWhen": "immediately",
"ttl": {
"expiresIn": 14,
"units": "d"
},
"template" => "fitness-promotion",
"content": {
"message-title": "Push Yourself",
"promotion-text": "Programs from $29/mo"
},
"data": {
"arbitrary": "data",
},
"notification": {
"title": "New Offer Available",
"message": "Open our app to view your new offer!"
},
"inbox": {
"title": "This is inbox title",
"subtitle": "This is inbox subtitle"
}
}' "https://messages.kumulos.com/v1/in-app-messages"
Sample PHP¶
<?php
$postData = json_encode(array(
"target" => [
"broadcast" => true,
],
"presentedWhen" => "immediately",
"ttl" => [
"expiresIn" => 14,
"units" => "d"
],
"template" => "fitness-promotion",
"content" => [
"message-title" => "Push Yourself",
"promotion-text" => "Programs from $29/mo"
],
"data" => [
"arbitrary" => "data"
],
"notification" => [
"title" => "New Offer Available",
"message" => "Open our app to view your new offer!"
],
"inbox" => [
"title" => "This is inbox title",
"subtitle" => "This is inbox subtitle"
]
));
$curl = curl_init();
curl_setopt_array( $curl, [
CURLOPT_URL => "https://messages.kumulos.com/v1/in-app-messages",
CURLOPT_HTTPHEADER => array (
'content-type: application/json',
'accept: application/json',
'content-length: ' . strlen($postData),
),
CURLOPT_USERPWD => 'API_KEY:SERVER_KEY',
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $postData,
CURLOPT_RETURNTRANSFER => true
] );
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
}
else {
echo $response;
}
?>
Responses¶
401 Unauthorized¶
Your request was rejected because the authorization header was not provided or poorly formed. Check your API Key, Server Key and that you have followed the HTTP Basic authentication strategy.
422 Unprocessable Entity¶
Your request was either unparsable / invalid JSON, was missing required fields, or had provided invalid values for a given key.
The response body will return a JSON object describing what keys were not present or had invalid values.
404 Not Found¶
A template with the given UID could not be found
400 Bad Request¶
Your request was valid but all of the targeted users or installs do not exist or the users don't have in-app messages enabled. No message has been queued and the errors payload will describe the errors.
{
message: null,
errors: {
unknownInstallIds: ["uuid1"]
unsubscribedInstallIds: ["uuid2"]
unknownUserIds: [123]
unsubscribedUserIds: [456]
}
}
202 Accepted¶
Your request was accepted and queued.
The response body will contain a JSON object describing the message object that was created as a result, along with an errors key which when present describes any users or installs that were targeted but do not exist or have disabled in-app messages.
{
"errors": {
"unknownInstallIds": ["uuid1"],
"unsubscribedInstallIds": ["uuid2"],
"unknownUserIds": [123],
"unsubscribedUserIds": [456]
},
"message": {
"id": 1,
"status": "queued",
"target": {
"broadcast": true
},
"data": {
"arbitrary": "data"
},
"reportingMeta": null,
"badge": null,
"schedule": null,
"updatedAt": "2017-01-01T00:00:00+0000",
"createdAt": "2017-01-01T00:00:00+0000",
"isTemplate": false,
"parentMessageId": null,
"sentAt": null,
"recurrence": null,
"completedAt": null,
"hasEditedSchedule": false,
"hasEditedContent": false,
"intelligentDeliveryAsap": false,
"releaseWindowMinutes": null,
"children": [],
"appId": 1,
"template": "fitness-promotion",
"content": {
...JSON Object of the literal template content, with any dynamic content tags replaced using the "content" field from request
},
"presentedWhen": "immediately",
"ttl": {
"units": "d",
"expiresIn": 14
},
"inbox": {
"visibleFrom": "2017-01-01T00:00:00+0000",
"visibleTo": "2017-02-01T00:00:00+0000",
"title": "This is inbox title",
"subtitle": "This is inbox subtitle",
"imageUrl": null
},
"notification": {
"title": "This is the notification title",
"message": "This is the notification message",
"ios": null,
"android": null,
"ttl": 1440
}
}
}
Cancelling a scheduled notification¶
You can cancel a notification that has been scheduled to send in the future using the ID of the notification that was created as follows:
DELETE https://messages.kumulos.com/v2/scheduled-notifications/{id}
¶
Sample cURL¶
curl -X DELETE
-H "Content-Type: application/json"
-H "Accept: application/json"
-u API_KEY:SERVER_KEY
"https://messages.kumulos.com/v2/scheduled-notifications/{id}"
Responses¶
401 Unauthorized¶
Your request was rejected because the authorization header was not provided or poorly formed. Check your API Key, Server Key and that you have followed the HTTP Basic authentication strategy.
400 Bad Request¶
Your request was valid but the notification has already been sent (or has been cancelled).
{
"error": "Notification already sent"
}
404 Not Found¶
A notification with the given ID could not be found.
204 No Content¶
Your request was accepted and processed - the notification has been cancelled.
Checking open rates¶
You can then use the ID of the notification created to get the installs or users that have opened the notification. This will allow you to track who or which install has opened what message and when. Very useful if you are measuring the effectiveness of your push campaigns.
Retrieving the installs that opened the notification¶
GET https://messages.kumulos.com/notifications/{id}/install-opens
¶
Sample cURL¶
curl -X GET
-H "Content-Type: application/json"
-H "Accept: application/json"
-u API_KEY:SERVER_KEY
"https://messages.kumulos.com/notifications/1/install-opens"
Responses¶
401 Unauthorized¶
Your request was rejected because the authorization header was not provided or poorly formed. Check your API Key, Server Key and that you have followed the HTTP Basic authentication strategy.
200 OK¶
Your request was accepted and processed.
The response body will contain an array of JSON objects showing the install IDs that opened the notification along with the time that the open was recorded.
[
{"installId":"abcdefgh","openedAt":"2017-01-01 00:00:00"},
{"installId":"ijklmnop","openedAt":"2017-01-01 00:00:00"}
]
Retrieving the users that opened the notification¶
GET https://messages.kumulos.com/notifications/{id}/user-opens
¶
Sample cURL¶
curl -X GET
-H "Content-Type: application/json"
-H "Accept: application/json"
-u API_KEY:SERVER_KEY
"https://messages.kumulos.com/notifications/1/user-opens"
Responses¶
401 Unauthorized¶
Your request was rejected because the authorization header was not provided or poorly formed. Check your API Key, Server Key and that you have followed the HTTP Basic authentication strategy.
200 OK¶
Your request was accepted and processed.
The response body will contain an array of JSON objects showing the install IDs that opened the notification along with the time that the open was recorded.
[
{"userId":"user-abcdefgh","openedAt":"2017-01-01 00:00:00"},
{"userId":"user-ijklmnop","openedAt":"2017-01-01 00:00:00"}
]
Using meta-data¶
If you use the User Association feature to identify your users to Kumulos from device SDKs and are making use of the userIds
targeting option, then the userMeta
, and reportingMeta
fields give you a flexible way to target & report on push notifications.
Reporting Meta-Data¶
When sending a notification, you may wish to associate meaningful meta-data with the notification. This meta-data will be reflected in the data field of any push events generated as a result of the notification and the user's interaction with the notification.
For example, if you wanted to send a campaign identifier, you could add the following to the send notification request:
{
...
"reportingMeta": {
"campaign": "Summer Promotion"
}
}
User Meta¶
User meta-data extends the concept of reporting meta-data to the user level when targeting pushes based on user identifiers.
For example, if sending to users, you can include meta-data specific to each user which will be reflected in any push events related to that user's notification & interactions with the message.
For example, if for each member you wanted to pass their current sequence number in a drip-feed content flow:
{
...
"userIds": ["member-id-1", "member-id-2"],
"userMeta": {
"member-id-1": { "messageSequenceNumber": 1 },
"member-id-2": { "messageSequenceNumber": 3 }
}
}
Creating a geofence¶
POST https://messages.kumulos.com/v1/geofences
¶
Sample cURL¶
Circle Geofence¶
curl -X POST
-H "Content-Type: application/json"
-H "Accept: application/json"
-u API_KEY:SERVER_KEY
-d '{
"name": "Circular Geofence",
"boundsGeoJson": {
"type": "Feature",
"properties": {
"radius": 425
},
"geometry": {
"type": "Point",
"coordinates": [-73.9652551,40.7827647]
}
},
"isEnabled": true,
"tags": ["Tourism", "Nature"]
}' "https://messages.kumulos.com/v1/geofences"
The boundsGeoJson
object is in GeoJSON format and radius
is specified in metres.
Polygon Geofence¶
curl -X POST
-H "Content-Type: application/json"
-H "Accept: application/json"
-u API_KEY:SERVER_KEY
-d '{
"name": "Polygon Geofence",
"boundsGeoJson": {
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-73.95815849304199,40.80065354924362],
[-73.98193359375,40.76802920702854],
[-73.97309303283691,40.76432383634019],
[-73.9493179321289,40.796949998204596],
[-73.95815849304199,40.80065354924362]
]
]
},
"properties": {
"orderAdded": [
0, 1, 2, 3, 4
],
"markerLocation": [
40.783102, -73.965074
]
}
},
"isEnabled": true,
"tags": ["Tourism", "Nature"]
}' "https://messages.kumulos.com/v1/geofences"
Again, the boundsGeoJson
object is in GeoJSON format and the orderAdded
array is required (to allow subsequent editing of the geofence points in the Kumulos UI).
Responses¶
401 Unauthorized¶
Your request was rejected because the authorization header was not provided or poorly formed. Check your API Key, Server Key and that you have followed the HTTP Basic authentication strategy.
422 Unprocessable Entity¶
Your request was either unparsable / invalid JSON, was missing required fields, or had provided invalid values for a given key.
The response body will return a JSON object describing what keys were not present or had invalid values.
201 Created¶
Your request was accepted and processed.
The response body will contain a JSON object describing the geofence that was created as a result.
Circle Geofence Response¶
{
"id": 1,
"name": "Circular Geofence",
"isEnabled": true,
"boundsGeoJson": {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-73.9652551,
40.7827647
]
},
"properties": {
"radius": 425
}
},
"activationCount": 0,
"createdAt": "2019-06-28T13:48:34+0000",
"updatedAt": "2019-06-28T13:48:34+0000",
"activeUsers": 0,
"appId": 1,
"tags": [
"Tourism",
"Nature"
]
}
Polygon Geofence Response¶
{
"id": 2,
"name": "Polygon Geofence",
"isEnabled": true,
"boundsGeoJson": {
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-73.95815849304199,40.80065354924362],
[-73.98193359375,40.76802920702854],
[-73.97309303283691,40.76432383634019],
[-73.9493179321289,40.79694999820459],
[-73.95815849304199,40.80065354924362]
]
]
},
"properties": {
"orderAdded": [
0, 1, 2, 3, 4
],
"markerLocation": [
40.783102, -73.965074
]
}
},
"activationCount": 0,
"createdAt": "2019-06-27T12:24:08+0000",
"updatedAt": "2019-06-27T12:24:08+0000",
"activeUsers": 0,
"appId": 1,
"tags": [
"Tourism",
"Nature"
]
}
Channels¶
Creating a channel¶
POST https://messages.kumulos.com/channels
¶
Sample cURL¶
curl -X POST
-H "Content-Type: application/json"
-H "Accept: application/json"
-u API_KEY:SERVER_KEY
-d '{
"uuid": "channel-uuid",
"name": "friendly name"
"showInPortal": true
"meta": {
"additional": "data"
}
}' "https://messages.kumulos.com/channels"
Responses¶
401 Unauthorized¶
Your request was rejected because the authorization header was not provided or poorly formed. Check your API Key, Server Key and that you have followed the HTTP Basic authentication strategy.
422 Unprocessable Entity¶
Your request was either unparsable / invalid JSON, was missing required fields, or had provided invalid values for a given key.
The response body will return a JSON object describing what keys were not present or had invalid values.
201 Created¶
Your request was accepted and processed.
The response body will contain a JSON object describing the channel that was created as a result.
{
"appId":1,
"uuid":"channel-uuid",
"name":"Channel Name",
"showInPortal":true,
"meta": {
"additional":"data"
},
"updatedAt":"2017-02-16 14:43:03",
"createdAt":"2017-02-16 14:43:03",
"id":1
}
Updating a channel¶
PUT https://messages.kumulos.com/channels/{id}
¶
Sample cURL¶
curl -X PUT
-H "Content-Type: application/json"
-H "Accept: application/json"
-u API_KEY:SERVER_KEY
-d '{
"uuid": "channel-uuid",
"name": "friendly name"
"showInPortal": true
"meta": {
"additional": "data"
}
}' "https://messages.kumulos.com/channels/{id}"
Responses¶
401 Unauthorized¶
Your request was rejected because the authorization header was not provided or poorly formed. Check your API Key, Server Key and that you have followed the HTTP Basic authentication strategy.
422 Unprocessable Entity¶
Your request was either unparsable / invalid JSON, was missing required fields, or had provided invalid values for a given key.
The response body will return a JSON object describing what keys were not present or had invalid values.
200 OK¶
Your request was accepted and processed.
The response body will contain a JSON object describing the channel in its updated state.
{
"appId":1,
"uuid":"channel-uuid",
"name":"Channel Name",
"showInPortal":true,
"meta": {
"additional":"data"
},
"updatedAt":"2017-02-16 14:43:03",
"createdAt":"2017-02-16 14:43:03",
"id":1
}
Deleting a channel¶
DELETE https://messages.kumulos.com/channels/{id}
¶
curl -X DELETE
-H "Content-Type: application/json"
-H "Accept: application/json"
-u API_KEY:SERVER_KEY
"https://messages.kumulos.com/channels/{id}"
Responses¶
401 Unauthorized¶
Your request was rejected because the authorization header was not provided or poorly formed. Check your API Key, Server Key and that you have followed the HTTP Basic authentication strategy.
204 No Content¶
Your request was accepted and processed.
Subscribing installs to a channel¶
POST https://messages.kumulos.com/v2/channels/{uuid}/subscriptions
¶
Sample cURL¶
curl -X POST
-H "Content-Type: application/json"
-H "Accept: application/json"
-u API_KEY:SERVER_KEY
-d '{
"installIds": ["uuid-1", "uuid-2"]
}' "https://messages.kumulos.com/v2/channels/{uuid}/subscriptions"
Responses¶
401 Unauthorized¶
Your request was rejected because the authorization header was not provided or poorly formed. Check your API Key, Server Key and that you have followed the HTTP Basic authentication strategy.
422 Unprocessable Entity¶
Your request was either unparsable / invalid JSON, was missing required fields, or had provided invalid values for a given key.
The response body will return a JSON object describing what keys were not present or had invalid values.
204 No Content¶
Your request was accepted and processed.
200 OK¶
Your request was accepted and processed.
The response body will contain a JSON object with an errors key which will describe any installs that do not exist.
{
"errors": {
unknownInstallIds: ["uuid1", "uuid2"]
}
}
Subscribing users to a channel¶
POST https://messages.kumulos.com/v2/channels/{uuid}/subscriptions
¶
Sample cURL¶
curl -X POST
-H "Content-Type: application/json"
-H "Accept: application/json"
-u API_KEY:SERVER_KEY
-d '{
"userIds": ["memeber-id-1", "memeber-id-2"]
}' "https://messages.kumulos.com/v2/channels/{uuid}/subscriptions"
Responses¶
401 Unauthorized¶
Your request was rejected because the authorization header was not provided or poorly formed. Check your API Key, Server Key and that you have followed the HTTP Basic authentication strategy.
422 Unprocessable Entity¶
Your request was either unparsable / invalid JSON, was missing required fields, or had provided invalid values for a given key.
The response body will return a JSON object describing what keys were not present or had invalid values.
204 No Content¶
Your request was accepted and processed.
200 OK¶
Your request was accepted and processed.
The response body will contain a JSON object with an errors key which will describe any users that do not exist.
{
"errors": {
unknownUserIds: ["memeber-id-1", "memeber-id-2"]
}
}
Subscribing users to a channel (bulk CSV)¶
POST https://messages.kumulos.com/v2/channels/{uuid}/subscribers-file
¶
If you need to subscribe many users to a channel, you can upload a CSV containing user identifiers. The CSV file should:
- Be UTF-8 encoded
- Have extension .csv and MIME type text/csv
- Have a single column of user identifier strings, one per line
- No single user identifier string should be longer than 255 characters
- Not have a header row
Sample cURL¶
curl -X POST
-H "Accept: application/json"
-u API_KEY:SERVER_KEY
-F '[email protected]' "https://messages.kumulos.com/v2/channels/{uuid}/subscribers-file"
Responses¶
401 Unauthorized¶
Your request was rejected because the authorization header was not provided or poorly formed. Check your API Key, Server Key and that you have followed the HTTP Basic authentication strategy.
404 Not Found¶
The channel you are attempting to subscribe to could not be found, please check the UUID parameter in the URL.
422 Unprocessable Entity¶
Your request was either unparsable / invalid CSV, was missing required fields, or had provided invalid values for a given key.
The response body will return a JSON object describing what keys were not present or had invalid values.
202 Accepted¶
Your request was accepted and queued for processing, it will be processed shortly.
Unsubscribing installs from a channel¶
DELETE https://messages.kumulos.com/v2/channels/{uuid}/subscriptions
¶
Sample cURL¶
curl -X DELETE
-H "Content-Type: application/json"
-H "Accept: application/json"
-u API_KEY:SERVER_KEY
-d '{
"installIds": ["uuid-1", "uuid-2"]
}' "https://messages.kumulos.com/v2/channels/{uuid}/subscriptions"
Responses¶
401 Unauthorized¶
Your request was rejected because the authorization header was not provided or poorly formed. Check your API Key, Server Key and that you have followed the HTTP Basic authentication strategy.
422 Unprocessable Entity¶
Your request was either unparsable / invalid JSON, was missing required fields, or had provided invalid values for a given key.
The response body will return a JSON object describing what keys were not present or had invalid values.
204 No Content¶
Your request was accepted and processed.
200 OK¶
Your request was accepted and processed.
The response body will contain a JSON object with an errors key which will describe any installs that do not exist.
{
"errors": {
unknownInstallIds: ["uuid1", "uuid2"]
}
}
Unsubscribing users from a channel¶
DELETE https://messages.kumulos.com/v2/channels/{uuid}/subscriptions
¶
Sample cURL¶
curl -X DELETE
-H "Content-Type: application/json"
-H "Accept: application/json"
-u API_KEY:SERVER_KEY
-d '{
"userIds": ["memeber-id-1", "memeber-id-2"]
}' "https://messages.kumulos.com/v2/channels/{uuid}/subscriptions"
Responses¶
401 Unauthorized¶
Your request was rejected because the authorization header was not provided or poorly formed. Check your API Key, Server Key and that you have followed the HTTP Basic authentication strategy.
422 Unprocessable Entity¶
Your request was either unparsable / invalid JSON, was missing required fields, or had provided invalid values for a given key.
The response body will return a JSON object describing what keys were not present or had invalid values.
204 No Content¶
Your request was accepted and processed.
200 OK¶
Your request was accepted and processed.
The response body will contain a JSON object with an errors key which will describe any users that do not exist.
{
"errors": {
unknownUserIds: ["memeber-id-1", "memeber-id-2"]
}
}
Calling from KScript¶
If you have multiple apps on Kumulos and you want an event in one app to trigger a push notification to an install of another app, you can do this using the HTTP client in a Kscript method.
var username = 'API Key of your other Kumulos app';
var password = 'Server Key of your other Kumulos app';
var auth = base64_encode( username + ':' + password );
var client = K.http.createClient('https://messages.kumulos.com');
var headers =
{
'Authorization': 'Basic ' + auth,
'Content-Type': 'application/json',
'Accept': 'application/json'
};
var params =
{
'broadcast': true,
'title' : 'Hello',
'message': 'World'
};
var response = client.post('notifications', K.JSON.stringify(params), headers);
if (response.isError()) {
K.log(res.getBody());
}
If you have companion apps with different push notification certificates and API methods but you want two apps to share the same a backend database tables (for example: to access the Install IDs of the other app), please contact technical support who can arrange this.
Configure Push Notification Gateways for an App¶
PUT https://push.kumulos.com/v1/apps/{appId}
Substitute the appId in the path with the integer ID of an app to set the configuration for.
Authentication¶
Authentication for this endpoint is via HTTP basic auth with the app apiKey
as the username and the app serverKey
as the password. These were in the response body when the app was created.
Request payload (application/json)¶
{
"android": {
"serverKey": [string],
"serviceAccount": {
"projectId": [string],
"privateKeyId": [string]
"privateKey": [string]
"clientEmail": [email]
"clientId": [string],
"authUri": [uri],
"tokenUri": [uri],
"authProviderX509CertUrl": [url],
"clientX509CertUrl": [url],
}
},
"ios": {
"p12": [base64 string, certificate contents],
"mode": [string, 'sandbox' or 'production'],
"password": [optional string]
// p8 configuration cannot be combined with p12
"p8": [base64 string, certificate contents],
"keyId": [string, the keyID provided when it was generated],
"teamId": [string, your Apple Developer account team identifier]
"bundleId": [string, the bundleId for the app]
},
"web": {
"iconUrl": [url]
},
"hcm": {
"appId": [integer],
"appIdPassword": [string]
},
"safari": {
"p12": [base64 string, certificate contents],
"password": [string],
"iconUrl": [string],
"siteUrl": [url]
}
}
Responses¶
200 - OK¶
Your request was successful, the response body will contain details of the app and what platforms have been configured. Example response body (application/json):
{
"id": 1,
"accountId": 1,
"createdAt": "2020-12-21T15:58:59+0000",
"platformConfigs": [
{
"platformType": 2,
"createdAt": "2020-12-21T15:58:59+0000",
"updatedAt": "2020-12-21T15:58:59+0000"
}
]
}
401 - Unauthorized¶
Your request was rejected because the authorization header was not provided or poorly formed. Check your app apiKey
and serverKey
and that you have followed the HTTP basic auth strategy.
403 - Forbidden¶
Your credentials were correct but do not give you access to the client or app specified.
422 - Unprocessable Entity¶
Your request was either unparsable / invalid JSON, was missing required email field, or have provided a invalid gateway configuration. The response body will return a JSON object describing what keys were not present or had invalid values.
Complete Example¶
Below is an example of configuring android push notifications with the Google FCM gateway:
PUT https://push.kumulos.com/v1/apps/1
{
"android": {
"serverKey": "AAAAeVHrnes:APA91bGpsKN...",
"serviceAccount": {
"projectId": "my-app-name",
"privateKeyId": "42d2d9f...",
"privateKey": "-----BEGIN PRIVATE KEY-----\nLENGTHYCRYPTOGRAPHICSTRING\n-----END PRIVATE KEY-----\n",
"clientEmail": "fi[email protected]",
"clientId": "289585204963045939329",
"authUri": "https://accounts.google.com/o/oauth2/auth",
"tokenUri": "https://oauth2.googleapis.com/token",
"authProviderX509CertUrl": "https://www.googleapis.com/oauth2/v1/certs",
"clientX509CertUrl": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-e85gkt%40my-app-name.iam.gserviceaccount.com",
}
}
}
Response: 200¶
{
"id": 1,
"accountId": 1,
"createdAt": "2020-12-21T15:58:59+0000",
"updatedAt": "2020-12-21T15:58:59+0000",
"platformConfigs": [
{
"platformType": 2,
"createdAt": "2020-12-21T15:58:59+0000",
"updatedAt": "2020-12-21T15:58:59+0000"
}
]
}
Read Push Notification Gateway Status¶
Returns a list of platform config statuses which contain the platform type and creation/update timestamps. This serves as a quick status check to indicate which gateways have had configurations set for them for a given app.
GET https://push.kumulos.com/v1/apps/{appId}
Substitute the appId in the path with the integer ID of an app to set the configuration for.
Authentication¶
Authentication for this endpoint is via HTTP basic auth with the app apiKey
as the username and the app serverKey
as the password. These were in the response body when the app was created.
Request payload (application/json)¶
No payload required for GET based request.
Responses¶
200 - OK¶
Your request was successful, the response body will contain details of the app and what platforms have been configured. Example response body (application/json):
{
"id": 1,
"accountId": 1,
"createdAt": "2020-12-21T15:58:59+0000",
"platformConfigs": [
{
"platformType": 2,
"createdAt": "2020-12-21T15:58:59+0000",
"updatedAt": "2020-12-21T15:58:59+0000"
}
]
}
401 - Unauthorized¶
Your request was rejected because the authorization header was not provided or poorly formed. Check your app apiKey
and serverKey
and that you have followed the HTTP basic auth strategy.
403 - Forbidden¶
Your credentials were correct but do not give you access to the client or app specified.
Complete Example¶
Below is an example which returns the full set of configured gateways for each platform, for app id 1:
GET https://push.kumulos.com/v1/apps/1
{
"id": 1,
"accountId": 1,
"createdAt": "2020-12-21T15:58:59+0000",
"platformConfigs": [
{
"platformType": 1,
"createdAt": "2020-12-21T15:58:59+0000",
"updatedAt": "2020-12-21T15:58:59+0000"
},
{
"platformType": 2,
"createdAt": "2020-12-21T15:58:59+0000",
"updatedAt": "2020-12-21T15:58:59+0000"
},
{
"platformType": 3,
"createdAt": "2020-12-21T15:58:59+0000",
"updatedAt": "2020-12-21T15:58:59+0000"
},
{
"platformType": 4,
"createdAt": "2020-12-21T15:58:59+0000",
"updatedAt": "2020-12-21T15:58:59+0000"
},
{
"platformType": 5,
"createdAt": "2020-12-21T15:58:59+0000",
"updatedAt": "2020-12-21T15:58:59+0000"
}
]
}
Where platformType
:
platformType | Platform Name |
---|---|
1 | iOS |
2 | Android (FCM) |
3 | Web |
4 | Safari |
5 | Android (HCM) |
Changelog¶
v2¶
- Added support for more detailed feedback on creation of notification
- Deprecated v1 documentation