POST Notifications

Send push notifications to segments of your users.

https://api.carnivalmobile.com/v6/notifications


Parameters

Body Parameters

Name Type Required Definition
notification object Yes JSON model of notification
notification.to object Yes A description of the devices to be targeted by the push. Can either be a set of criteria as an Object, or a string referring to the ID of an existing audience. More information on how to format this below.
notification.payload object Yes The content of the notification sent to the device. Can have arbitrary k/v values, but certain values - alert, title, subtitle, badge, category and sound are treated specially by the Sailthru Mobile Platform
notification.payload.title string No The title of the notification. Displays in bold on devices. Only displays on android phones using SDK > v5.7.0.
notification.payload.subtitle string No The subtitle of the notification, not displayed on Android. On iOS, displays in bold under the title.
notification.payload.alert string No The body text of the notification
notification.payload.badge integer No The number to display in a badge on your app's icon.
notification.payload.sound string No The name of a sound file in your app

Examples

Expand the example by clicking the title. On The Fly Audiences

Copy
curl -X POST -u :$API_KEY -H "Content-type: application/json" -H 'Accept: application/json' https://api.carnivalmobile.com/v6/notifications -d '{
  "notification": {
    "to": [{ "name": "events.video_plays", "criteria": [{ "gt": 10 }]}, { "name": "custom.string.video_category", "criteria": ["sports"]}],
    "payload": {
      "alert": "This is a push notification test",
      "badge": 1,
      "sound": "Default.caf",
      "category": "TEST_CATEGORY",
      "any_key": "any_value" // Arbitrary keys/values.
    }
  }
}'// Events sent via our API must be prefixed by `Public Api`. The same applies
// if you're using auto-analytics.
curl -X POST -u :$API_KEY -H "Content-type: application/json" -H 'Accept: application/json' https://api.carnivalmobile.com/v6/notifications -d '{
  "notification": {
    "to": [{ "name": "events.Public Api.web_login", "criteria": [{ "gt": 10 }]}],
    "payload": {
      "alert": "This is a push notification test",
      "badge": 1,
      "sound": "Default.caf",
      "category": "TEST_CATEGORY",
      "any_key": "any_value" // Arbitrary keys/values.
    }
  }
}'
Predefined Audience
Copy
curl -X POST -u :$API_KEY -H "Content-type: application/json" -H 'Accept: application/json' https://api.carnivalmobile.com/v6/notifications -d '{
  "notification": {
    "to": { "audience" : "55961e0741646178d0010010" },
    "payload": {
      "alert": "This is a push notification test",
      "badge": 1,
      "sound": "Default.caf",
      "any_key": "any_value" // Arbitrary keys/values.
    }
  }
}'
Everyone
Copy
// Note that you have to explicitly use an asterisk(*) to send a push notification to everyone.
curl -X POST -u :$API_KEY -H "Content-type: application/json" -H 'Accept: application/json' https://api.carnivalmobile.com/v6/notifications -d ' {
  "notification": {
    "to":  "*",
    "payload": {
      "alert": "This is a push notification test",
      "badge": 1,
      "sound": "Default.caf",
      "any_key": "any_value" // Arbitrary keys/values.
    }
  }
}'
Specific Users
Copy
curl -X POST -u :$API_KEY -H "Content-type: application/json" -H 'Accept: application/json' https://api.carnivalmobile.com/v6/notifications -d '{
  "notification": {
    "to": [{ "name": "user_id", "criteria": ["1234"]}],
    "payload": {
      "alert": "This is a push notification test",
      "badge": 1,
      "sound": "Default.caf",
      "any_key": "any_value" // Arbitrary keys/values.
    }
  }
}'
Rich Push
Copy
curl -X POST -u :$API_KEY -H "Content-type: application/json" -H 'Accept: application/json' https://api.carnivalmobile.com/v6/notifications -d '{
  "notification": {
    "to": [{ "name": "custom.string.mykey", "criteria": ["tag2"]}],
    "payload": {
      "alert": "Check out this rich push!",
      "badge": 1,
      "sound": "Default.caf",
      "category": "TEST_CATEGORY",
      "mutable_content": true,
      "_st": {
        "image_url": "https://www.mysite.com/img.png"      }
    }
  }
}'
Liquid Template
Copy
# Users with custom attributes will receive something similar to:
# "Hello Simon, we just updated your Sneakers collection with brand new arrivals."# Users with no custom attributes will receive:
# "Hello there, we just updated your collection with brand new arrivals."curl -X POST -u :$API_KEY -H "Content-type: application/json" -H 'Accept: application/json' https://api.carnivalmobile.com/v6/notifications -d '{
  "notification": {
    "to":  [{"name": "device_id", "criteria": ["1234", "5678", "79894"]}],
    "payload": {
      "alert": "Hello {{custom.first_name | default: 'there'}}, we just updated your {{custom.favorite_collection}} collection with brand new arrivals.",
      "badge": 1,
      "sound": "Default.caf"    }
  }
}'
Distance Filter
Copy
curl -X POST -u :$API_KEY -H "Content-type: application/json" -H 'Accept: application/json' https://api.carnivalmobile.com/v6/notifications -d '{
  "notification": {
    "to": [{ "name": "sdk_location",
             "criteria": [{ "point": { "latitude": -41.1339, "longitude": 174.8406 },
                            "distance": 4, "unit": "kilometers" }] }],
    "payload": {
      "alert": "This is a push notification test",
      "badge": 1,
      "sound": "Default.caf",
      "any_key": "any_value" // Arbitrary keys/values.
    }
  }
}'
Polygon Filter
Copy
curl -X POST -u :$API_KEY -H "Content-type: application/json" -H 'Accept: application/json' https://api.carnivalmobile.com/v6/notifications -d '{
  "notification": {
    "to": [{ "name": "location",
             "criteria": [{ "polygon":
                [{ "latitude": -41.31243, "longitude": 174.75154 }, 
                 { "latitude": -41.30341, "longitude": 174.96063 }, 
                 { "latitude": -41.19293, "longitude": 174.91806 }, 
                 { "latitude": -41.20029, "longitude": 174.76511 }]
        }] }],
    "payload": {
      "alert": "This is a push notification test",
      "badge": 1,
      "sound": "Default.caf",
      "any_key": "any_value" // Arbitrary keys/values.
    }
  }
}'
Update Push
Copy
# Define a collapse_key you can reuse in subsequent calls. In this case, our collapse_key is notification_19cbba0022

