Urban Airship API v3

Base URL for requests

https://verizonventures-prod.apigee.net/urbanairship

Push

Send Push

POST /api/push/

Send a push notification to a specified device or list of devices. The body of the request must be one of:

Example Request:

POST /api/push HTTP/1.1
Authorization: Basic <master authorization string>
Content-Type: application/json
Accept: application/vnd.urbanairship+json; version=3;
{
  "audience" : {
      "ios_channel" : "9c36e8c7-5a73-47c0-9716-99fd3d4197d5"
  },
  "notification" : {
       "alert" : "Hello!"
  },
  "device_types" : "all"
}

Example Response:

HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
Data-Attribute: push_ids
{
    "ok" : true,
    "operation_id" : "df6a6b50-9843-0304-d5a5-743f246a4946",
    "push_ids": [
        "9d78a53b-b16a-c58f-b78d-181d5e242078",
    ]
}


JSON Parameters:
Status Codes:
  • 202 Accepted – The push notification has been accepted for processing
  • 400 Bad Request – The request body was invalid, either due to malformed JSON or a data validation error. See the response body for more detail.
  • 401 Unauthorized – The authorization credentials are incorrect
  • 406 Not Acceptable – The request could not be satisfied because the requested API version is not available.

Validate

POST /api/push/validate

Accept the same range of payloads as /api/push, but parse and validate only, without sending any pushes.



Status Codes:
  • 200 OK – The payload was valid.
  • 400 Bad Request – The request body was invalid, either due to malformed JSON or a data validation error. See the response body for more detail.
  • 401 Unauthorized – The authorization credentials are incorrect
  • 406 Not Acceptable – The request could not be satisfied because the requested API version is not available.

Below are some specific validation cases which will cause pushes to be rejected with an HTTP 400 error. The response body will provide explicit detail regarding the error. Below are two examples.

Missing Payload

A push which specifies delivery to a platform, but does not supply a payload for that platform, is invalid.

Example - this push is invalid because it specifies Android as a delivery platform, but does not provide any payload for android:

 {
     "audience" : "all",
     "device_types" : [ "ios", "android" ],
     "notification" : {
         "ios" : {
             "alert" : "Boo"
         }
     }
 }

Device Identifier/Restriction Mis-Match

A push which includes a device identifier in the audience selection, but does not include the corresponding platform (or "all") in the "device_types"" specifier, is invalid.

Example - this push is invalid because it includes an iOS device token in the audience selection, but has not specified "ios" as a delivery platform:

 {
     "audience" : {
         "or" : [
             { "device_pin" : "1fd34210" },
             { "device_token" : "645A5C6C06AFB2AE095B079135168A04A5F974FBF27163F3EC6FE1F2D5AFE008" }
         ]
     },
     "device_types" : [ "blackberry" ],
     "notification" : {
         "alert" : "WAT"
     }
 }

Push Object

A push object describes everything about a push, including the audience and push payload. A push object is composed of up to five attributes:

  • "audience" - Required

  • "notification" - Required if "message" is not present, optional if it is

  • "device_types" Required. Possible values:

    "ios", "android", "amazon", "wns", "mpns", "blackberry", "all"
    
  • "options" - Optional, a place to specify non-payload-specific delivery options for the push. See Push Options.

  • "message" - Optional, a Rich Push message

{
   "audience" : {
      "OR" : [
         { "tag" : ["sports", "entertainment"]},
         { "device_token" : "871922F4F7C6DF9D51AC7ABAE9AA5FCD7188D7BFA19A2FA99E1D2EC5F2D76506" },
         { "apid" : "5673fb25-0e18-f665-6ed3-f32de4f9ddc6" }
      ]
   },
   "notification" : {
      "alert" : "Hi from Urban Airship!",
      "ios" : {
         "extra" : { "url" : "http://www.urbanairship.com"}
      }
   },
   "options" : {
      "expiry" : "2015-04-01T12:00:00"
   },
   "message" : {
      "title" : "Message title",
      "body" : "<Your message here>",
      "content_type" : "text/html"
   },
   "device_types" : [ "ios", "wns", "mpns" ]
}

Audience Selection

An audience selector forms the expression that determines the set of devices to which a notification will be sent. A valid audience selector is a JSON expression which can identify an app installation by means of one of the following four selector types:

  • Atomic selector
  • Compound selector
  • Location expression
  • Special selector
Atomic Selectors

Atomic selectors are the simplest way to identify a single device, i.e., app installation, or a group of devices. These selectors are either a unique identifier for the device such as a channel ID or metadata that maps to the device (or multiple devices) such as a tag. Atomic selectors may be one of:

tag
a tag is an arbitrary bit of metadata used to group different devices together.
alias
an alias is an alternate, non-unique name, often mapped to a user profile in a different database, that can be used to target devices associated with that profile
segment
a Segment is a subset of your audience that is predefined by combining Tags and/or devices that meet your specified location-targeting criteria
ios_channel
the unique channel identifier used to target an iOS device
device_token
the unique identifier used to target an iOS device, superseded by ios_channel
device_pin
the unique identifier used to target a Blackberry device
android_channel
the unique channel identifier used to target an Android device
apid
the unique identifier used to target an Android device, superseded by android_channel
amazon_channel
the unique channel identifier used to target an Amazon device
wns
the unique identifier used to target a Windows device
mpns
the unique identifier used to target a Windows Phone device

Examples:

Push to a tag:

{
    "audience" : {
        "tag" : "Giants Fans"
    }
}

Pushing to a single iOS device using a channel id:

{
    "audience" : {
        "ios_channel" : "9c36e8c7-5a73-47c0-9716-99fd3d4197d5"
    }
}

Pushing to a single iOS device using a device token:

{
    "audience" : {
        "device_token" : "C9E454F6105B0F442CABD48CB678E9A230C9A141F83CF4CC03665375EB78AD3A"
    }
}

Pushing to a single Android device using a channel id:

{
    "audience" : {
        "android_channel" : "b8f9b663-0a3b-cf45-587a-be880946e880"
    }
}

Pushing to a single Amazon device using a channel id:

{
    "audience" : {
        "amazon_channel" : "b8f9b663-0a3b-cf45-587a-be880946e880"
    }
}

As is to a single Windows device:

{
    "audience" : {
        "wns" : "3644dada-d807-a2da-19d0-90d902ea7636"
    }
}

Or Windows Phone:

{
    "audience" : {
        "mpns" : "7048a456-0ce9-1c33-77d0-5975d980ffa0"
    }
}

Or Blackberry:

{
    "audience" : {
        "device_pin" : "f9307dd7"
    }
}

And here’s a Segment. You must know the segment-id for the target Segment:

{
    "audience" : {
        "segment" : "<segment-id>"
    }
}

And an alias:

{
    "audience" : {
        "alias" : "room_237"
    }
}
Compound Selectors

Compound selectors combine one or more of the above atomic expressions with logical operators. There are two forms of compound expressions— an operator followed by an array of atomic expression objects, and an implicit OR form which preserves the convenient syntax for using multiple atomic selectors.

Examples:

Implicit OR Expressions
{
   "audience" : {
      "tag" : ["apples", "oranges", "bananas"]
   }
}

In the above expression, the push will be sent to any device matching any of the three tags, and is equivalent to the explicit form as follows:

{
   "audience" : {
      "OR" : [
         { "tag" : "apples" },
         { "tag" : "oranges" },
         { "tag" : "bananas" }
      ]
   }
}
Logical Expressions

An explicit logical expression is a JSON object consisting of a logical operator as the key, and an array of one or more expressions (which can be atomic, implicit OR, or other explicit logical expressions – anything except “all”).

Examples:

Select devices which have subscribed to pushes about sports or entertainment, in English:

{
   "audience": {
      "AND": [
         {"OR": [
            {"tag": "sports"},
            {"tag": "entertainment"}
         ]},
         {"tag": "language_en"}
      ]
   }
}

A simple group message could be composed to send to all members of the group Group1 except for the sender, UserA:

{
   "audience": {
      "AND": [
         { "tag": "Group1" },
         { "NOT":
            { "alias": "UserA" }
         }
      ]
   }
}
Location Expressions

When sending to a location, include a location expression in the audience object, identifying the intended polygon by means of:

  1. either an id or alias and
  2. the window of time for the targeted message

The notification will match devices that have checked in with a location within the given polygon during the given time window. The time window is required and must be specified by a Time Period Specifier.

Example: (referencing a location by id)

{
   "audience" : {
      "location" : {
         "id" : "4oFrxA7ncddPratuelEQIV",
         "date" : {
            "days" : {
               "start" : "2015-10-15",
               "end" : "2015-10-21"
            }
         }
      }
   }
}

Example: (referencing a location by alias)

{
   "audience" : {
      "location" : {
         "<alias-type>" : "some_alias_value",
         "date" : {
            "minutes" : {
               "start" : "2015-01-01 12:00",
               "end" : "2015-01-01 12:45"
            }
         }
      }
   }
}

JSON Parameters



id: Optional, a polygon ID
<alias-type>: Optional, a polygon alias, with the key indicating the type of alias. One of id or alias must be provided. See: Boundary Types and Aliases Catalog for more information.
date: Required, a Time Period Specifier
Time Period Specifier

The time period specifier is an object indicating a time period in which to match device locations.

Fields



<resolution>: Optional. An object with "start" and "end" attributes containing ISO dates, specifying an absolute window. The key is one of the time resolution specifiers.
recent: Optional. An object specifying a relative window. See table below.

One of either days or recent must be set.

Resolutions

Valid time resolutions are:

  • "minutes"
  • "hours"
  • "days"
  • "weeks"
  • "months"
  • "years"

Absolute Window

An absolute window is indicated by setting the "days" attribute on the location selector. The value of that must be an object with two required fields, "start", and "end", both of which must contain ISO formatted date values as strings.

Relative Window

A relative window is indicated by setting the "recent" attribute on the location selector. The value of that must be an object with a single integer-valued attribute set. The name of the attribute determines the unit of time and must be one of the resolution specified, and the value, which must be a positive integer, determines the period.




Resolution Valid Range Notes
"minutes" 1-120 Up to the last two hours
"hours" 1-48 Up to the last two days
"days" 1-60 Up to the past 60 days
"weeks" 1-10 Up to the past 10 weeks
"months" 1-48 Up to the past 4 years
"years" 1-20 Up to the past 10 years

Example: (absolute window)

An absolute window is indicated by setting one of the time resolution attributes on the location selector, which has two required attributes - "start", and "end", both of which must be ISO-formatted dates.

{
    "audience" : {
        "location" {
            "id" : "00xb78Jw3Zz1TyrjqRykN9",
            "date" : {
                "days" : {
                    "start" : "2015-01-01",
                    "end" : "2015-01-15"
                }
            }
        }
    }
}
{
    "audience" : {
        "location" {
            "id" : "00xb78Jw3Zz1TyrjqRykN9",
            "date" : {
                "minutes" : {
                    "start" : "2015-01-01 12:00",
                    "end" : "2015-01-01 12:45"
                }
            }
        }
    }
}
{
    "audience" : {
        "location" {
            "id" : "00xb78Jw3Zz1TyrjqRykN9",
            "date" : {
                "months" : {
                    "start" : "2012-01",
                    "end" : "2012-06"
                }
            }
        }
    }
}
Special Selectors

Certain audience selectors cannot be described as atomic and are represented by a string which then maps to a special Urban Airship internal accounting of all devices that meet the criteria for that string.

Broadcast

In previous versions of the Urban Airship API, the broadcast or “send to all” feature relied on a separate endpoint. Beginning with v3 of our API, send a broadcast message by using "all" as the audience selector.

Example:

{
   "audience" : "all",
   "device_types" : "all",
   "notification" : {
      "alert" : "This one goes out to all of the mobile people."
   }
}
Triggered Audience

Another special selector value is for use with Pipelines (Automated Messages). The string "triggered" indicates that the audience is comprised of the device(s) that activated the trigger.

See: Pipeline Objects for more detail.

Notification Payload

The notification payload is a JSON object assigned to the "notification" attribute on a Push Object, which contains the actual contents to be delivered to devices. At its simplest, the payload consists of a single string-valued attribute, "alert", which sends a push notification consisting of a single piece of text.

 {
     "audience" : "all",
     "device_types" : "all",
     "notification" : {
         "alert" : "Hello from Urban Airship."
     }
 }

The notification payload MAY include an optional "actions" object, which is described in the Actions section. If present, the actions object cannot be null or empty ({}), or an HTTP 400 will be returned.

Platform Overrides

Each supported platform has an optional platform override section, which can simply change the value of alert for that platform, or provide more detailed platform-specific payload data.

If the alert key has been provided at the top level, it will be merged with the platform-specific payload. For example, an Android payload can add the extra map without overriding an alert value provided at the top level.

Example:

The following example sends a different alert string for every supported platform:

{
   "audience" : "all",
   "device_types" : "all",
   "notification" : {
      "ios" : {
         "alert" : "Hello, iDevices"
      },
      "android" : {
         "alert" : "These are not the...yeah, lame joke."
      },
      "amazon" : {
         "alert" : "Read any good books lately?"
      },
      "blackberry" : {
         "alert" : "Greetings, Blackberry Nation!"
      },
      "mpns" : {
         "alert" : "Hello, Nokia/HTC"
      },
      "wns" : {
         "alert" : "Developers, developers, developers."
      },

   }
}
iOS

The platform override section for iOS uses the attribute ios. For more detailed discussion of iOS-specific push behavior, see iOS Push.

Note

Departing from API v1, the keys which map directly to the APNS "aps" have moved into top level of the "ios" override object. We are no longer directly mirroring Apple’s "aps" structure.

The iOS override section may have any of the following attributes:

  • "alert" - Override the alert value provided at the top level, if any. May be a JSON string or an object which conforms to Apple’s spec (see Table 3-2 in the APNS Docs).
  • "badge" - May be an integer, or an auto badge value (see Badge Values, below).
  • "sound" - a string.
  • "content-available" or "content_available" - a boolean, one of true or false
  • "extra" - a dictionary of string keys to arbitrary JSON values.
  • "expiry" - The expiry time for APNS to cease trying to deliver a push. Can be an integer encoding number of seconds from now, or an absolute timestamp in ISO UTC format. An integer value of 0 (zero) will be passed directly to Apple, and indicates that the push should be delivered immediately and not stored by APNS (“now or never” delivery). If a global expiry value has been provided in the push options object, this will override it.
  • "priority" - Optional, an integer. Sets the APNS priority of the delivery. This feature of APNS is specific to iOS 7. Valid values are 10 (immediate delivery) and 5 (conserve battery). The default value is 10.
Extras and Actions

Keys provided in the extras object may conflict with actions, if any are specified, and can result in an HTTP 400 being returned. See “iOS, Extras and Actions” for more details.

Badge Values

The "badge" key on the iOS override may be an integer, the value "auto", or an increment value. Increments are expressed by integers formatted as strings, and prefixed with either ‘+’ (U+002B) or ‘-‘ (U+002D). The numeric portion may be an integer value.

Examples:

  • "+1"
  • "+12"
  • "-3"
  • 12
  • "auto"

In a change from API v1, the "badge" key is restricted to the above values. Anything else will cause a validation failure, resulting in an HTTP 400 Bad Request response.

Alert

The "alert" key on the iOS override may be either a plain string, or a JSON object with one or more of the following fields.



body: String, the alert text
action-loc-key: String
loc-key: String
loc-args: Array of strings
launch-image: String
Android

The platform override section for Android uses the attribute "android". The android override section may have any of the following attributes:

  • "alert" - Optional, override the alert value provided at the top level, if any.
  • "collapse_key" - Optional, a string
  • "time_to_live" - Optional, an integer or timestamp specifying the expiration time for the message. 0 indicates that GCM should not store the message (i.e. “now or never” delivery).
  • "delay_while_idle" - Optional, a boolean
  • "extra" - a JSON dictionary of string values. Values for each entry may only be strings. If an API user wishes to pass structured data in an extra key, it must be properly JSON-encoded as a string.
  • "style" - Optional advanced styles
  • "title" - Optional, a string representing the title of the notification. The default value is the name of the app at the SDK.
  • "summary" - Optional, a string representing a summary of the notification.

For more detailed discussion of Android-specific push behavior, see Android Integration.

See Google’s GCM Advanced Topics documentation for explanations of collapse_key, time_to_live, and delay_while_idle.

Example:

{
    "android": {
        "alert": "Hello",
        "extra": {
            "url": "http://example.com",
            "story_id": "1234",
            "moar": "{\"key\": \"value\"}"
        },
        "collapse_key": "gobbledygook",
        "time_to_live" : 10,
        "delay_while_idle" : true
    }
}
Android L Features
  • "priority" - Optional integer in the range from -2 to 2, inclusive. Used to help determine notification sort order. 2 is the highest priority, -2 is the lowest, and 0 is the default priority.
  • "category" - Optional string from the following list: "alarm", "call", "email", "err", "event", "msg", "promo", "recommendation", "service", "social", "status", "sys", and "transport". It is used to help determine notification sort order.
  • "visibility" - Optional integer in the range from -1 to 1 inclusive. 1 is public (default), 0 is private, and -1 is secret. Secret does not show any notifications, while private shows a redacted version of the notification.
  • "public_notification" - Optional object. A notification to show on the lock screen instead of the redacted one. This is only useful with "visibility" set to 0 (private). The object may contain any of the following fields: "title", "alert", and "summary".

Example:

{
   "android" : {
      "priority" : 1,
      "category" : "promo",
      "visibility" : -1,
      "public_notification" : {
         "title" : "the title",
         "alert" : "hello, there",
         "summary" : "the subtext"
      }
   }
}
Wearables
  • "local_only" - Optional boolean (default false). Only show the notification on the wearable device.

  • "wearable" - Optional object with the following optional fields:
    • "background_image" - String field containing the URL to a background image to display on the wearable device.
    • "extra_pages" - List of objects, each with “title” and “alert” string attributes for specifying extra pages of text to appear as pages after the notification alert on the wearable device.
    • "interactive" - An object which can be used to override the interactive notification payload for the wearable device. The object must conform to the interactive object specification.

Example:

{
   "android" : {
      "local_only" : true,
      "wearable" : {
         "background_image" : "http://example.com/background.png",
         "extra_pages" : [
            {
               "title" : "Page 1 title - optional title",
               "alert" : "Page 1 title - optional alert"
            },
            {
               "title" : "Page 2 title - optional title",
               "alert" : "Page 2 title - optional alert"
            }
         ],
         "interactive" : {
            "type" : "ua_yes_no_foreground",
            "button_actions" : {
               "yes" : {
                  "add_tag" : "butter",
                  "remove_tag" : "cake",
                  "open" : {
                     "type" : "url",
                     "content" : "http://www.urbanairship.com"
                  }
               },
               "no" : {
                  "add_tag" : "nope"
               }
            }
         }
      }
   }
}
Style

A number of advanced styles are available on Android 4.3+ by adding the "style" attribute to the platform-specific notation payload on Android and Amazon. The "style" object must contain a string field "type", which will be set to either "big_text", "big_picture", or "inbox". Whatever "type" is set to must also exist as an independent string field within the "style" object:

  • "big_picture" - If "type" is set to "big_picture", then the "big_picture" string field must also be present. "big_picture" should be set to the URL for some image
  • "big_text" - If "type" is set to "big_text", then the "big_text" string field must also be present. "big_text" should be set to the text that you want to display in big text style.
  • "inbox" - If "type" is set to "inbox", then the "lines" field must also be present. The "lines" field should be an array of strings.

The "style" object may also contain "title" and "summary" override fields:

  • "title" - Optional string field which will override the notification.
  • "summary" - Optional string field which will override the summary of the notification.

Examples:

{
   "android" : {
      "style" : {
         "type" : "big_text",
         "big_text" : "This is big!",
         "title" : "Big text title",
         "summary" : "Big text summary"
      }
   }
}
{
   "android" : {
      "style" : {
         "type" : "big_picture",
         "big_picture" : "http://pic.com/photo",
         "title" : "Big picture title",
         "summary" "Big picture summary"
      }
   }
}
{
   "android" : {
      "style" : {
         "type" : "inbox",
         "lines" : ["line 1", "line 2", "line 3", "line 4"],
         "title" : "Inbox title",
         "summary" : "Inbox summary"
      }
   }
}
Amazon

The platform override section for Amazon uses the attribute "amazon". the "amazon" object may have zero or more of the following attributes:

  • "alert" - Optional, override the alert value provided at the top level, if any.
  • "consolidation_key" - Optional, a string value. Similar to GCM’s collapse_key.
  • "expires_after" - Optional, an integer value indicating the number of seconds that ADM will retain the message if the device is offline. The valid range is 60 - 2678400 (1 minute to 31 days), inclusive. Can also be an absolute ISO UTC timestamp, in which case the same validation rules apply, with the time period calculated relative to the time of the API call.
  • "extra" - JSON dictionary of string values. Values for each entry may only be strings. If you wish to pass structured data in an extra key, it must be properly JSON-encoded as a string.
  • "title" - Optional, a string representing the title of the notification. The default value is the name of the app at the SDK.
  • "summary" - Optional, a string representing a summary of the notification.
  • "style" - Optional advanced styles available for certain Android and Amazon devices. See: Style.
Blackberry

The platform override section for Blackberry uses the attribute "blackberry". The Blackberry override section may have:

  • "alert" - Shortcut for: "body": <alert value>, "content_type": "text/plain"

Or:

  • body
  • content_type or content-type
Windows 8

The platform override section for Windows 8 uses the attribute "wns". The "wns" object must have exactly one of the following attributes:

  • "alert"
  • "toast"
  • "tile"
  • "badge"

With the exception of the removal of the "type" attribute, the WNS platform override section is exactly as in API v2. See Windows 8 WNS Payload Reference

Windows Phone 8

The platform override section for Windows 8 uses the attribute "mpns". The "mpns" object must have exactly one of the following attributes:

  • "alert"
  • "toast"
  • "tile"

With the exception of the removal of the "type" attribute, the MPNS platform override section is exactly as in API v2. See MPNS Payload Reference

Push Options

The options attribute is a JSON dictionary for specifying non-payload options related to the delivery of the push, such as expiry. Currently, expiry is the only publicly available push option but we will continue to expose new options for this attribute in future releases.

Expiry

Delivery expiration, also commonly referred to as TTL. If an expiry time is included with the push, and that time is subsequently reached before the push is delivered, the Platform provider, e.g., APNS or GCM will not attempt to redeliver the message.

The value is expressed as either absolute ISO UTC timestamp, or number of seconds from now. When the delivery platform supports it, a value of zero (0) indicates that the message should be delivered immediately and never stored for later attempts.

If the value of expiry is zero and the underlying platform for a push does not support a “never store this message” option, the minimum TTL for that platform will be used.

Example:

{
   "audience" : "all",
   "device_types" : [ "ios" ],
   "notification" : {
      "ios" : {
         "badge" : "+1"
      }
   },
   "options" : {"expiry" : "2015-04-01T12:00:00"}
}

Schedules

Note

As of the release of the Urban Airship API v3, the operation of scheduling a push for a later time is no longer handled via an argument in the payload of the Push API at /api/push/scheduled/<schedule_id>.

Scheduled notifications are now managed via the schedule endpoint at /api/schedules. See API v3 Migration Guide for more information.

Warning

The API prohibits batch sizes of larger than 1000 for scheduled pushes, and batches of larger than 100 for push to local time scheduled pushes.

Schedule a Notification

POST /api/schedules/

Scheduled notifications are created by POSTing to the schedule URI. The body of the request must be one of:

Example Request:

POST /api/schedules/ HTTP/1.1
Authorization: Basic <authorization string>
Content-type: application/json
Accept: application/vnd.urbanairship+json; version=3;

{
    "name": "Booyah Sports",
    "schedule": {
        "scheduled_time": "2013-04-01T18:45:00"
    },
    "push": {
        "audience": { "tag": "spoaaaarts" },
        "notification": { "alert": "Booyah!" },
        "device_types": "all"
    }
}


JSON Parameters:
  • schedule – A schedule object defining the schedule.
  • scheduled_time – The time to send the notification, in UTC.
  • local_scheduled_time – Alternate to scheduled_time. The device local time to send the notification, in UTC.
  • name – An optional string.
  • push – A push object defining the notification payload.

Example Response:

HTTP/1.1 201 Created
Content-type: application/json;
Data-Attribute: schedule_urls
{
   "ok": true,
   "operation_id":"efb18e92-9a60-6689-45c2-82fedab36399",
   "schedule_urls":[
      "https://go.urbanairship/api/schedules/2d69320c-3c91-5241-fac4-248269eed109"
   ],
   "schedules":[
      {
         "url": "https://go.urbanairship/api/schedules/2d69320c-3c91-5241-fac4-248269eed109",
         "schedule":{
            "scheduled_time": "2013-04-01T18:45:00"
         },
         "name":"Booyah Sports",
         "push":{
            "audience":{ "tag": "spoaaaarts" },
            "notification": { "alert": "Booyah!" },
            "device_types": "all"
         },
         "push_ids":[ "83046227-9b06-4114-9f23-0df349792bbd" ]
      }
   ]
}


Status Codes:
  • 201 Created – The response body will contain an array of response objects with the created resource URIs.
  • 400 Bad Request – The request body was invalid, most likely due to malformed JSON. See the response body for more detail.
  • 401 Unauthorized – The authorization credentials are incorrect or missing.
  • 403 Forbidden – The application does not have the proper entitlement to access scheduling.
  • 404 Not Found – Returned if the scheduled push has been deleted or has already been delivered.

List Schedules

GET /api/schedules/

List all existing schedules. Returns an array of schedule objects in the "schedules" attribute.

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Count: 2
Data-Attribute: schedules
{
    "ok": true,
    "count": 2,
    "total_count": 4,
    "next_page": "https://go.urbanairship.com/api/schedules/?start=5c69320c-3e91-5241-fad3-248269eed104&limit=2&order=asc",
    "schedules": [
        {
            "url": "http://go.urbanairship/api/schedules/2d69320c-3c91-5241-fac4-248269eed109",
            "schedule": { },
            "push": { }
        },
        {
            "url": "http://go.urbanairship/api/schedules/2d69320c-3c91-5241-fac4-248269eed10A",
            "schedule": { },
            "push": { }
        }
    ]
}


Query Parameters:
  • start – string (optional) - ID of the starting element for paginating results
  • limit – integer (optional) - maximum number of elements to return
Status Codes:
  • 200 OK – Returned on success, with the JSON representation of the scheduled pushes in the body of the response.
  • 401 Unauthorized – The authorization credentials are incorrect or missing.
  • 403 Forbidden – The application does not have the proper entitlement to access scheduling.

List a Specific Schedule

GET /api/schedules/(id)

Fetch the current definition of a single schedule resource. Returns a single schedule object.

Example Request:

GET /api/schedules/5cde3564-ead8-9743-63af-821e12337812 HTTP/1.1
Authorization: Basic <authorization string>
Accept: application/vnd.urbanairship+json; version=3;
Content-type: application/json

Example Response:

HTTP/1.1 200 OK
Content-type: application/json; charset=utf-8
{
     "name": "Booyah Sports",
     "schedule": {
         "scheduled_time": "2013-04-01T18:45:30"
     },
     "push": {
         "audience": { "tag": [ "spoaaaarts", "Beyonce", "Nickelback" ] },
         "notification": { "alert": "Booyah!" },
         "device_types": "all"
     }
}


Uri id:

The ID of the schedule to retrieve.

Status Codes:
  • 200 OK – Returned on success, with the JSON representation of the scheduled push in the body of the response.
  • 401 Unauthorized – The authorization credentials are incorrect.
  • 403 Forbidden – The application does not have the proper entitlement to access scheduling.
  • 404 Not Found – Returned if the scheduled push has been deleted or has already been delivered.

Update Schedule

PUT /api/schedules/(id)

Update the state of a single schedule resource. The body must contain a single schedule object. A PUT cannot be used to create a new schedule, it can only be used to update an existing one.

Example Request:

PUT /api/schedules/5cde3564-ead8-9743-63af-821e12337812 HTTP/1.1
Authorization: Basic <authorization string>
Content-type: application/json
Accept: application/vnd.urbanairship+json; version=3;
{
     "name": "Booyah Sports",
     "schedule": {
         "scheduled_time": "2013-04-01T18:45:30"
     },
     "push": {
         "audience": { "tag": [ "spoaaaarts", "Beyonce", "Nickelback" ] },
         "notification": { "alert": "Booyah!" },
         "device_types": "all"
     }
}

Example Response:

HTTP/1.1 200 OK
Content-type: application/json; charset=utf-8
Content-Length: 123
{
     "ok": true,
     "operation_id": "7c56d013-5599-d66d-6086-6205115d85e2",
     "schedule_urls": [ "https://go.urbanairship.com/api/schedules/0af1dead-e769-4b78-879a-7c4bb52d7c9e" ],
     "schedules": [
         {
             "url": "https://go.urbanairship.com/api/schedules/0af1dead-e769-4b78-879a-7c4bb52d7c9e",
             "schedule": {
                 "scheduled_time": "2013-04-01T18:45:30"
             },
             "name": "Booyah Sports",
             "push": {
                 "audience": { "tag": [ "spoaaaarts", "Beyonce", "Nickelback" ] },
                 "notification": { "alert": "Booyah!" },
                 "device_types": "all"
             },
             "push_ids": [ "48fb8e8a-ee51-4e2a-9a47-9fab9b13d846" ]
         }
     ]
}


Uri id:

The ID of the schedule to update.

Status Codes:
  • 200 OK – Returned if the scheduled push has been succesfully updated.
  • 401 Unauthorized – The authorization credentials are incorrect or missing.
  • 403 Forbidden – The application does not have the proper entitlement to access scheduling.
  • 404 Not Found – Returned if the scheduled push does not exist, has been deleted or has already been delivered.

Delete Schedule

DELETE /api/schedules/(id)

Delete a schedule resource, which will result in no more pushes being sent. If the resource is successfully deleted, the response does not include a body.

Example Request:

DELETE /api/schedules/b384ca54-0a1d-9cb3-2dfd-ae5964630e66 HTTP/1.1
Authorization: Basic <authorization string>
Accept: application/vnd.urbanairship+json; version=3;

Example Response:

HTTP/1.1 204 No Content


Uri id:

The ID of the schedule to delete.

Status Codes:
  • 204 No Content – Returned if the scheduled push has been succesfully deleted.
  • 401 Unauthorized – The authorization credentials are incorrect or missing.
  • 403 Forbidden – The application does not have the proper entitlement to access scheduling.
  • 404 Not Found – Returned if the scheduled push has been deleted or has already been delivered.

Schedule Object

A schedule consists of a schedule, i.e., a future delivery time, an optional name, and a push object.

There are two forms of schedule, specifying a delivery time in UTC.

Scheduled push to be delivered globally at the same moment

{"scheduled_time": "2013-04-01T18:45:30"}

Scheduled push to be delivered at the device local time

{"local_scheduled_time": "2013-04-01T18:45:30"}

A full schedule object, then, will have both a schedule and a push object.

{
    "url": "http://go.urbanairship/api/schedules/2d69320c-3c91-5241-fac4-248269eed109",
    "schedule": {"scheduled_time": "2013-04-01T18:45:30"},
    "name": "My schedule",
    "push": {
        "audience": {"tag": "49ers"},
        "device_types": "all",
        "notification": {"alert": "Touchdown!"},
        "options": {"expiry": 10800}
    }
}

Note

The url key is set by the server, and so is present in responses but not in creation requests sent from the client.

Local Time Delivery

Push to Local time is an option, when scheduling a push, to have it delivered at the same time of day across all time zones in your app’s audience, around the world. If your application uses our library and has analytic events turned on, you can schedule a push to each device’s local time by specifying local_scheduled_time in the schedule object when creating the schedule. The push will then arrive for that device or set of devices at local time, instead of UTC (as is the case with other scheduled pushes). This feature is available only on iOS and Android, and requires the integration of the library in your app.

Note

In order to be able to use Local Time Delivery, you must have Analytic Events turned on and integrated into your application. See iOS Analytic Reports and Android Analytic Reports for more information.

Example Request:

POST /api/schedules HTTP/1.1
Content-Type: application/vnd.urbanairship+json; version=3
{
   "schedule" : {
      "local_scheduled_time" : "2015-04-01T12:00:00"
   },
   "push" : {
      "audience" : "all",
      "notification" : { "alert" : "OH HAI FUTURE PEOPLEZ" },
      "device_types" : "all"
   }
}

Automation

An Automated Message is unlike a notification or a message in that the creation of an Automated Message involves setting the conditions under which a notification or notifications will be delivered.

Due to the complexity of the logic and triggering events that will fulfill the delivery of the messages, we have created a new endpoint for interacting with these kinds of messages at /api/pipelines/. See below for the examples.

Pipelines (Automated Messages)

When using the API to create an Automated Message, use the /api/pipelines/ endpoint. Note that “pipelines” is the naming convention for generating Automated Messages through our API but that Automated Message is the proper product/feature name that you will see in the user dashboard.

POST /api/pipelines/

Pipelines are created by POSTing to the pipeline URI. The body of the request must be one of

Example Request:

POST /api/pipelines/ HTTP/1.1
Authorization: Basic <master authorization string>
Content-Type: application/json
Accept: application/vnd.urbanairship+json; version=3;
{
     "immediate_trigger": { "tag_added": "new_customer" },
     "enabled": true,
     "outcome": {
         "push": {
             "audience": "triggered",
             "device_types": "all",
             "notification": { "alert": "Hello new customer!" }
         }
     }
}

In the event of success, the response will contain an array of pipeline URIs, in the "pipeline_urls" attribute. If more than one entity was included in the request, the URIs will be in the same order as the objects in the request.

Example Response:

HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
Content-Length: 123
Data-Attribute: pipeline_urls
{
    "ok" : true,
    "operation_id" : "86ad9239-373d-d0a5-d5d8-04fed18f79bc",
    "pipeline_urls" : [
        "https://go.urbanairship/api/pipelines/4d3ff1fd-9ce6-5ea4-5dc9-5ccbd38597f4"
    ]
}


JSON Parameters:
  • name – A descriptive name for the pipeline.
  • enabled – a boolean value indicating whether or not the pipeline is enabled.
  • immediate_trigger – An immediate trigger object
  • outcome – An outcome object
Status Codes:
  • 201 Created – The response body will contain an array of response objects with the created resource URIs.
  • 400 Bad Request – The request body was invalid, most likely due to malformed JSON. See the response body for more detail.
  • 401 Unauthorized – The authorization credentials are incorrect or missing.
  • 403 Forbidden – The application does not have the proper entitlement to access pipelines.
  • 409 Conflict – The application has exceeded the maximum number of active or total pipelines. In order to increase pipeline maximum, contact support@urbanairship.com.
POST /api/pipelines/validate

Accept the same range of payloads as /api/pipelines, but parse and validate only, without creating a pipeline.



Status Codes:
  • 200 OK – The payload was valid.
  • 400 Bad Request – The request body was invalid, either due to malformed JSON or a data validation error. See the response body for more detail.
  • 401 Unauthorized – The authorization credentials are incorrect or missing.
  • 406 Not Acceptable – The request could not be satisfied because the requested API version is not available.
  • 409 Conflict – The application has exceeded the maximum number of active or total pipelines. In order to increase pipeline maximum, contact support@urbanairship.com.
GET /api/pipelines

List all existing pipelines. Returns an array of pipeline objects in the "pipelines" attribute.

Example Request:

curl -X GET -u "<appkey>:<mastersecret>" -H "Accept: application/vnd.urbanairship+json; version=3" -H "Content-Type: application/json" https://verizonventures-prod.apigee.net/urbanairship/api/pipelines


Query Parameters:
  • start – string (optional) - ID of the starting element for paginating results
  • enabled – boolean (optional) - Limit the listing to only pipelines which match the specified enabled flag. If enabled is omitted, all pipelines will be returned, regardless of status.
Status Codes:
  • 200 OK – Returned on success, with the JSON representation of the pipelines in the body of the response.
  • 401 Unauthorized – The authorization credentials are incorrect or missing.
  • 403 Forbidden – The application does not have the proper entitlement to access pipelines.
GET /api/pipelines/deleted

List all deleted pipelines. Returns an array of deleted pipeline objects in the "pipelines" attribute.



Query Parameters:
  • start – string (optional) - Timestamp of the starting element for paginating results
JSON Parameters:
  • pipeline – The id of the pipeline.
  • deletion_time – An ISO 8601 UTC timestamp indicating the date and time that the pipeline was deleted.
GET /api/pipelines/(id)

Fetch the current definition of a single pipeline resource. Returns an array containing a single pipeline object in the "pipelines" attribute.



Uri id:

The ID of the pipeline to update

Status Codes:
  • 200 OK – Returned on success, with the JSON representation of the pipeline in the body of the response.
  • 401 Unauthorized – The authorization credentials are incorrect or missing.
  • 403 Forbidden – The application does not have the proper entitlement to access pipelines.
  • 404 Not Found – If the pipeline does not exist (perhaps because it has already been deleted).
PUT /api/pipelines/(id)

Update the state of a single pipeline resource. Partial updates are not permitted.



Uri id:

The ID of the pipeline to update

Status Codes:
  • 200 OK – Returned if the pipeline has been succesfully updated.
  • 401 Unauthorized – The authorization credentials are incorrect or missing.
  • 403 Forbidden – The application does not have the proper entitlement to access pipelines.
  • 409 Conflict – The application has exceeded the maximum number of active or total pipelines. In order to increase pipeline maximum, contact support@urbanairship.com.
DELETE /api/pipelines/(id)

Delete a pipeline resource, which will result in no more pushes being sent. If the resource is successfully deleted, the response does not include a body.

Example Request:

DELETE /api/pipelines/0f927674-918c-31ef-51ca-e96fdd234da4 HTTP/1.1
Authorization: Basic <authorization string>
Accept: application/vnd.urbanairship+json; version=3;

Example Response:

HTTP/1.1 204 No Content


Uri id:

The ID of the pipeline to delete

Status Codes:
  • 204 No Content – Returned if the pipeline has been succesfully deleted.
  • 401 Unauthorized – The authorization credentials are incorrect or missing.
  • 403 Forbidden – The application does not have the proper entitlement to access pipelines.
  • 404 Not Found – Returned if the pipeline does not exist.

Data Formats

Pipeline Object

A pipeline object encapsulates the complete set of objects that define an Automation pipeline: Triggers, Outcomes, and metadata.

A pipeline object has the following attributes:





Key Type Qualifier Notes
Requests
name string Optional A descriptive name for the pipeline.
enabled boolean Required Determines whether or not the pipeline is active.
outcome object* Required A single outcome object or an array of outcome objects.
immediate_trigger object* Optional A single event identifier or an array of event identifiers.
historical_trigger object* Optional A single historical trigger object or an array of historical trigger objects.
constraint object* Optional A single constraint object or array of constraint objects.
condition object* Optional A single condition set or array of condition sets.




Key Type Qualifier Notes
Responses
url string Read only The canonical identify of the pipeline. This is a read-only field present on responses from the API, but will be ignored if it is present on requests.
status string Read only One of live, or disabled. An enumerated string value indicating whether the pipeline is currently capable of triggering pushes, based on evaluation of values for enabled.
creation_time timestamp Read only An ISO 8601 timestamp in UTC indicating the time that the pipeline was initially created. This is a read-only field which is present on GET responses. If it is included in a POST or PUT request it will be ignored.
last_modified_time timestamp Read only An ISO 8601 timestamp in UTC indicating the time that the pipeline was last modified. This is a read-only field which is present on GET responses. If it is included in a POST or PUT request it will be
Outcome Object

An outcome object has the following attributes:

  • "delay" - Optional, integer >= 60. The number of seconds to delay before processing the outcome. Only valid if the "push" attribute is present.
  • "push" - A single push object. The "audience" field must be set to "triggered".
Immediate Triggers

An immediate trigger object defines a condition that activates a trigger immediately when an event matching it occurs. If a pipeline has multiple immediate triggers, they’re combined via an implicit OR operation. Any one of the triggers firing will activate the pipeline.

Immediate triggers are all event identifiers.

Historical Trigger Object

A historical trigger object defines a condition that matches against event data trended over time. The trigger consists of the following components:

event identifier
"event" : "open"

matches on app open, registered upon app open via the Urban Airship iOS and Android client libraries.

matching operator
"equals" : 0,

Only a value of 0 is currently supported in this field, to initiate an inactivity trigger. Future releases will support more flexible notions of triggering based on historical events.

time period
"days" : 30

set value up to 90 days

Example: (this trigger will match if a device has not opened the app in 30 days)

{
  "event" : "open",
  "equals" : 0,
  "days" : 30
}
Event Identifiers

Event identifiers describe events that Automation can detect and act on. They may be described by a simple string (e.g. "open"), or by an object for parameterized events (e.g. { "tag_added" : "<t>" }).

A simple event identifier is a string that names an event which does not require any parameters to match.

At this time, there are two simple event identifiers:

  • "open" - Matches on app opens.
  • "first_open" - Matches on first open of an app.

Because an app open event is communicated to Urban Airship via our iOS and Android mobile client libraries, it is required that your app is utilizing the library and registering app open events.

Note

open is a valid Event Identifier only for Historical Triggers, and cannot be used to activate a pipeline via Immediate Trigger. Conversely, first_open is a valid Event Identifier only for Immediate Triggers.

A compound event identifier is a JSON dictionary with a single key indicating the event type, and a value specifying the specific parameter to match on.

Valid compound event identifiers are:

  • "tag_added" - Matches when the specified tag is added. The value of the identifier is a simple string identifying a device tag. See tags.
  • "tag_removed" - Matches when the specified tag is removed. The value of the identifier is a simple string identifying a device tag. See tags.
Constraint Object

A constraint object describes a constraint placed on when triggered pushes can be sent, such as a rate limit, or a window in which pushes can be delivered or suppressed. A constraint object is expressed as a JSON dictionary with a single key indicating the type of the constraint, and a dictionary with its values.

Valid constraint types are:

A rate limit constraint describes a limit on the number of pushes that can be sent to an individual device per a specified time period.

A rate limit object is comprised of two fields:

  • pushes - An integer, specifying the maximum number of pushes that can be sent to a device per time period.
  • days - An integer, specifying the time period in number of days.

Example: (This pipeline is limited to a maximum of 10 pushes per day, per device.)

{
    "name" : "Rate-limited pipeline",
    "enabled" : true,
    "immediate_trigger" : { "tag_added" : "pipelines_are_people_too" },
    "outcome" : { "push" : { } },
    "constraint" : [
        {
            "rate" : {
                "pushes" : 10,
                "days" : 1
            }
        }
    ]
}
Tag Conditions

Tag Conditions use the top level attribute of the pipeline object, "conditions". When present, the "conditions" attribute will evaluate for the presence or non-presence of the only valid condition type, tag(s).

Upon evaluation, combined with boolean operators in a Condition Set, when true, Tag Conditions will execute the given outcomes of the pipeline.

Condition Object

A condition object defines an individual condition which will be evaluated when considering whether to execute the outcomes of a pipeline. Condition objects are JSON dictionaries with a key indicating the type of condition, and a value containing any necessary parameters to that condition.

There is one valid condition type: "tag", and Tag Conditions have two possible attributes:



tag_name Required - the name of the tag to be matched.
negated Optional - a boolean indicating this condition should match on the absence of a tag.

Example:

The following example shows a Condition Object from a pipeline which will execute if the target device has the VIP tag, or does NOT have the dont_push tag.

{
  "condition" : [
    {
      "or" : [
        {
          "tag" : {
            "tag_name" : "VIP"
          }
        },
        {
          "tag" : {
            "tag_name" : "dont_push",
            "negated" : true
          }
        }
      ]
    }
  ]
}
Condition Set

A condition set is a collection of one or more conditions and an operator for combining them, in the case that there are multiple conditions. A condition set may contain a maximum of 20 conditions.

Taken together, the operator and set of conditions form a boolean expression which must evaluate to true for a pipeline to be activated and its outcomes executed.

Valid operators for a condition set are "and" and "or".

Warning

Nesting of operators is not supported within a condition set, i.e., you may not combine "and" logic with "or" logic.

Example:

 {
   "name" : "Very Specific Pipeline With Conditions",
   "enabled" : true,
   "immediate_trigger" : { "tag_added": "new_customer" },
   "outcome" : {
     "push" : {
       "audience" : "triggered",
       "device_types" : "all",
       "notification" : { "alert": "A fine conditional VIP hello to you!" }
     }
   },
   "condition" : [
     {
       "or" : [
         {
           "tag" : {
             "tag_name" : "VIP"
           }
         },
         {
           "tag" : {
             "tag_name" : "dont_push",
             "negated" : true
           }
         }
       ]
     }
   ]
}

Deleted Pipeline Object

A deleted pipeline object contains the id and the deletion time for each pipeline that is returned when you list deleted pipelines with GET /api/pipelines/deleted.