curl -X POST -u :$API_KEY -H "Content-type: application/json" -H 'Accept: application/json' https://api.carnivalmobile.com/v6/notifications -d '{
  "notification": {
    "to": [{ "name": "user_id", "criteria": ["1234"]}],
    "payload": {
      "alert": "Story developing: highest attendance on records for the 4th of July parade.",
      "badge": 1,
      "collapse_key": "notification_19cbba0022",
      "sound": "Default.caf"    }
  }
}'# Send an update by referencing the same collapse key, but changing the push payload
curl -X POST -u :$API_KEY -H "Content-type: application/json" -H 'Accept: application/json' https://api.carnivalmobile.com/v6/notifications -d '{
  "notification": {
    "to": [{ "name": "user_id", "criteria": ["1234"]}],
    "payload": {
      "alert": "Update: highest attendance on records for the 4th of July parade. Over one million people attended the event.",
      "badge": 1,
      "_u": "https://example.com/story/19cbba0022/4th-july-parade",
      "collapse_key": "notification_19cbba0022",
      "sound": "Default.caf"    }
  }
}'

Result Format

201 Created

Copy
{
  "created_at": "2017-03-09T13:23:37.488Z",
  "state": "scheduled",
  "id": "58c157595c50nz000e347f79",
  "to": {
    "id": "589b54e38b1ny0000876e528",
    "type": "Audience"  },
  "notification": {
    "id": "58c157595c50nz000e347f7a", // The Notification ID to use with the Stats endpoint
    "created_at": "2017-03-09T13:23:37.502Z",
    "payload": {
      "alert": "This is a push notification test",
      "badge": 1,
      "sound": "Default.caf",
      "category": "TEST_CATEGORY",
      "any_key": "any_value"    }
  }
}

401 Unauthorized