The object contains:

  • pipeline_id - The id of the pipeline.
  • deletion_time - An ISO 8601 UTC timestamp indicating the date and time that the pipeline was deleted.

Tags

Tag Listing

GET /api/tags/

List tags that exist for this application.

Note

Tag Listing will return up to the first 100 tags per application.

Example Request:

GET /api/tags/ HTTP/1.1
Authorization: Basic <application authorization string>

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "tags": [
      "tag1",
      "some_tag",
      "portland_or"
   ]
}

Tag Creation

PUT /api/tags/(tag)

Explicitly create a tag with no devices associated with it.

Note

This call is optional; tags are created implicitly when devices are added to them. You might use this to pre-create the list for your Push Composer users, however.

Example Request:

PUT /api/tags/new_tag HTTP/1.1
Authorization: Basic <application authorization string>


Status Codes:
  • 200 – The tag already exists.
  • 201 – The tag was created.
  • 400 – The tag is invalid.

Adding and Removing Devices from a Tag

Warning

Use Caution When Setting Tags Server-Side

iOS

In the iOS SDK, registration is handled for you automatically, which gives us any tags that are set on the device. Calling this API from a server might interfere with metadata if set differently. Specifically, if you set a tag from the API but are using the SDK, the SDK will clear the tag upon registration.

It is possible to disable tags being set by the SDK by setting deviceTagsEnabled to NO on iOS.

Android

Similarly, on Android/Amazon, metadata set from the server will be overwritten or cleared by registrations from the SDK unless you turn off device-side tag setting:

  • Prior to Android 5.0 SDK: PushManager.shared().setDeviceTagsEnabled(false);

or

  • Android SDK 5.0 or later: UAirship.shared().getPushManager().setDeviceTagsEnabled(false);
POST /api/tags/(tag)

Add or remove one or more iOS, Android or Amazon channels (or device tokens, APIDs, or PINs) to a particular tag.

Example Request:

POST /api/tags/some_tag HTTP/1.1
Authorization: Basic <master authorization string>
Content-type: application/json

{
   "ios_channels": {
      "add": [
         "9c36e8c7-5a73-47c0-9716-99fd3d4197d5",
         "9c36e8c7-5a73-47c0-9716-99fd3d4197d6"
      ]
   },
   "android_channels": {
      "remove": [
         "channel_1_to_remove"
      ]
   }
}


Status Codes:
  • 200 – The devices are being added or removed from this tag.
  • 401 – The authorization credentials are incorrect

Full capability:

Any number of Channels, device tokens, APIDs, or PINs can be added or removed.

POST /api/tags/some_tag HTTP/1.1
Authorization: Basic <master authorization string>
Content-type: application/json

{
   "ios_channels": {
      "add": [
         "9c36e8c7-5a73-47c0-9716-99fd3d4197d5",
         "9c36e8c7-5a73-47c0-9716-99fd3d4197d6"
      ]
   },
   "device_tokens": {
      "add": [
         "device_token_1_to_add",
         "device_token_2_to_add"
      ],
      "remove": [
         "device_token_to_remove"
      ]
   }
   "device_pins": {
      "add": [
         "device_pin_1_to_add",
         "device_pin_2_to_add"
      ],
      "remove": [
         "device_pin_to_remove"
      ]
   }
   "apids": {
      "add": [
         "apid_1_to_add",
         "apid_2_to_add"
      ],
      "remove": [
         "apid_to_remove"
      ]
   }
}


Status Codes:
  • 200 – The devices are being added or removed from this tag.
  • 401 – The authorization credentials are incorrect

Deleting a Tag

A tag can be removed from our system by issuing a delete. This will remove the master record of the tag. Additionally it will remove the tag from all devices with the exception of devices that are inactive due to uninstall. Devices that were uninstalled will retain their tags.

Note

The removal process can take a long time if many devices use this tag.

DELETE /api/tags/(tag)

Delete a tag and remove it from devices.

Example Request:

DELETE /api/tags/some_tag HTTP/1.1
Authorization: Basic <master authorization string>


Status Codes:
  • 204 – The tag has been removed.
  • 401 – The authorization credentials are incorrect
  • 404 – The tag was not found or has already been removed.

Batch modification of tags

POST /api/tags/batch/

Modify the tags for a number of device tokens, channels, or apids.

You must include an object containing either an ios_channel, android_channel, amazon_channel, device_pins, device_token or apid section and also containing a tags section to apply the tags.

Each row of data will be validated to confirm that the device token, channel or APID is valid, and that a list of tags is present. For any row that does not match these validation requirements, an error response will be returned. The error response is an object, the errors member of which is an array of two-member arrays. The two-member arrays will contain the row that did not pass validation and the error response produced by our system. Note: the error messages are not normalized or machine-readable; they are currently just short strings meant to give the API caller enough information to debug the issue with the failed row. Note: we do not validate the existence of the APID, if one or more of the APIDs do not exist in our system the application of tags to those APIDs will silently fail.

Example Request:

POST /api/tags/batch/ HTTP/1.1
Authorization: Basic <master authorization string>

[
   {
      "ios_channel": "9c36e8c7-5a73-47c0-9716-99fd3d4197d5",
      "tags": [
         "tag_to_apply_1",
         "tag_to_apply_2"
      ]
   },
   {
      "device_token": "device_token_to_tag_1",
      "tags": [
         "tag_to_apply_1",
         "tag_to_apply_2",
         "tag_to_apply_3"
      ]
    },
   {
      "device_token": "device_token_to_tag_2",
      "tags": [
         "tag_to_apply_1",
         "tag_to_apply_4",
         "tag_to_apply_5"
      ]
   },
   {
      "apid": "apid_to_tag_2",
      "tags": [
         "tag_to_apply_1",
         "tag_to_apply_4",
         "tag_to_apply_5"
      ]
   }
]


Status Codes:
  • 200 – The tags are being applied.
  • 400 – The batch tag request was invalid.
  • 401 – The authorization credentials are incorrect

Actions

Actions are specified by the "actions" attribute on a notification object. See Push Object for more detail about the notification object.

{
   "audience" : "all",
   "notification" : {
        "alert" : "You got your emails!",
        "actions" : {
            "add_tag" : "MY_TAG"
        }
    },
    "device_types" : "all"
}

Note

For information on how actions are handled within the client code within your app, see: iOS Actions and Android Actions.

The "actions" attribute MUST be an object as described in this section. The actions object can have the following five attributes:

Any combination of these attributes may be present. If any other attribute is present, an HTTP 400 response will be returned. Also, if no attributes are present, a 400 will be returned.

Example:

This actions object contains each of the possible action attributes.

{
   "actions" : {
       "add_tag" : "airship",
       "remove_tag" : "boat",
       "share" : "Check out Urban Airship!",
       "open" : {
           "type" : "url",
           "content" : "http://www.urbanairship.com"
       },
       "app_defined" : { "some_app_defined_action" : "some_value" }
   }
}

Add Tag

The "add_tag" attribute can be a single string or an array of strings. A null value, empty array, or any null values in the array will result in an HTTP 400 response. Duplicate tags in an array will not cause an error, but will have the same effect as if just a single instance of that tag was included.

Note

A single-element array will be passed to the client device (we do not turn it into a plain string).

Example:

Here we add a single tag:

{
    "actions" : {
        "add_tag" : "a_tag"
    }
}

Here we add several tags:

{
    "actions" : {
        "add_tag" : ["a_tag", "b_tag"]
    }
}

Remove Tag

The "remove_tag" attribute can be a single string or an array of strings. A null value, empty array, or any null values in the array will result in an HTTP 400 response. Duplicate tags in an array will not cause an error, but will have the same effect as if just a single instance of that tag was included.

Note

A single-element array will be passed on to the client device (we do not turn it into a plain string).

Example:

Here we remove a tag:

{
    "actions" : {
        "remove_tag" : "a_tag"
    }
}

Here we remove several tags:

{
    "actions" : {
        "remove_tag" : ["a_tag", "b_tag"]
    }
}

Open

The "open" attribute MUST be an object with two attributes: type and content.

  • "type" – A string. MUST be one of: url, deep_link or landing_page:
    • "url""content" is a string, which MUST be a URL. null is not accepted. The URL MUST start with either “http” or “https”.
    • "deep_link""content" MUST be non-blank string. null is not accepted.
    • "landing_page"content must be a content object (see example).

If the open object fails any of these conditions, an HTTP 400 will be returned.

Examples:

Examples for each type of "open":

{
    "actions" : {
        "open" : {
            "type" : "url",
            "content" : "http://www.urbanairship.com"
        }
    }
}

In the following example, note that the value for the "content" attribute, "prefs", is a string representing a common deep-linking use case: sending the user to the app’s preferences page. This is not an out-of-the-box deep link; rather, it must be defined in your project.

See iOS Deep Link Actions and Android/Amazon Deep Link Actions for information about defining these resources in your app.

{
    "actions" : {
        "open" : {
            "type" : "deep_link",
            "content" : "prefs"
        }
    }
}
{
    "actions" : {
        "open" : {
            "type" : "landing_page",
            "content" : {
                "body" : "<html>content</html>",
                "content_type" : "text/html",
                "content_encoding" : "utf-8"
            }
        }
    }
}

Share

The "share" attribute must be a string if present. Anything else will return an HTTP 400 response.

In the following example, the text “Check out Urban Airship!” will populate the share feature for the user.

Example:

{
    "actions" : {
        "share" : "Check out Urban Airship!"
    }
}

Action Mappings

Most of the top-level actions described above also map to a short name and a long name on the mobile device. You can use these alternatives in your API requests if you include them under the app_defined object. If either the short name or the long name appears in the app_defined object, but the corresponding top-level key also appears, then an HTTP 400 error will be returned. However, no error occurs if the corresponding top-level key does not appear.




Action Short Name Long Name
add_tag ^+t add_tags_action
remove_tag ^-t remove_tags_action
open: { "type" : "url", ... } ^u open_external_url_action
open: { "type" : "deep_link", ... } ^d deep_link_action
open: { "type" : "landing_page", ... } ^p landing_page_action

Examples:

This is the short name equivalent of the top-level action add_tag:

{
    "actions" : {
        "app_defined" : {
            "^+t" : "foo"
        }
    }
}

And here is the long name equivalent of the top-level "open" action for a "url":

{
    "actions" : {
        "app_defined" : {
            "open_external_url_action" : "http://www.urbanairship.com"
        }
    }
}

This next example will result in an HTTP 400 because the app_defined action ^+t corresponds to the top-level action add_tag:

{
    "actions" : {
        "add_tag" : "foo",
        "app_defined" : {
            "^+t" : "bar"
        }
    }
}

This action will result in an HTTP 400 because the app_defined action ^p corresponds to the top-level open action for a landing page:

{
    "actions" : {
        "open" : {
            "type" : "landing_page",
            "content" : {
                "body" : "foo",
                "content_type" : "text/html"
            }
        },
        "app_defined" : {
            "^p" : "bar"
        }
    }
}

This action results in an error because the app_defined action add_tags_action maps to the top-level add_tag action:

{
    "actions" : {
        "add_tag" : "foo",
        "app_defined" : {
            "add_tags_action" : "bar"
        }
    }
}

This action will result in an HTTP 400 because the same key ("open") appears in both the app_defined and top-level action objects:

{
    "actions" : {
        "open" : {
            "type" : "landing_page",
            "content" : {
                "body" : "foo",
                "content_type" : "text/html"
            }
        },
        "app_defined" : {
            "open" : {
                "type" : "deep_link",
                "content" : "bar"
            }
        }
     }
 }

Note

The preceding shows that even if a top-level open action seems to represent a different meaning than an app_defined open action, we still give an HTTP 400 due to duplicate key appearing on both objects.

This action will NOT result in an error. The top-level action opens a landing page ("open" : { "type" : "landing_page" }), but the app_defined action ^d corresponds to a deep-link open, not a landing page open:

{
    "actions" : {
        "open" : {
            "type" : "landing_page",
            "content" : {
                "body" : "foo",
                "content_type" : "text/html"
            }
        },
        "app_defined" : {
            "^d" : "bar"
        }
    }
}

Note

Even though you don’t receive an error, since both of these are "open" actions, which one will actually be opened is unknown. One of them will most likely be dropped on the mobile device (unless the app developer has overridden action handling in some way to deal with this).

This action will NOT result in an error, but is also problematic. The app_defined keys ^d and deep_link_action map to the same action on the device, but we do not translate any keys in the app_defined object, so no error occurs:

{
    "actions" : {
        "app_defined" : {
            "^d" : "bar",
            "deep_link_action" : "baz"
        }
    }
}

Note

Only one of these will actually be included in the delivery to the mobile device and result in an action.

iOS, Extras and Actions

On iOS, the extra object can conflict with top-level action names. If an extra key is the same as one of the long or short names specified in the Action Mappings section, and the corresponding top-level action is present, then an HTTP 400 will be returned.

Additionally, if an extras key is the same as a key on the app_defined object, an HTTP 400 will be returned.

Example:

This action will result in an HTTP 400 because the same key ("open") appears in the app_defined and extra objects:

{
    "notification" : {
        "alert" : "Boo",
        "ios" : {
            "extra" : {
                "open" : "hello"
            }
        },
        "actions" : {
            "app_defined" : {
                "open" : "goodbye"
            }
        }
    }
}

This action will give an HTTP 400 because the extra object carries a key that conflicts with the long name ("add_tags_action") for the add_tags action.

{
    "notification" : {
        "alert" : "Boo",
        "ios" : {
            "extra" : {
                "add_tags_action" : "hello"
            }
        },
        "actions" : {
            "add_tags" : "hello"
        }
    }
}

The following example would also give an HTTP 400 because the "^+t" key on the extra object conflicts with short name for the add_tags action:

{
    "notification" : {
        "alert" : "Boo",
        "ios" : {
            "extra" : {
                "^+t" : "hello"
            }
        },
        "actions" : {
            "add_tags" : "hello"
        }
    }
}

This action will NOT give an error, even though the extra object has a key ("add_tags_action") matching the long name for add_tags, because "add_tags" is not included as a top-level action:

{
    "notification" : {
        "alert" : "Boo",
        "ios" : {
            "extra" : {
                "add_tags_action" : "hello"
            }
        },
        "actions" : {
            "remove_tags" : "hello"
        }
    }
}

This action will NOT give an error, even though the extra object has a ^+t key, because the “add_tags_action” key is included in the app_defined section, and therefore won’t be translated to a short name:

{
    "notification" : {
        "alert" : "Boo",
        "ios" : {
            "extra" : {
                "^+t" : "hello"
            }
        },
        "actions" : {
            "app_defined" : {
                "add_tags_action" : "hello"
            }
        }
    }
}

Note

In the above case, the client device will most likely drop one of the actions, and the results will be indeterminate.

Actions payload for GCM and iOS

Actions specify a payload that will be sent to the mobile device. Predefined actions use the mapping as specified in the action mappings section. This section details the specific payload sent to iOS and Android devices.

On iOS, action names map to keys at the top level of the payload, and arguments are any valid JSON fragment (as long as the targeted action supports those arguments).

On Android we can only send extras in the form of string-to-string key/value pairs. Therefore, we will send the “com.urbanairship.actions” key, whose value will be serialized JSON object mapping action names to argument values.