Copy
// This error is given when your API client credentials are not correct. 
{
  "error":"unauthorized"}

403 Forbidden

Copy
// This error is given when your API client does not have the ability to send Push Notifications.
{
  "error":"your api client does not have the correct roles"}

422 Unprocessable Entity

Copy
{
error: # Dependant on why the request body was incorrect. 
}

Payload field

Updating Notifications

You can update a notification (including its payload) by specifying a collapse_key in the notification payload. This key acts as a unique identifier, so that you can reference the same notification in subsequent Notifications API requests.

Platform-specific Data

Some payload values are treated specially by iOS or Android. Below we describe some specific keys that can cause different behavior depending on the platform.

iOS

Key Description
content_available Must be true or false. Setting this value to true will cause an inactive app to be awoken. APNs does not guarantee that it will be delivered and it can depend on different factors like battery level, app not in memory, etc. This field will be used as part of the APNs payload for the key content-available.
mutable_content Must be true or false. If set to true the notification content can be modified before it is displayed. This field will be used as part of the APNs payload for the key mutable-content. iOS 10+ devices only. More information can be found here.
category APNs Notification identifier. Example: survey The identifier must be registered by the app using UNNotificationCategory. This field will be used as part of the APNs payload for the key category. More information can be found here.
interruption_level Must be passiveactivetime-sensitive or critical. This value is used to determine the interruption-level for the notification on iOS 15+. If absent the default behavior is active. More information about interruption levels can be found here.
relevance_score Must be a numerical value between 0 and 1 inclusive. Maximum accuracy is to two decimal places. This value is used to determine the relevance-score for the notification on iOS 15+. If absent the default score is 0.

Android

Key Description
_channel_id The notification's channel id (new in Android Oreo, SDK 26). Example: news The channel must be created by the application prior to receiving the push with such identifier. More information about Android Channels can be found here.
category Firebase Action identifier. Example: survey The identifier must be registered using NotificationConfig More information can be found here.

Reserved Keys

Some keys are reserved by the APNs or Firebase and they must not be used:

  • available
  • from
  • gcm
  • Any value prefixed by google

Sailthru Mobile define some internal keys that should not be set:

  • _st
  • _u (used for Deep Linking)

Other keys and values will be assumed to be custom keys, and will be included in the push payload.

To Field

There are three options for target devices:
  • "*": will target everyone
  • { "audience": "AUDIENCE_ID" }: an object with key audience and the value being the Audience ID. Will target all users in the specified audience. You can retrieve an ID via Audiences API or as a result of creating an on-the-fly audience (see below).
  • [{ "name": "CRITERIA_TYPE", "criteria": [CRITERIA_1, CRITERIA_2, ...]}, {...}]: an array of one or more filters for creating an on-the-fly audience (see Filters below). Will target devices that match the specified criteria.

Note: Be extremely careful with this endpoint during testing, especially when using "to": "*" . We recommend setting up a different app on Sailthru Mobile from your production app to avoid accidental communication with your users.

Targeting Test Devices

You can send notification to your testers by flagging your test devices as 'development' within the Sailthru Mobile dashboard. When you do so, you can send a push notification to your devices by creating this audience: [{"name": "development", "criteria": [true]}]

Note: By default, Xcode builds your app against the Debug scheme, which maps to your Development provisioning profile which in turn can only talk to the Sandbox APNS. If your Xcode scheme is Debug, make sure to target your Device ID using an on-the-fly audience, and make sure your device is in development mode. You can set this up here: Testing Developer Push Notifications.

Filters

A filter is an object composed of three attributes: namecriteria and not_filter.

Filter attributeDetails
nameString. Device attribute on which the criteria will be applied. Example: { "name": "locale", criteria: ["en_US"] } will match devices with en_US locale. See the list of valid names/attributes below.
criteriaArray with values to match.Provide at least one element of type string, integer, float, boolean or a range object (see below how to define a range object).
not_filterBoolean. When true, it will match devices that don't match the criteria. Default is false.

Valid names/attributes for a filter

Name/AttributeDescription
localeLocale used on the device, specified as a combination of ISO 639-1 and ISO 3166-1 alpha-2 e.g. en_NZfr_FR.
time_zone
Time zone used on the device. Possible values can be found here.
created_atDate of device registration
registered_atDate of last device update
badge
Current badge count
os_nameDevice OS name
os_versionDevice OS version
app_versionApp version
sdk_versionCarnival SDK version
device_idCarnival generated Device ID
countryCountry based on user location (can be inaccurate, since sometimes the user don't enable GPS tracking and this value be defined using the user IP). Refer to Known Countries for a list of valid values.
marketing_nameDevice model. Examples: iPhone 5, iPhone 6, Samsung Galaxy S5
user_idThe ID assigned to the user.
user_emailThe email address of the user of a given device
developmentWhether or not to target development devices. Boolean.
locationLast available location of the user (being GeoIP or GPS location).
sdk_locationLast available GPS location of the user.
notifications_allowedWhether or not a device has push notifications enabled. Possible values are EnabledDisabled and Unknown.
You can see valid values for these keys by querying Audience Builder in the dashboard.

Filter by Custom Attributes

The filter name should be composed as follows: custom. + type of attribute (string, integer, float, date or boolean). + attribute_name. Examples:

Data TypePrefixExample
Stringcustom.string.custom.string.favorite_color
Datecustom.date.custom.date.last_purchased
Integercustom.integer.custom.integer.tier_points
Floatcustom.float.custom.float.lifetime_value
Booleancustom.boolean.custom.boolean.is_paid_user

Filter by custom events

The filter name should be composed as follows: events. + source + event name. Events collected by the SDK do not have a source. Examples:

SourcePrefixExample
SDK
events.
events.checkout_completed
Events collected via Devices / Events or Users / Events
events.Public Api.
events.Public Api.instore_purchase_completed
Auto Analytics: Google Analytics
events.Google Analytics.
events.Google Analytics.message_stream_user
Auto Analytics: Adobe Analytics
events.Adobe Analytics.
events.Adobe Analytics.checkout_started
Auto Analytics: Mixpanel
events.Mixpanel.
events.Mixpanel.tutorial_started
Auto Analytics: Localytics
events.Localytics.
events.Localytics.tutorial_completed
Auto Analytics: Flurry
events.Flurry Analytics.
events.Flurry Analytics.shared_post_on_twitter
Auto Analytics: Amplitude
events.Amplitude.
events.Amplitude.video_played

Specifying criteria ranges

A range is an object with at least of the following keys: gtltgte and lte. Examples of valid ranges:

  • { "gt": 0 } returns values greater than 0
  • { "gt": 0, "lt": 10 } returns values greater than zero and less than 10 (non-inclusive)
  • { "gte": 0 } returns values greater than or equal to 0
  • { "gt": "now-1d" } return devices where this event have hapenned after yesterday
Range keyDescription
gt
Greater than value
lt
Less than value
gte
Greater than or equal to value
lte
Less than or equal to value
Using Math Date for event last happened at

You can filter devices by the last time that an event happened. You do it using the same criteria range method but with a special math date syntax. Example of valid math date ranges:

  • { "gt": "now-1d" } return devices where this event happened after yesterday
  • { "gt": "now-2M" } return devices where this event happened after 2 months ago
  • { "gt": "now-2w" } return devices where this event happened after 2 weeks ago
  • { "lt": "now-1y" } return devices where this event happened before 1 year ago
  • { "gt": "now-1y", "lt": "now-1d" } return devices where this event happened between 1 year ago and yesterday
The supported units are:
LetterUnit
y
years
M
months
w
weeks
d
days
h or H
hours
m
minutes
s
seconds
More examples of supported Math Date expressions:
  • now+1h: The current time plus one hour, with ms resolution.
  • now+1h+1m: The current time plus one hour plus one minute, with ms resolution.
  • now+1h/d: The current time plus one hour, rounded down to the nearest day.
  • 2015-01-01||+1M/d: 2015-01-01 plus one month, rounded down to the nearest day.

Filtering by distance

location and sdk_location are the only fields that can be filtered by distance. The filter criteria must have the following keys:

KeyDescriptionExample
point
A latitude and longitude object
{ "latitude" : -41.28664, "longitude" : 174.77557 }
distance
A number
10.5
unit
The unit of distance used. It can be one of the following: in, inch, yd, yards, ft, feet, km, kilometers, nauticalmiles, mi, miles m, meters
"kilometers"

Example:

Copy

  "name": "sdk_location", 
  "criteria": [{ "point" : { "latitude" : -41.1339, "longitude": 174.8406 }, 
                    "distance" : 4, "unit" : "kilometers" }] }