Example:

Here is a push payload that adds a tag and alerts the user:

{
   "audience" : "all",
   "notification" : {
        "alert" : "You got your emails!",
        "actions" : {
            "add_tag" : "MY_TAG"
        }
    },
    "device_types" : [
        "ios",
        "android"
    ]
}

The APNS payload sent to an iOS device will look like:

{
    "aps" : {
        "alert" : "You got your emails."
    },
    "^+t" : "MY_TAG",
}

And the GCM payload sent to an Android device will look like (notice that the value of the actions key is a serialized JSON object):

Example:

{
    "registration_ids": [ "..."],
    "data": {
        "alert": "You got your emails!",
        "com.urbanairship.actions": "{\"^+t\" : \"MY_TAG\"}"
    }
}

Interactive Notifications

Interactive Notifications are specified by the "interactive" attribute in a notification object. The "interactive" attribute must be an object as described in this section. The interactive object may contain the following two attributes:

The type attribute is mandatory and the button_actions attribute is optional. If any other attribute is present, an HTTP 400 response will be returned. Attempting to specify an interactive payload on an unsupported device will result in an HTTP 400 response.

Example:

This interactive object contains a pre-defined "type" with actions defined for each button.

{
   "interactive" : {
      "type" : "ua_yes_no_foreground",
      "button_actions" : {
         "yes" : {
            "add_tag" : "more_cake_please",
            "remove_tag" : "lollipop",
            "open" : {
               "type" : "url",
               "content" : "http://www.urbanairship.com"
            }
         },
         "no" : {
            "add_tag" : "nope"
         }
      }
   }
}

Example:

This interactive object contains the pre-defined "ua_share" type with the share button action and text defined.

{
   "interactive" : {
      "type" : "ua_share",
      "button_actions" : {
         "share" : { "share" : "Look at me! I'm on a boat." }
      }
   }
}

Type

The type field of the interactive object must be a string and specify either the name of one of the predefined interactive notifications or a custom defined interactive notification. Note that all predefined interactive notification types begin with the prefix "ua_", and custom defined interactive notification types must not begin with "ua_".

Button Actions

The button_actions field of the interactive object must be an object if present. The keys are the button IDs for the specified interactive notification type. If the notification type begins with "ua_", the keys must match exactly the button IDs for that type or a strict subset. The names of the button IDs cannot be validated for custom notifications. The values must be valid Actions objects as described in the Actions API documentation.

Feeds

The Feed API is used to add and remove RSS or Atom feeds used to trigger push notifications. For most users the API is unnecessary, and you should use the dashboard instead. For more information about feeds, see integrating feeds.

Warning

The Feed API still uses the version 1 Push API. In the future it will be upgraded to use the V3 push API.

Creating a new feed

POST /api/feeds/

We only require two things be present in the data: the feed URL you wish to follow and your feed template.

We recommend checking the template with our feeds interface to see exactly how it performs.

Example Request:

POST /api/feeds/ HTTP/1.1
Authorization: Basic <master authorization string>
Content-type: application/json

{
   "feed_url": "http://example.com/atom.xml",
   "template": {
      "aps": {
         "badge": 1,
         "sound": "cat.caf",
         "alert": "New item from some place! {{ title }}"
      }
   },
   "broadcast": true
}


JSON Parameters:
  • feed_url – The full URL to the RSS or Atom feed.
  • template – A template for the Urban Airship v1 Push API.
  • broadcast – Whether this feed is a broadcast or has a specified audience.

Example Response:

HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
Location: https://go.urbanairship.com/api/feeds/<feed_id>/

{
   "url": "https://go.urbanairship.com/api/feeds/<feed_id>/",
   "id": "<feed_id>",
   "last_checked": null,
   "feed_url": "http://example.com/atom.xml",
   "template": {
      "aps": {
         "badge": 1,
         "sound": "cat.caf",
         "alert": "New item from some place! {{ title }}"
      }
   },
   "broadcast": true
}


JSON Parameters:
  • url – The location of the feed entry. Can be used for altering or removing the feed later.
  • last_checked – The last time we saw a new entry for this feed, in UTC.
Status Codes:
  • 201 – The feed is now being monitored.
  • 400 – The request is invalid; see the response body for details.
  • 401 – The authorization credentials are incorrect.

Feed details

GET /api/feeds/(feed_id)/

Returns information about that particular feed.

Example Request:

GET /api/feeds/<feed_id> HTTP/1.1
Authorization: Basic <master authorization string>

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "url": "https://go.urbanairship.com/api/feeds/<feed_id>/",
   "template": {
      "aps": {
         "badge": 1,
         "alert": "New update from Someplace! - {{ title }}"
      }
   },
   "id": "<feed_id>",
   "last_checked": "2010-03-08 21:52:21",
   "feed_url": "<your_feed_url>",
   "broadcast": true
}


JSON Parameters:
  • url – The location of the feed entry. Can be used for altering or removing the feed later.
  • last_checked – The last time we saw a new entry for this feed, in UTC.

Updating a feed

PUT /api/feeds/(feed_id)/

Updates a feed with a new template

Example Request:

PUT /api/feeds/<feed_id> HTTP/1.1
Authorization: Basic <master authorization string>
Content-type: application/json

{
   "template": {
      "aps": {
         "sound": "frog.caf",
         "alert": "New update from Someplace! - {{ title }}"
      }
   },
   "feed_url": "<new_feed_url>",

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "url": "https://go.urbanairship.com/api/feeds/<feed_id>/",
   "template": {
      "aps": {
         "sound": "frog.caf",
         "alert": "New update from Someplace! - {{ title }}"
      }
   },
   "id": "<feed_id>",
   "last_checked": "2010-03-08 21:52:21",
   "feed_url": "<new_feed_url>",
   "broadcast": true
}


JSON Parameters:
  • url – The location of the feed entry. Can be used for altering or removing the feed later.
  • last_checked – The last time we saw a new entry for this feed, in UTC.
Status Codes:
  • 200 – The feed update was successful.
  • 400 – The request is invalid; see the response body for details.
  • 401 – The authorization credentials are incorrect.

Deleting a feed

DELETE /api/feeds/(feed_id)/

Removes a feed from the monitoring service, and stops new pushes from being sent.

Example Request:

DELETE /api/feeds/<feed_id> HTTP/1.1
Authorization: Basic <master authorization string>

Example Response:

HTTP/1.1 204 No Content


Status Codes:
  • 204 – The feed was deleted, and no content was returned.

Rich App Pages

Note

As of the release of the Urban Airship Push API v3, the operation of sending a rich message to an inbox within the application is no longer handled via the Rich Push endpoints at /api/airmail/.

Rich content which is optionally associated with a push notification is now included in the message component of the Push API at /api/push/

Sending a Rich Message

POST /api/push/
 
{
    "audience" : { "tag" : [ "tag1", "tag2" ] },
    "notification" : { "alert" : "New message!" },
    "message" : {
        "title" : "Message title",
        "body" : "<Your message here>",
        "content_type" : "text/html"
    }
}

Note

Rich messages automatically result in a badge update, even if the notification attribute is not included in the payload. This is default behavior. Customers who would like to turn off this behavior should contact Support or their technical account manager.

Warning

Because rich push broadcasts cannot be segmented by platform, the "device_types" parameter that may be present during a standard push broadcast has no effect here. For example, if the above request included a "device_types" : [ "ios" ] line, the message would still be sent to all devices with the required tags, including Android and Amazon devices.

Rich Message Object

The object may have the following attributes:

  • title — Required, string
  • body — Required, string
  • content_type or content-type — Optional, a string denoting the MIME type of the data in body. Defaults to "text/html".
  • content_encoding or content-encoding — Optional, a string denoting encoding type of the data in body. For example, utf-8 or base64. Defaults to utf-8 if not supplied. base64 encoding can be used in cases which would be complex to escape properly, just as HTMl containing embedded javascript code, which itself may contain embedded JSON data.
  • expiry - The expiry time for a rich app page to delete a message from the user’s inbox. Can be an integer encoding number of seconds from now, or an absolute timestamp in ISO UTC format. An integer value of 0 is equivalent to no expiry set.
  • extra — a JSON dictionary of string values. Values for each entry may only be strings. If an API user wishes to pass structured data in an extra key, it must be properly JSON-encoded as a string.
  • icons — an optional JSON dictionary of string key and value pairs. At this time, only one key, “list_icon”, is supported. Values must be URI/URLs to the icon resources. For resources hosted by UA, use the following URI format “ua:<resource-id>”. For example: "icons" : { "list_icon" : "ua:9bf2f510-050e-11e3-9446-14dae95134d2" }
  • options — an optional JSON dictionary of key and value pairs specifying non-payload options (coming soon).

Note

Use of expiry carries the following SDK requirements:

  • iOS 3.0.4 or greater
  • Android 3.2.3 or greater
  • Amazon 4.0.0 or greater

Example:

{
    "audience" : "all",
    "notification" : {
        "ios" : {
            "badge" : "+1"
        }
    },
    "message": {
        "title": "This week's offer",
        "body": "<html><body><h1>blah blah</h1> etc...</html>",
        "content_type": "text/html",
        "expiry": "2015-04-01T12:00:00",
        "extra": {
            "offer_id" : "608f1f6c-8860-c617-a803-b187b491568e"
        },
        "icons": {
            "list_icon" : "http://cdn.example.com/message.png"
        },
        "options": {
            "some_delivery_option" : true
        }
    }
}

Rich Message ID

Rich message IDs generated by the API are in the form of web-safe base64-encoded UUIDs, which are 22 characters in length. For example, "hpkAHEIAAAl6wn2h6yUR4g".

When a rich message is accompanied by a push notification, the ID of the rich message will be added to the notification payload that is sent to the device for any platform that supports extra (currently iOS, Android) as the value of the key "_uamid". This will be a root level key in the iOS payload, and a member of the "extra" map for Android and ADM.

For iOS, this reduces the number of bytes available for the APNS alert payload from 2000 to 1966 (by adding ,"_uamid":"hpkAHEIAAAl6wn2h6yUR4g" to the APNS payload).

Reports

Warning

The Statistics API at /api/push/stats/ is available to all customers.

The Urban Airship Reports APIs, however, are only available for use by Enterprise Edition customers. For more information, please visit the Pricing Plans section of our website.

Individual Push Response Statistics

GET /api/reports/responses/(push_id)

Returns detailed reports information about a specific push notification. Use the push_id, which is the identifier returned by the API that represents a specific push message delivery.

Example Response:

{
   "push_uuid": "f133a7c8-d750-11e1-a6cf-e06995b6c872",
   "direct_responses": "45",
   "sends": 123,
   "push_type": "UNICAST_PUSH",
   "push_time": "2012-07-31 12:34:56"
}


JSON Parameters:
  • push_type – Describes the push operation, which is often comparable to the audience selection, e.g., BROADCAST_PUSH

Devices Report API

GET /api/reports/devices/?date=(Date)

Returns an app’s opted-in and installed device counts broken out by device type. This endpoint returns the same data that populates the Devices Report.

Example Response:

{
    "total_unique_devices": 150,
    "date_computed": "2014-10-01T08:31:54.000Z",
    "date_closed": "2014-10-01T00:00:00.000Z",
    "counts": {
                "android": {
                    "unique_devices": 50,
                    "opted_in": 0,
                    "opted_out": 0,
                    "uninstalled": 10
                },
                "ios": {
                    "unique_devices": 50,
                    "opted_in": 0,
                    "opted_out": 0,
                    "uninstalled": 10
                },
        }
}


JSON Parameters:
  • total_unique_devices – Sum of the unique devices for every device type
  • date_computed – The date and time the device event data was tallied and stored
  • date_closed – All device events counted occured before this date and time
  • unique_devices – Devices considered by Urban Airship Reports to have the app installed
  • opted_in – Opted in to receiving push notifications
  • opted_out – Opted out of receiving push notifications
  • uninstalled – Devices for which Reports has seen an uninstall event

Push Report

GET /api/reports/sends/?start=(date)&end=(date)&precision=(precision)

Get the number of pushes you have sent within a specified time period.

Example curl request:

# Get data from 2012-05-05 10:00 until 2012-05-15 20:00 by hour
curl -u <app key>:<master secret> "https://verizonventures-prod.apigee.net/urbanairship/api/reports/sends/?start=2012-05-05%2010:00&end=2012-05-15%2020:00&precision=HOURLY"

Example HTTP request:

GET /api/reports/sends/?start=2012-05-05%2010:00&end=2012-05-15%2020:00&precision=HOURLY HTTP/1.1
Authorization: Basic <master authorization string>


Query Parameters:
  • start – Timestamp for start of report
  • end – Timestamp for end of report
  • precision – Granularity of results to return. Possible values: HOURLY, DAILY, MONTHLY

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "sends": [
      {
         "android": 50
         "date": "2012-12-01 00:00:00",
         "ios": 500
      }
   ]
   "next_page": "https://go.urbanairship.com/api/reports/..."
}


JSON Parameters:
  • next_page – There might be more than one page of results for this report. Follow this URL if it is present to the next batch of results.

Response Report

GET /api/reports/responses/?start=(date)&end=(date)&precision=(precision)

Get the number of direct and influenced opens of your app.

Example Request:

Get data from 2012-05-05 10:00 until 2012-05-15 20:00 by hour. First example uses CURL, second uses HTTP directly.

curl -u <app key>:<master secret> "https://verizonventures-prod.apigee.net/urbanairship/api/reports/responses/?start=2012-05-05%2010:00&end=2012-05-15%2020:00&precision=HOURLY"
GET /api/reports/responses/?start=2012-05-05%2010:00&end=2012-05-15%2020:00&precision=HOURLY HTTP/1.1
Authorization: Basic <master authorization string>


Query Parameters:
  • start – Timestamp for start of report
  • end – Timestamp for end of report
  • precision – Granularity of results to return. Possible values: HOURLY, DAILY, MONTHLY

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "next_page": "https://go.urbanairship.com/api/reports/..."
   "responses": [
      {
         "android": {
            "direct": 0,
            "influenced": 0
         },
         "date": "2012-12-11 10:00:00",
         "ios": {
            "direct": 0,
            "influenced": 0
         }
      }
   ]
}


JSON Parameters:
  • next_page – There might be more than one page of results for this report. Follow this URL if it is present to the next batch of results.

Response Listing

GET /api/reports/responses/list

Get a listing of all pushes, plus basic response information, in a given timeframe. Start and end date times are required parameters.

Example Request:

GET /api/reports/responses/list?start=2013-07-01T00:00:00.000Z&end=2013-08-01T00:00:00.000Z&limit=25 HTTP/1.1
Authorization: Basic <master authorization string>


Query Parameters:
  • start – Timestamp for start of report
  • end – Timestamp for end of report
  • limit – Number of results to return at one time (for pagination)
  • push_id_start – Begin with this id

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Data-Attribute: push_ids
{
   "next_page": "/api/reports/..../?start=2013-07-01T00:00:00.000Z&end=2013-08-01T00:00:00.000Z&push_id_start=04911800-f48d-11e2-acc5-90e2ba027020&limit=25",
   "pushes": [
         {
         "push_uuid": "f133a7c8-d750-11e1-a6cf-e06995b6c872",
         "push_time": "2012-07-31 12:34:56",
         "push_type": "UNICAST_PUSH",
         "direct_responses": "10",
         "sends": "123",
         "group_id": "04911800-f48d-11e2-acc5-90e2bf027020"
         }
      ]
}


JSON Parameters:
  • next_page – There might be more than one page of results for this report. Follow this URL if it is present to the next batch of results.
  • push_type – Describes the push operation, which is often comparable to the audience selection, e.g., BROADCAST_PUSH
  • group_id – An identifier set by the server to logically group a set of related pushes, e.g., in a push to local time.
Status Codes:
  • 202 Accepted – The push notification has been accepted for processing
  • 400 Bad Request – The request body was invalid, either due to malformed JSON or a data validation error. See the response body for more detail.
  • 401 Unauthorized – The authorization credentials are incorrect
  • 406 Not Acceptable – The request could not be satisfied because the requested API version is not available.

App Opens Report

GET /api/reports/opens/?start=(date)&end=(date)&precision=(precision)

Get the number of users who have opened your app within the specified time period.

Example Request: Get data from 2012-05-05 10:00 until 2012-05-15 20:00 by hour. First example uses CURL, second uses HTTP directly.

# Get data from 2012-05-05 10:00 until 2012-05-15 20:00 by hour
curl -u <app key>:<master secret> "https://verizonventures-prod.apigee.net/urbanairship/api/reports/opens/?start=2012-05-05%2010:00&end=2012-05-15%2020:00&precision=HOURLY"
GET /api/reports/opens/?start=2012-05-05%2010:00&end=2012-05-15%2020:00&precision=HOURLY HTTP/1.1
Authorization: Basic <master authorization string>


Query Parameters:
  • start – Timestamp for start of report
  • end – Timestamp for end of report
  • precision – Granularity of results to return. Possible values: HOURLY, DAILY, MONTHLY

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "opens": [
      {
         "android": 50
         "date": "2012-12-01 00:00:00",
         "ios": 500
      }
   ]
   "next_page": "https://go.urbanairship.com/api/reports/..."
}


JSON Parameters:
  • next_page – There might be more than one page of results for this report. Follow this URL if it is present to the next batch of results.

Time in App Report

GET /api/reports/timeinapp/?start=(date)&end=(date)&precision=(precision)

Get the average amount of time users have spent in your app within the specified time period.

Example Request: Get data from 2012-05-05 10:00 until 2012-05-15 20:00 by hour. The first example uses CURL. The second uses HTTP directly.

# Get data from 2012-05-05 10:00 until 2012-05-15 20:00 by hour
curl -u <app key>:<master secret> "https://verizonventures-prod.apigee.net/urbanairship/api/reports/timeinapp/?start=2012-05-05%2010:00&end=2012-05-15%2020:00&precision=HOURLY"
GET /api/reports/timeinapp/?start=2012-05-05%2010:00&end=2012-05-15%2020:00&precision=HOURLY HTTP/1.1
Authorization: Basic <master authorization string>


Query Parameters:
  • start – Timestamp for start of report
  • end – Timestamp for end of report
  • precision – Granularity of results to return. Possible values: HOURLY, DAILY, MONTHLY

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "timeinapp": [
      {
         "android": 50
         "date": "2012-12-01 00:00:00",
         "ios": 500
      }
   ]
   "next_page": "https://go.urbanairship.com/api/reports/..."
}


JSON Parameters:
  • next_page – There might be more than one page of results for this report. Follow this URL if it is present to the next batch of results.

Opt-in Report

GET /api/reports/optins/?start=(date)&end=(date)&precision=(precision)

Get the number of opted-in Push users who access the app within the specified time period.

Example Request: Get data from 2012-05-05 10:00 until 2012-05-15 20:00 by hour. First example uses CURL, second uses HTTP directly.

# Get data from 2012-05-05 10:00 until 2012-05-15 20:00 by hour
curl -u <app key>:<master secret> "https://verizonventures-prod.apigee.net/urbanairship/api/reports/optins/?start=2012-05-05%2010:00&end=2012-05-15%2020:00&precision=HOURLY"
GET /api/reports/optins/?start=2012-05-05%2010:00&end=2012-05-15%2020:00&precision=HOURLY HTTP/1.1
Authorization: Basic <master authorization string>


Query Parameters:
  • start – Timestamp for start of report
  • end – Timestamp for end of report
  • precision – Granularity of results to return. Possible values: HOURLY, DAILY, MONTHLY

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
   "optins": [
      {
         "android": 50
         "date": "2012-12-01 00:00:00",
         "ios": 500
      }
   ]
   "next_page": "https://go.urbanairship.com/api/reports/..."
}


JSON Parameters:
  • next_page – There might be more than one page of results for this report. Follow this URL if it is present to the next batch of results.

Opt-out Report

GET /api/reports/optouts/?start=(date)&end=(date)&precision=(precision)

Get the number of opted-out Push users who access the app within the specified time period.

Example Request: Get data from 2012-05-05 10:00 until 2012-05-15 20:00 by hour. First example uses CURL, second uses HTTP directly.

# Get data from 2012-05-05 10:00 until 2012-05-15 20:00 by hour
curl -u <app key>:<master secret> "https://verizonventures-prod.apigee.net/urbanairship/api/reports/optouts/?start=2012-05-05%2010:00&end=2012-05-15%2020:00&precision=HOURLY"
GET /api/reports/optouts/?start=2012-05-05%2010:00&end=2012-05-15%2020:00&precision=HOURLY HTTP/1.1
Authorization: Basic <master authorization string>


Query Parameters:
  • start – Timestamp for start of report
  • end – Timestamp for end of report
  • precision – Granularity of results to return. Possible values: HOURLY, DAILY, MONTHLY

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "optouts": [
      {
         "android": 50
         "date": "2012-12-01 00:00:00",
         "ios": 500
      }
   ]
   "next_page": "https://go.urbanairship.com/api/reports/..."
}


JSON Parameters:
  • next_page – There might be more than one page of results for this report. Follow this URL if it is present to the next batch of results.

Statistics

Warning

Requests to /api/push/stats/ must be made without an Accept HTTP header that specifies an API version.

The statistics API is available for all applications.

GET /api/push/stats/?start=(start_time)&end=(end_time)

Return hourly counts for pushes sent for this application.

Times are in UTC, and data is provided for each push platform. (Currently: iOS, Helium, BlackBerry, C2DM, GCM, Windows 8, and Windows Phone 8, in that order.)

In addition to JSON, the data is also available in CSV for easy importing into spreadsheets.

Here’s an example use with curl:

curl -u <application key> "https://verizonventures-prod.apigee.net/urbanairship/api/push/stats/?start=2009-06-22&end=2009-06-22+06:00&format=csv"
Enter host password for user '<application key>':
2009-06-22 00:00:00,0,0,0,0,0,0,0
2009-06-22 01:00:00,0,0,4,0,0,0,0
2009-06-22 02:00:00,0,0,2,0,0,0,0
2009-06-22 03:00:00,0,0,1,0,0,0,0
2009-06-22 04:00:00,8,0,0,0,0,0,0
2009-06-22 05:00:00,1,0,0,0,0,0,0

Mappings

GET /api/reports/mappings/send_ids/(send_id)

The send_ids endpoint allows you to look up the particular push ID associated with a given push received on a device.



Parameters:
  • send_id – The send ID to use for lookup.
Status Codes:
  • 200 – A push ID to send ID mapping.
  • 400 Bad requestsend_id malformed and could not be decoded.
  • 404 Not found – No push ID associated with the send ID.

Example Request: Get the push ID associated with send ID “5ciT0WadEeOjtAAbIc5Dvb”.

curl -u <app key>:<master secret> "https://verizonventures-prod.apigee.net/urbanairship/api/reports/mappings/send_ids/5ciT0WadEeOjtAAbIc5Dvb"

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "send_id": "5ciT0WadEeOjtAAbIc5Dvb",
  "push_id": "17e6719c-af7f-41fe-bb50-06b33bc63a3e"
}
GET /api/reports/mappings/message_ids/(message_id)

The message_ids endpoint takes a message ID from a rich message and returns the equivalent push ID. The endpoint does not guarantee that a rich message corresponding to the message_id actually exists. For details on the rich message ID, see Rich Message ID.



Parameters:
  • message_id – The rich message ID to use for lookup.
Status Codes:
  • 200 – A push ID to message ID mapping.
  • 400 Bad requestmessage_id malformed and could not be decoded.

Example Request: Get the push ID associated with rich message ID “KzYeYGKwEeOHhgCQ9dZz4g”.

# Get data from 2012-05-05 10:00 until 2012-05-15 20:00 by hour
curl -u <app key>:<master secret> "https://verizonventures-prod.apigee.net/urbanairship/api/reports/mappings/message_ids/KzYeYGKwEeOHhgCQ9dZz4g"

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "message_id": "KzYeYGKwEeOHhgCQ9dZz4g",
  "push_id": "2b361e60-62b0-11e3-8786-0090f5d673e2"
}

Per Push Reporting

There are two endpoints for retrieving data specific to the performance of an individual push. One that provides all the performance details at:

/api/reports/perpush/detail/(push_id)

and one that provides data for a time series at:

/api/reports/perpush/series/(push_id)

The Detail endpoint, if used with the GET method, requires no additional arguments. The endpoint can also be used with the POST method to get information on a collection of push IDs. In the latter case, you would omit the (push_id) and include a JSON array of push IDs. In either situation, you will receive an object (or array of objects) containing the following information:

Message Detail

app_key
unique identifier for your application, used to authenticate the application for API calls
push_id
UUID that is returned in the response for the push
created
time that the push was created
push_body
push payload as a Base64 encoded string

Engagement Activity

rich_deletions
if applicable, number of rich messages marked as deleted
rich_responses
if applicable, unique number of rich messages marked as opened
rich_sends
if applicable, number of rich notifications sent
sends
total number of push notification sent
direct_responses
app opens that are directly attributable to the push notification, i.e., user taps message or slides to view
influenced_responses
combination of app opens that are both directly and indirectly attributable to the push notification. Note: Urban Airship will no longer count influenced responses once 12 hours have passed since the notification was sent.

Platform-Specific Values

Beneath the totals, platform-specific values are given for sends, direct responses and influenced responses. Only iOS and Android are supported at this time. As a result, it’s possible that the total values, which include all platforms, will not match up with the sum of the platform-specific values if you are sending to additional platforms.

Per Push: Detail

Single Request
GET /api/reports/perpush/detail/(push_id)

Get all the analytics detail for a specific push ID

Example Request:

GET /api/reports/perpush/detail/57ef3728-79dc-46b1-a6b9-20081e561f97 HTTP/1.1
Authorization: Basic <authorization string>
Accept: application/vnd.urbanairship+json; version=3;

Example response

HTTP/1.1 200 OK
Content-Type: application/json

{
    "app_key": "some_app_key",
    "push_id": "57ef3728-79dc-46b1-a6b9-20081e561f97",
    "created": "2013-07-25 23:03:12",
    "push_body": "<Base64-encoded string>",
    "rich_deletions": 0,
    "rich_responses": 0,
    "rich_sends": 0,
    "sends": 58,
    "direct_responses": 0,
    "influenced_responses": 1,
    "platforms": {
        "android": {
            "direct_responses": 0,
            "influenced_responses": 0,
            "sends": 22
        },
        "ios": {
            "direct_responses": 0,
            "influenced_responses": 1,
            "sends": 36
        }
    }
}


Status Codes:
  • 400 Bad request – The request is malformed, precision is not one of HOURLY, DAILY, or MONTHLY, start or end date doesn’t parse (is not ISO 8601 or epoch millisecsonds).
  • 401 Unauthorized – The authorization credentials are incorrect or missing.
  • 403 Forbidden – Your account does not have access to this feature.
  • 404 Not found – The push does not exist.
Batch Request
POST /api/reports/perpush/detail/

Pass an array of individual Push IDs to the /reports/perpush/detail/ endpoint for batch processing. Receive Push Reports for a number of device tokens, channels, or APIDs.

Maximum 100 Push IDs per request.

Example Request:

POST /api/reports/perpush/detail/ HTTP/1.1
Authorization: Basic <authorization string>
Content-Type: application/json
Accept: application/vnd.urbanairship+json; version=3;

{
   "push_ids": [
      "8ecd82a9-982z-14da-39sg-uia90sa9",
      "8cj28vhw-734x-dj12-bbk0-08zii341"
   ]
}

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

[
   {
      "app_key": "DLRssdsoQ231FEqu92z_43",
      "push_id": "8ecd82a9-982z-14da-39sg-uia90sa9",
      "created": 0,
      "push_body": "<Base64-encoded string>",
      "sends": 57356,
      "direct_responses": 2654,
      "influenced_responses": 8915,
      "rich_sends": 0,
      "rich_responses": 0,
      "rich_deletions": 0,
      "platforms": {
         "ios": {
            "sends": 31522,
            "direct_responses": 1632,
            "influenced_responses": 5347
         },
         "android": {
            "sends": 25834,
            "direct_responses": 1022,
            "influenced_responses": 3568
         }
      }
   },
   {
      "app_key": "DLRssdsoQ231FEqu92z_43",
      "push_id": "8cj28vhw-734x-dj12-bbk0-08zii341",
      "created": 0,
      "push_body": "<Base64-encoded string>",
      "sends": 68348,
      "direct_responses": 3492,
      "influenced_responses": 11376,
      "rich_sends": 0,
      "rich_responses": 0,
      "rich_deletions": 0,
      "platforms": {
         "ios": {
            "sends": 39476,
            "direct_responses": 1987,
            "influenced_responses": 6754
         },
         "android": {
            "sends": 28872,
            "direct_responses": 1505,
            "influenced_responses": 4622
         }
      }
   },
]


JSON Parameters:
  • push_ids – An array of individual push_id values

Per Push: Series

GET /api/reports/perpush/series/(push_id)

Get the default time series data: Hourly precision for 12 hours. The series begins with the hour in which the push was sent.

Example Request:

GET /api/reports/perpush/series/57ef3728-79dc-46b1-a6b9-20081e561f97 HTTP/1.1
Authorization: Basic <authorization string>
Accept: application/vnd.urbanairship+json; version=3;

Example response (truncated to show only the first three items in array)

HTTP/1.1 200 OK
Content-Type: application/json

{
    "app_key": "some_app_key",
    "push_id": "57ef3728-79dc-46b1-a6b9-20081e561f97",
    "start": "2013-07-25 23:00:00",
    "end": "2013-07-26 11:00:00",
    "precision": "HOURLY",
    "counts": [
        {
            "push_platforms": {
                "all": {
                    "direct_responses": 0,
                    "influenced_responses": 1,
                    "sends": 58
                },
                "android": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 22
                },
                "ios": {
                    "direct_responses": 0,
                    "influenced_responses": 1,
                    "sends": 36
                }
            },
            "rich_push_platforms": {
                "all": {
                    "responses": 0,
                    "sends": 0
                }
            },
            "time": "2013-07-25 23:00:00"
        },
        {
            "push_platforms": {
                "all": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 0
                },
                "android": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 0
                },
                "ios": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 0
                }
            },
            "rich_push_platforms": {
                "all": {
                    "responses": 0,
                    "sends": 0
                }
            },
            "time": "2013-07-26 00:00:00"
        },
        {
            "push_platforms": {
                "all": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 0
                },
                "android": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 0
                },
                "ios": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 0
                }
            },
            "rich_push_platforms": {
                "all": {
                    "responses": 0,
                    "sends": 0
                }
            },
            "time": "2013-07-26 01:00:00"
        },