Filter by a Polygon

location and sdk_location are the only fields that can be filtered by a polygon. The filter criteria must have the key polygon with at least 3 points with latitude and longitude. Example:

Copy

  "name": "location",
  "criteria": [
    { "point" : { "latitude" : -41.1339, "longitude": 174.8406 }, 
                      "distance" : 4, "unit" : "kilometers" },
    { "polygon" :
      [{ "latitude" :-41.31243, "longitude" : 174.75154 }, 
       { "latitude" :-41.30341, "longitude" : 174.96063 }, 
       { "latitude" :-41.19293, "longitude" : 174.91806 }, 
       { "latitude" :-41.20029, "longitude" : 174.76511 }]  }
  ] 
}

Polygon and distance filters can be mixed in a single criteria. For example:

Copy

  "name": "location",
  "criteria": [
    { "point" : { "latitude" : -41.1339, "longitude": 174.8406 }, 
                      "distance" : 4, "unit" : "kilometers" },
    { "polygon" :
      [{ "latitude" :-41.31243, "longitude" : 174.75154 }, 
       { "latitude" :-41.30341, "longitude" : 174.96063 }, 
       { "latitude" :-41.19293, "longitude" : 174.91806 }, 
       { "latitude" :-41.20029, "longitude" : 174.76511 }]  }
  ] 
}

On-the-Fly Audiences

On-the-fly audiences are persisted in your list of Audiences. When you send a notification, we return an audience ID in the response. You can use the Audience ID in the to.id to retrieve your Audience ] for example when you want to check the targeted device count, or to get a list of devices in this audience. You will be given one Audience ID for each on-the-fly audience. If you use the same on-the-fly spec more than once you will be given the same Audience ID. This example shows you how to create an on-the-fly audience, retrieve its ID and device count, and reuse it to send a push notification at a later stage.

Copy
// First, create an on-the-fly audience when sending a push notification
curl -X POST -u :WRITE_API_KEY -H "Content-type: application/json" -H 'Accept: application/json' https://api.carnivalmobile.com/v6/notifications -d '{
  "notification": {
    "to": [{ "name": "events.video_plays", "criteria": [{ "gt": 10 }]}, { "name": "custom.string.mykey", "criteria": ["tag2"]}],
    "payload": { /* Your push payload goes here */ }
  }
}'// The response will be similar to this:
{
  "created_at": "2017-03-09T13:23:37.488Z",
  "state": "scheduled",
  "id": "58c157595c50nz000e347f79",
  "to": {
    "id": "589b54e38b1ny0000876e528",
    "type": "Audience"  },
  "notification": { /* Notification payload */ }
}

// Next, use the `to.id` value to check the targeted device count.
// Make sure your API Key has Read permissions.
curl -X GET -u :READ_API_KEY https://api.carnivalmobile.com/v6/audiences/589b54e38b1ny0000876e528

// Response
{
    "audience": {
        "name": "api_audience_571a2cb135c4f3008028728_f9b10204a59727a528a4d33d262591f33de7f9fad977e4e1fb70aa4d533b162",
        "created_at": "2017-03-21T19:39:25.324Z",
        "updated_at": "2017-03-21T19:39:25.324Z",
        "id": "589b54e38b1ny0000876e528",
        "device_count": 42
    }
}

// You can reuse this on-the-fly audience for another push by specifying its ID
curl -X POST -u :WRITE_API_KEY -H "Content-type: application/json" -H 'Accept: application/json' https://api.carnivalmobile.com/v6/notifications -d '{
  "notification": {
    "to": { "audience": "589b54e38b1ny0000876e528" },
    "payload": { /* Your push payload goes here */ }
  }
}'