Status Codes:
  • 400 Bad request – The request is malformed, precision is not one of HOURLY, DAILY, or MONTHLY, start or end date doesn’t parse (is not ISO 8601 or epoch millisecsonds).
  • 401 Unauthorized – The authorization credentials are incorrect or missing.
  • 403 Forbidden – Your account does not have access to this feature.
  • 404 Not found – The push does not exist.

Per Push: Series with Precision

GET /api/reports/perpush/series/(push_id)?precision=(precision)

Get the series data, specifying the precision as HOURLY, DAILY, or MONTHLY. By specifying the precision without providing a time range, the default number of periods at each precision returned are as follows: Hourly: 12 Daily: 7 Monthly: 3

Example Request:

GET /api/reports/perpush/series/57ef3728-79dc-46b1-a6b9-20081e561f97?precision=HOURLY HTTP/1.1
Authorization: Basic <authorization string>
Accept: application/vnd.urbanairship+json; version=3;

Example response (truncated to show only the first three items in array)

HTTP/1.1 200 OK
Content-Type: application/json

{
    "app_key": "some_app_key",
    "push_id": "57ef3728-79dc-46b1-a6b9-20081e561f97",
    "start": "2013-07-25 23:00:00",
    "end": "2013-07-26 11:00:00",
    "precision": "HOURLY",
    "counts": [
        {
            "push_platforms": {
                "all": {
                    "direct_responses": 0,
                    "influenced_responses": 1,
                    "sends": 58
                },
                "android": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 22
                },
                "ios": {
                    "direct_responses": 0,
                    "influenced_responses": 1,
                    "sends": 36
                }
            },
            "rich_push_platforms": {
                "all": {
                    "responses": 0,
                    "sends": 0
                }
            },
            "time": "2013-07-25 23:00:00"
        },
        {
            "push_platforms": {
                "all": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 0
                },
                "android": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 0
                },
                "ios": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 0
                }
            },
            "rich_push_platforms": {
                "all": {
                    "responses": 0,
                    "sends": 0
                }
            },
            "time": "2013-07-26 00:00:00"
        },
        {
            "push_platforms": {
                "all": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 0
                },
                "android": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 0
                },
                "ios": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 0
                }
            },
            "rich_push_platforms": {
                "all": {
                    "responses": 0,
                    "sends": 0
                }
            },
            "time": "2013-07-26 01:00:00"
        },


Status Codes:
  • 400 Bad request – The request is malformed, precision is not one of HOURLY, DAILY, or MONTHLY, start or end date doesn’t parse (is not ISO 8601 or epoch millisecsonds).
  • 401 Unauthorized – The authorization credentials are incorrect or missing.
  • 403 Forbidden – Your account does not have access to this feature.
  • 404 Not found – The push does not exist.

Per Push: Series with Precision & Range

Note

Results may be paginated if requesting hourly precision over a long period of time.

GET /api/reports/perpush/series/(push_id)?precision=(precision)&start=(start_time)&end=(end_time)

Get the series data and specify what type of precision and a time range

Example Request:

GET /api/reports/perpush/series/57ef3728-79dc-46b1-a6b9-20081e561f97?precision=DAILY&start=2013-07-25&end=2013-07-30 HTTP/1.1
Authorization: Basic <authorization string>
Accept: application/vnd.urbanairship+json; version=3;

Example response (truncated to show only the first two items in array)

HTTP/1.1 200 OK
Content-Type: application/json

{
    "app_key": "some_app_key",
    "push_id": "57ef3728-79dc-46b1-a6b9-20081e561f97",
    "start": "2013-07-25 00:00:00",
    "end": "2013-07-30 00:00:00",
    "precision": "DAILY",
    "counts": [
        {
            "push_platforms": {
                "all": {
                    "direct_responses": 0,
                    "influenced_responses": 1,
                    "sends": 58
                },
                "android": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 22
                },
                "ios": {
                    "direct_responses": 0,
                    "influenced_responses": 1,
                    "sends": 36
                }
            },
            "rich_push_platforms": {
                "all": {
                    "responses": 0,
                    "sends": 0
                }
            },
            "time": "2013-07-25 00:00:00"
        },
        {
            "push_platforms": {
                "all": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 0
                },
                "android": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 0
                },
                "ios": {
                    "direct_responses": 0,
                    "influenced_responses": 0,
                    "sends": 0
                }
            },
            "rich_push_platforms": {
                "all": {
                    "responses": 0,
                    "sends": 0
                }
            },
            "time": "2013-07-26 00:00:00"
        },


Status Codes:
  • 400 Bad request – The request is malformed, precision is not one of HOURLY, DAILY, or MONTHLY, start or end date doesn’t parse (is not ISO 8601 or epoch millisecsonds).
  • 401 Unauthorized – The authorization credentials are incorrect or missing.
  • 403 Forbidden – Your account does not have access to this feature.
  • 404 Not found – The push does not exist.

Device Information

Individual Device Lookup

GET /api/channels/(channel)

Get information on an individual channel

Note

For more information on Channels, see Channels Primer.

Example Request:

GET /api/channels/9c36e8c7-5a73-47c0-9716-99fd3d4197d5 HTTP/1.1
Authorization: Basic <application authorization string>

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "ok":true,
  "channel":{
    "channel_id":"01234567-890a-bcde-f012-3456789abc0"
    "device_type":"ios",
    "installed":true,
    "opt_in":false,
    "push_address":"FE66489F304DC75B8D6E8200DFF8A456E8DAEACEC428B427E9518741C92C6660",
    "created":"2013-08-08T20:41:06",
    "last_registration":"2014-05-01T18:00:27",
    "alias":"your_user_id",
    "tags":[
      "tag1",
      "tag2"
    ],
    "ios":{
      "badge":0,
      "quiettime":{
        "start":null,
        "end":null
      },
      "tz":"America/Los_Angeles"
    }
  }
}
GET /api/device_tokens/(device_token)

Get information on a particular iOS device token.

Note

For iOS devices, we recommend transitioning to Channels as your primary identifier. Channels are available today for iOS apps using at minimum the 4.0 version of the Urban Airship SDK. See Channels Primer for more information.

Example Request:

GET /api/device_tokens/FE66489F304DC75B8D6E8200DFF8A456E8DAEACEC428B427E9518741C92C6660 HTTP/1.1
Authorization: Basic <application authorization string>

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "device_token": "FE66489F304DC75B8D6E8200DFF8A456E8DAEACEC428B427E9518741C92C6660",
   "active": true,
   "alias": "your_user_id",
   "tags": [
      "tag1",
      "tag2"
   ],
   "created": "2013-08-08 20:41:06",
   "last_registration": "2014-05-01 18:00:27",
   "badge": 2,
   "quiettime": {
      "start": "22:00",
      "end": "8:00"
   },
   "tz": "America/Los_Angeles"
}


JSON Parameters:
  • active – Status of the device token. If a device token is inactive, we will not push to it.
  • last_registration – We will show the date and time of the last registration if it is known; otherwise, the value will be null
GET /api/apids/(APID)

Get information on a particular Android APID.

Example Request:

GET /api/apids/11111111-1111-1111-1111-111111111111 HTTP/1.1
Authorization: Basic <application authorization string>

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "apid": "11111111-1111-1111-1111-111111111111",
   "active": true,
   "alias": "",
   "tags": [
      "tag1",
      "tag2"
   ],
   "created": "2013-03-11 17:49:36",
   "last_registration": "2014-05-01 18:00:27",
   "gcm_registration_id": "your_gcm_reg_id"
}


JSON Parameters:
  • active – Status of the APID. If the APID is inactive, we will not push to it.
  • last_registration – We will show the date and time of the last registration if it is known; otherwise, the value will be null
GET /api/device_pins/(PIN)

Get information on a particular BlackBerry PIN.

Example Request:

GET /api/device_pins/12345678 HTTP/1.1
Authorization: Basic <application authorization string>

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "device_pin": "12345678",
   "active": true,
   "alias": "your_user_id",
   "tags": [
      "tag1",
      "tag2"
   ],
   "created": "2013-03-11 17:49:36",
   "last_registration": "2014-05-01 18:00:27"
}


JSON Parameters:
  • active – Status of the PIN. If a PIN is inactive, we will not push to it.
  • last_registration – We will show the date and time of the last registration if it is known; otherwise, the value will be null

Device listing

GET /api/channels/

Fetch channels registered to this application, along with associated metadata

Example Request:

GET /api/channels/ HTTP/1.1
Authorization: Basic <master authorization string>

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "next_page": "https://go.urbanairship.com/api/channels?start=07AAFE44CD82C2F4E3FBAB8962A95B95F90A54857FB8532A155DE3510B481C13&limit=2",
   "channels": [
      {
         "channel_id": "9c36e8c7-5a73-47c0-9716-99fd3d4197d5",
         "device_type": "ios",
         "push_address": "FE66489F304DC75B8D6E8200DFF8A456E8DAEACEC428B427E9518741C92C6660",
         "opt_in": true,
         "installed": true,

         "created": "2014-03-06T18:52:59",
         "last_registration": "2014-10-07T21:28:35",

         "alias": "your_user_id",
         "tags": [
            "tag1",
            "tag2"
         ],

         "ios": {
            "badge": 2,
            "quiettime": {
               "start": "22:00",
               "end": "8:00"
            },
            "tz": "America/Los_Angeles"
         }
      },
      {
         "channel_id": "bd36e8c7-5a73-47c0-9716-99fd3d4197d5",
         "device_type": "ios",
         "push_address": null,
         "opt_in": false,
         "installed": true,

         "created": "2014-03-06T18:52:59",
         "last_registration": "2014-10-07T21:28:35",

         "alias": "your_user_id",
         "tags": [
            "tag1",
            "tag2"
         ],

         "ios": {
            "badge": 0,
            "quiettime": {
               "start": null,
               "end": null,
            },
            "tz": null
         }
      }
   ]
}


JSON Parameters:
  • next_page – There might be more than one page of results for this listing. Follow this URL if it is present to the next batch of results.
GET /api/device_tokens/

Fetch iOS device tokens registered to this application, along with associated metadata

Note

You may now encounter Channels (e.g., “9c36e8c7-5a73-47c0-9716-99fd3d4197d5”) in the next page URLs for this endpoint. This is expected behavior resulting from our back-end migration of device tokens to Channels as primary push identifiers. Calls to this endpoint should still work as expected as long as your code is dynamically getting to the next page based on the given URL.

Example Request:

GET /api/device_tokens/ HTTP/1.1
Authorization: Basic <master authorization string>

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "next_page": "https://go.urbanairship.com/api/device_tokens/?start=07AAFE44CD82C2F4E3FBAB8962A95B95F90A54857FB8532A155DE3510B481C13&limit=2",
   "device_tokens_count": 87,
   "device_tokens": [
      {
         "device_token": "0101F9929660BAD9FFF31A0B5FA32620FA988507DFFA52BD6C1C1F4783EDA2DB",
         "active": false,
         "alias": null,
         "tags": []
      },
      {
         "device_token": "07AAFE44CD82C2F4E3FBAB8962A95B95F90A54857FB8532A155DE3510B481C13",
         "active": true,
         "alias": null,
         "tags": ["tag1", "tag2"]
      }
   ],
   "active_device_tokens_count": 37
}


JSON Parameters:
  • next_page – There might be more than one page of results for this listing. Follow this URL if it is present to the next batch of results.
GET /api/device_tokens/count/

Fetch count of iOS device tokens registered to this application.

Example Request:

GET /api/device_tokens/count/ HTTP/1.1
Authorization: Basic <master authorization string>

Example Response:

{
  "active_device_tokens_count" : 100,
  "device_tokens_count" : 140
}
GET /api/apids/

Fetch Android APIDs registered to this application, along with associated metadata

Example Request:

GET /api/apids/ HTTP/1.1
Authorization: Basic <master authorization string>

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "next_page": "https://go.urbanairship.com/api/apids/?start=11111111-1111-1111-1111-111111111111&limit=2000",
   "apids": [
     {
         "c2dm_registration_id": null,
         "created": "2012-04-25 23:01:53",
         "tags": [],
         "apid": "00000000-0000-0000-0000-000000000000",
         "alias": null,
         "active": false
     },
     {
         "c2dm_registration_id": null,
         "created": "2013-01-25 00:55:06",
         "tags": [
             "tag1"
         ],
         "apid": "11111111-1111-1111-1111-111111111111",
         "alias": "alias1",
         "active": true
     }
   ]
}


JSON Parameters:
  • next_page – There might be more than one page of results for this listing. Follow this URL if it is present to the next batch of results.
GET /api/device_pins/

Fetch BlackBerry PINs registered to this application, along with associated metadata

Example Request:

GET /api/device_pins/ HTTP/1.1
Authorization: Basic <master authorization string>

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "next_page": "https://go.urbanairship.com/api/device_pins/?start=31676e1e&limit=2",
   "device_pins": [
      {
         "device_pin": "21504591",
         "active": true,
         "alias": "adam",
         "tags": [
            "tag1"
         ]
      },
      {
         "device_pin": "27a526e5",
         "active": true,
         "alias": null,
         "tags": [
             "tag1",
             "tag2"
         ]
      }
   ]
}


JSON Parameters:
  • next_page – There might be more than one page of results for this listing. Follow this URL if it is present to the next batch of results.

Feedback

GET /api/device_tokens/feedback/?since=(timestamp)

Apple informs us when a push notification is sent to a device that can’t receive it because the application has been uninstalled. We mark the device token as inactive and immediately stop sending notifications to that device.

The device token feedback listing API returns all device tokens marked inactive since the given timestamp. A device token can be marked as inactive in the Urban Airship system for one of three reasons:

  1. Apple’s feedback service reports the device token, as above.
  2. The device token has been manually deactivated via a device token deactivation API call
  3. The device token was rejected by APNS. See Rejected device token in the troubleshooting guide for more information.

Note

Apple sends a timestamp for each device token returned via the feedback service. Since a device can be off the network for a while, this can be a point in the recent past. In order to make this API work smoothly for you, we record the timestamp we marked as inactive. This means you only need to query for data since the last time you queried. Once a day is a good timeframe, or once a week for very small or infrequently used applications. A few times a day is good for applications with heavy use.

Example Request:

GET /api/device_tokens/feedback/?since=2009-06-15 HTTP/1.1
Authorization: Basic <master authorization string>


Query Parameters:
  • since – Find device tokens deactivated since this date or timestamp. This value must be less than one month from the current date.

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

[
   {
      "device_token": "1234123412341234123412341234123412341234123412341234123412341234",
      "marked_inactive_on": "2009-06-22 10:05:00",
      "alias": "bob"
   },
   {
      "device_token": "ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD",
      "marked_inactive_on": "2009-06-22 10:07:00",
      "alias": null
   }
]


JSON Parameters:
  • marked_inactive_on – Timestamp this token was marked inactive in our system.
GET /api/apids/feedback/?since=(timestamp)

Google informs us when a push notification is sent to a device that can’t receive it because the application has been uninstalled. We mark the APID as inactive and immediately stop sending notifications to that device.

Note

You only need to query for data since the last time you queried. Once a day is a good timeframe, or once a week for very small or infrequently used applications. A few times a day is good for applications with heavy use.

Example Request:

GET /api/apids/feedback/?since=2009-06-15T10:10:00 HTTP/1.1
Authorization: Basic <master authorization string>


Query Parameters:
  • since – Find APIDs deactivated since this date or timestamp. This value must be less than one month from the current date.

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

[
   {
      "apid": "00000000-0000-0000-0000-000000000000",
      "gcm_registration_id": null,
      "marked_inactive_on": "2009-06-22 10:05:00",
      "alias": "bob"
   },
   {
      "apid": "00000000-0000-0000-0000-000000000001",
      "gcm_registration_id": null,
      "marked_inactive_on": "2009-06-22 10:07:00",
      "alias": null
   }
]


JSON Parameters:
  • marked_inactive_on – Timestamp this APID was marked inactive in our system.

Device Registration APIs

One of the primary duties of the Urban Airship mobile SDKs is to register device identifiers with Urban Airship. Because this process is handled automatically by the SDK, there is no reason to manually register device IDs with Urban Airship via our APIs, except in the following two cases:

  1. You are sending notifications to the Blackberry platform, for which UA does not support a mobile SDK.

    We do not provide an SDK for Blackberry apps. See: BlackBerry PIN Registration for details on registering Blackberry PINs with Urban Airship.

  2. You have a sufficiently old or unique implementation which does not make use of the Urban Airship client SDK. In this case we strongly recommend that you discuss your implementation with our Support team. Failure to implement the SDK means that you cannot make use of the bulk of our functionality. The Support team can provide you with device registration API details if necessary.

BlackBerry PIN Registration

PUT /api/device_pins/(pin)

Register this PIN with this application. This will mark the PIN as active in our system. Optionally set metadata.

Simple registration can be done without a body.

Example Request:

PUT /api/device_pins/12345678 HTTP/1.1
Authorization: Basic <application authorization string>


Status Codes:
  • 200 – The device pin registration has been accepted.
  • 201 – The device pin registration has been accepted, and this device token has not been recorded for this app before.

Full capability:

Optionally, an alias or tags can be set in this request.

PUT /api/device_pins/12345678 HTTP/1.1
Authorization: Basic <application authorization string>
Content-Type: application/json
{
   "alias": "your_user_id",
   "tags": [
      "tag1",
      "tag2"
   ]
}


JSON Parameters:
  • alias – An alias for this device token. If no alias is supplied, any existing alias will be removed from the device token record.
  • tags – Zero or more tags for this device token. If the tags key is missing from the JSON body, tags will not be modified. To empty the tag set, send an empty array: [].
DELETE /api/device_pins/(pin)

Deactivate the PIN. Pushes will not be sent to inactive PINs. A future registration will reactivate the PIN.

Example Request:

DELETE /api/device_pins/12345678 HTTP/1.1
Authorization: Basic <application authorization string>


Status Codes:
  • 204 – The device token has been deactivated.

Uninstall Channels

POST /api/channels/uninstall/

Mark the given Channels as uninstalled; uninstalled channels do not receive push or rich app pages.

Note

Uninstallation is handled automatically by our SDK and push systems. If an end user opens their app after this API marks the device as “uninstalled”, it will automatically be set as “active” and “installed” again. This API is only useful for very specific scenarios. Before using this API endpoint, it is recommended that you first contact Urban Airship Support or your Account Manager to discuss your plans and intended use of this API endpoint.

Example Request:

POST /api/channels/uninstall/ HTTP/1.1
Authorization: Basic <master authorization string>
Content-Type: application/json
Accept: application/vnd.urbanairship+json; version=3;
[
   {
      "channel_id": "00000000-0000-0000-0000-000000000000",
      "device_type": "ios"
   },
   {
      "channel_id": "00000000-0000-0000-0000-000000000001",
      "device_type": "ios"
   }
]

Example Response:

HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
{
   "ok": true
}

Segments

Segments Information

GET /api/segments/

List all of the segments for the application.

Example Request:

GET /api/segments/ HTTP/1.1
Authorization: Basic <master authorization string>

Example Response:

HTTP/1.1 200 OK
Link: <https://go.urbanairship.com/api/segments?limit=1&sort=id&order=asc&start=3832cf72-cb44-4132-a11f-eafb41b82f64>;rel=next
Content-Type: application/json; charset=utf-8

{
   "next_page": "https://go.urbanairship.com/api/segments?limit=1&sort=id&order=asc&start=3832cf72-cb44-4132-a11f-eafb41b82f64",
   "segments": [
      {
         "creation_date": 1346248822221,
         "display_name": "A segment",
         "id": "00c0d899-a595-4c66-9071-bc59374bbe6b",
         "modification_date": 1346248822221
      }
   ]
}


Response Headers:
  • link – A link to the next page of results. If present, follow this URL to the next page of segments. Also available in the next_page value in the response body.
JSON Parameters:
  • next_page – A link to the next page of results. If present, follow this URL to the next page of segments. Also available in the Link header.
GET /api/segments/(segment_id)

Fetch information about a particular segment.

Example Request:

GET /api/segments/00c0d899-a595-4c66-9071-bc59374bbe6b HTTP/1.1
Authorization: Basic <master authorization string>

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "criteria": {
      "and": [
         {
            "tag": "ipad"
         },
         {
            "not": {
               "tag": "foo"
            }
         },
      ]
   },
   "display_name": "A segment"
}

Segment Creation

POST /api/segments/

Create a new segment.

Example Request:

POST /api/segments/ HTTP/1.1
Authorization: Basic <master authorization string>
Content-type: application/json

{
   "display_name": "News but not sports",
   "criteria": {
      "and": [
         {"tag": "news"},
         {"not":
            {"tag": "sports"}
         }
      ]
   }
}


JSON Parameters:
  • display_name – Human readable name for this segment. This will be used in the push composer.
  • criteria – Audience selection criteria. See the Segments documentation for detailed description.
Status Codes:
  • 201 – The segment was created.
PUT /api/segments/(segment_id)

Change the definition of the segment.

Example Request:

PUT /api/segments/00c0d899-a595-4c66-9071-bc59374bbe6b HTTP/1.1
Authorization: Basic <master authorization string>
Content-type: application/json

{
   "display_name": "Entertainment but not sports",
   "criteria": {
      "and": [
         {"tag": "news"},
         {"not":
            {"tag": "entertainment"}
         }
      ]
   }
}


JSON Parameters:
  • display_name – Human readable name for this segment. This will be used in the push composer.
  • criteria – Audience selection criteria. See the Segments documentation for detailed description.
Status Codes:
  • 200 – The segment was updated.
DELETE /api/segments/(segment_id)

Remove the segment.

Example Request:

DELETE /api/segments/00c0d899-a595-4c66-9071-bc59374bbe6b HTTP/1.1
Authorization: Basic <master authorization string>


Status Codes:
  • 204 – The segment has been deleted.

Segments Push

The Push APIs have been significantly updated in API v3, and they now have the ability to push to segments. See Push API v3 and API v3 Migration Guide for more information.

Location

Location Boundary Information

Name Lookup

GET /api/location/?q=(query)&type=(boundary_type)

Search for a location boundary by name. The search primarily uses the location names, but you can also filter the results by boundary type. For a full reference, please see our Boundary Types and Aliases Catalog. Because there are over 2.5M location boundaries available in Segments, we recommend you provide a type parameter along with your search to increase the chance you find the polygon you’re looking for. If you are not getting satisfactory results with searching for a location by name, you may want to consider using “Search for location by latitude and longitude” or “Search for location by bounding box” below.

Note

Due to contractual obligations we do not return proprietary datasets such as Maponics Neighborhood Boundaries or Nielsen DMA© in this endpoint. You can, however, search for those locations using the web interface.

Example Request:

GET /api/location/?q=San%20Francisco&type=city HTTP/1.1
Authorization: Basic <master authorization string>


Query Parameters:
  • q – Text search query.
  • type – Optional location type, e.g. city, province, or country.

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "features": [
      {
         "bounds": [
            37.63983,
            -123.173825,
            37.929824,
            -122.28178
         ],
         "centroid": [
            37.759715,
            -122.693976
         ],
         "id": "4oFkxX7RcUdirjtaenEQIV",
         "properties": {
            "boundary_type": "city",
            "boundary_type_string": "City/Place",
            "context": {
               "us_state": "CA",
               "us_state_name": "California"
            },
            "name": "San Francisco",
            "source": "tiger.census.gov"
         },
         "type": "Feature"
      }
   ]
}


JSON Parameters:

Lat/Long Lookup

GET /api/location/(latitude),(longitude)?type=(boundary_type)

Search for a location by latitude and longitude. For example, if you have (latitude: 37.7749295, longitude: -122.4194155), you could systematically convert those coordinates to the surrounding city (San Francisco) or the surrounding ZIP code (94103).

Example Request:

GET /api/location/37.7749295,-122.4194155?type=city HTTP/1.1
Authorization: Basic <master authorization string>


Query Parameters:
  • type – Optional location type, e.g. city, province, or country.

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "features": [
      {
         "bounds": [
            37.63983,
            -123.173825,
            37.929824,
            -122.28178
         ],
         "centroid": [
            37.759715,
            -122.693976
         ],
         "id": "4oFkxX7RcUdirjtaenEQIV",
         "properties": {
            "boundary_type": "city",
            "boundary_type_string": "City/Place",
            "context": {
               "us_state": "CA",
               "us_state_name": "California"
            },
            "name": "San Francisco",
            "source": "tiger.census.gov"
         },
         "type": "Feature"
      }
   ]
}


JSON Parameters:

Bounding Box Lookup

GET /api/location/(latitude_1),(longitude_1),(latitude_2),(longitude_2)&type=(boundary_type)

Search for locations using a bounding box. A bounding box is a rectangle that covers part of the earth. For example, you could say “give me all the ZIP codes in this area”. This may be useful if you want to create Segments that cover multiple locations nearby a certain area.

Example Request:

GET /api/location/37.805172690644405,-122.44863510131836,37.77654930110633,-122.39404678344727?type=postalcode HTTP/1.1
Authorization: Basic <master authorization string>

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "features": [
      {
         "bounds": [
            37.758749999999999,
            -122.477411,
            37.778851000000003,
            -122.428426
         ],
         "centroid": [
            37.769751999999997,
            -122.448239
         ],
         "id": "191QgPcnG1Um9MW06h1fa6",
         "properties": {
            "aliases": {
               "us_zip": "94117"
            },
            "boundary_type": "postalcode",
            "boundary_type_string": "Postal/ZIP Code",
            "name": "94117",
            "source": "tiger.census.gov"
         },
         "type": "Feature"
      },
   ]
}

Alias Lookup

GET /api/location/from-alias?(query)

Look up location boundary information based on real-world references.

Example Request:

GET /api/location/from-alias?us_state=CA HTTP/1.1
Authorization: Basic <master authorization string>

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
   "bounds": [
      32.528832,
      -124.482003,
      42.009517,
      -114.131211
   ],
   "centroid": [
      37.215297,
      -119.663837
   ],
   "id": "5LajTWicgiQKuX1RBBLDRI",
   "properties": {
      "abbr": "CA",
      "aliases": {
         "fips_10-4": "US06",
         "hasc": "US.CA",
         "state": "US06",
         "us_state": "CA"
      },
      "boundary_type": "province",
      "boundary_type_string": "State/Province",
      "name": "California",
      "source": "tiger.census.gov"
   },
   "type": "Feature"
}

Multiple queries may be passed in one API call:

GET /api/location/from-alias?us_state=CA&us_state=OR&us_state=WA HTTP/1.1
Authorization: Basic <master authorization string>

Polygon Lookup

Note

Due to contractual obligations we do not return proprietary datasets such as Maponics Neighborhood Boundaries or Nielsen DMA© in this endpoint. You can, however, search for those locations using the web interface.

GET /api/location/(polygon ID)?zoom=(zoom level)

Use this call to query polygons for which you already know the ID, for information such as context, boundary type, centroid, bounds, and its geometry.

The zoom level determines the level of detail of the coordinates (higher numbers are zoomed out farther, so they include fewer coordinates/the shape is simplified).

Valid range for zoom level is 1 (least detailed) through 20 (most detailed).

The polygon ID is what is returned from other location API lookup calls, and is the unique identifier for that polygon.

Example Request:

GET /api/location/1H4pYjuEW0xuBurl3aaFZS?zoom=1 HTTP/1.1
Authorization: Basic <master authorization string>

Example response (Coordinates listing truncated):

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
    "type": "Feature",
    "id": "1H4pYjuEW0xuBurl3aaFZS",
    "properties": {
        "source": "tiger.census.gov",
        "boundary_type_string": "City/Place",
        "name": "Portland",
        "context": {
            "us_state_name": "Oregon",
            "us_state": "OR"
        },
        "boundary_type": "city"
    },
    "bounds": [
        45.432393,
        -122.83675,
        45.653272,
        -122.472021
    ],
    "centroid": [
        45.537179,
        -122.650037
    ],
    "geometry": {
        "coordinates": [
            [
                [
                    [
                        -122.586136,
                        45.462439
                    ],
                    [
                        "..."
                    ]
                ]
            ]
        ],
        "type": "MultiPolygon"
    }
}

Location Date Ranges

The historical part of location is subject to some generous restraints. For example, you can’t use per-minute granularity for locations from 12 months ago, but you can do per-week granularity for locations from 12 months ago. This endpoint retrieves the possible date range bucket types that can be used for date ranges with location predicates and the cutoff date for history available for each range. This defines what time ranges are legal in location predicates. For example, 90 days = 129600 minutes. You cannot say “was in ZIP code 94123 in the past 129600 minutes”, but you can say “was in ZIP code 94123 in the past 3 months”.

You can query based on the following time ranges:

  • By minutes for the past 120 minutes
  • By hour for the past 48 hours
  • By day for the past 60 days
  • By week for the past 10 weeks
  • By month for the past 48 months
  • By year for the past 10 years
GET /api/segments/dates/

Retrieve cutoff dates for each time granularity.

Example request

GET /api/segments/dates/ HTTP/1.1
Authorization: Basic <master authorization string>

Example Response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

[
   {
      "unit": "minutes",
      "cutoff": "2012-07-11 13:42"
   },
   {
      "unit": "hours",
      "cutoff": "2012-07-09 15"
   },
   {
      "unit": "days",
      "cutoff": "2012-05-12"
   },
   {
      "unit": "weeks",
      "cutoff": "2012-W18"
   },
   {
      "unit": "months",
      "cutoff": "2008-07"
   },
   {
      "unit": "years",
      "cutoff": "2002"
   }
]