Custom push payloads

You can send highly customized push notifications using a Custom Payload. If you’ve integrated with our SDK, custom payloads let you send images and link customers to pages in your app when they tap your message.

Getting started with custom payloads

Creating a custom payload for your push notification grants access to a greater range of push features, like images and deep links—provided that your app is set up to support those features.

To enter a custom payload, click Custom Payload when composing your push notification.

Within a push message, Custom Payload is selected above the editor.
Within a push message, Custom Payload is selected above the editor.

You can then write or paste your custom code into the editor. There are different tabs for Android and iOS so that you can send custom code for each platform separately but, if you are using Firebase Cloud Messaging, you can just use the Android tab to send custom code that will be used for both Android and iOS.

Before you begin

Figure out what you want your message to do: do you want to send people to a deep link in your app or show them an image? Before you compose your message, make sure that your app supports that functionality. You may have to develop your app to handle some custom payload features.

If your payload includes links (like the link key, supported by our SDKs), you may need to know the format of deep links—links to pages within your app. Talk to your development team if you need help understanding the link scheme within your app.

You should also understand which push provider(s) you use. If you use Firebase Cloud Messaging, you may be able to construct a single payload supporting both Android and iOS devices. If you use Apple’s Push Notification service (APNs), you’ll need to enter different payloads for both iOS and Android devices.

When you have your payload, you’ll need to ensure that:

  1. Your JSON code is valid.

  2. The code you use follows the guidelines for the specific provider:

Here’s the most basic example of a custom payload for sending to Android and iOS devices via Firebase Cloud Messaging:

{
  "message": {
      "notification": {
        "body": "YOUR MESSAGE BODY HERE",
        "title": "YOUR MESSAGE TITLE HERE",
        "image": "YOUR IMAGE URL HERE"
      }
  }
}

Here’s the most basic example of a custom payload for sending to iOS devices via Apple Push Notification Service:

{
  "aps": {
    "alert": {
      "body": "YOUR MESSAGE BODY HERE",
      "title": "YOUR MESSAGE TITLE HERE"
    }
  }
}

Personalize push notifications

You can use liquidA syntax that supports variables, letting you personalize messages for your audience. For example, if you want to reference a person’s first name, you might use the variable {{customer.first_name}}. in your custom payload. While you can technically use liquid in any string field, you probably want to limit yourself to the body, title, and subtitle (on iOS) fields.

Here’s a basic Android (and iOS via FCM) example using customer and event data:

{
  "message": {
      "notification": {
         "body": "Hi {{customer.first_name}}, your {{event.event_title}} has been booked!",
         "title": "All set!"
      }
  }
}

This results in a push notification that looks like this on iOS:

Custom push payload reference

While you can send push notifications to both iOS and Android devices using FCM, if you want to provide a custom payload, you must provide separate payloads for your iOS and Android audiences.

If your custom payload does not match the shape below, or you provide an incorrect data type for a key, your notification may fail.

 Check your iOS notification setup

your iOS push payload changes based on whether you send notifications through Google’s Firebase cloud messaging platform (FCM) or the Apple Push Notification service (APNs). Make sure you reference the correct reference for your push provider.

FCM custom push payload

Your custom payload’s shape and keys depend on whether you use Customer.io’s SDKs or developed your own custom integration with our API. If you send a message with our SDKs, you can place the entire message within the message.data object or use the notification; our SDK handles both payload structures flexibly. This works for both Android and iOS platforms.

The message.data object can also contain custom data that your app to interpret. Custom data isn’t supported natively; it takes additional development. Talk to your app’s developer(s) to understand the custom data that you can pass to your app.

If you developed a custom integration, you can set a global notification—for both Android and iOS—in the message.notification object. You can pass additional options for the android push in the message.android.notification object.

You’ll find example payloads below depending on whether you’ve integrated with our SDK or wrote your own custom integration.

Our SDK natively supports the keys below. However, if you’ve extended the SDK or done additional app development, your payload may contain other fields.

{
  "message": {
    "data": {
      "title": "string", //(optional) The title of the notification
      "body": "string", //The message you want to send
      "image": "string", //https URL to an image you want to include in the notification
      "link": "string", //Deep link in the format remote-habits://deep?message=hello&message2=world
    }
  }
}
  • message
    Required The parent object for all push payloads.
        • body_loc_arg string
          Variable string values used in place of the format specifiers in body_loc_key to localize the body text to the user’s current localization. See Formatting and Styling for more information.
        • body_loc_key string
          The key to the body string in the app’s string resources that you want to use to localize the body text to the user’s current localization. See String Resources for more information.
        • click_action string
          The action that occurs when a user taps on the notification. Launches an activity with a matching intent filter when a person taps the notification.
        • color string
          The notification’s icon color in #rrggbb format.
        • icon string
          Sets the notification icon to myicon for drawable resource myicon. If you don’t send this key, FCM displays the launcher icon from your app manifest.
        • sound string
          The sound that plays when the device receives the notification. Supports "default" or the filename of a sound resource bundled in your app. Sound files must reside in /res/raw/.
        • tag string

          Identifier to replace existing notifications in the notification drawer. If empty, each request creates a new notification.

          If you specify a tag, and a notification with the same tag is already being shown, the new notification replaces the existing one in the notification drawer.

        • title_loc_arg string
          Variable string values used in place of the format specifiers in title_loc_key to localize the title text to the user’s current localization. See Formatting and Styling for more information.
        • title_loc_key string
          The key to the title string in the app’s string resources that you want to use to localize the title text to the user’s current localization. See String Resources for more information.
      • body string
        The body of your push notification.
      • image string
        The URL of an HTTPS image that you want to use for your message.
      • link string
        A deep link (to a page in your app), or a link to a web page.
      • title string
        The title of your push notification.
{
    "message": {
        "notification": {
            "title": "string", //(optional) The title of the notification
            "body": "string", //(optional) The message you want to send
            "image": "string" //https URL to an image you want to include in the notification
        },
        "data": {
            //Use if you've integrated with our SDK.
            //Optional key-value pairs that your app interprets.
            //We don't validate the keys or values you provide.
        },
        "android": {
            "notification": {
                //(Optional) Contains options specific to an android notification. 
                "icon": "string", 
                "sound": "string",
                "tag": "string",
                "color": "#rrggbb",
                "click_action": "string",
                "body_loc_key": "string",
                "body_loc_args": "stringified,array",
                "title_loc_key": "string",
                "title_loc_args": "stringified,array"
            }
        }
    }
}
        • body_loc_arg string
          Variable string values used in place of the format specifiers in body_loc_key to localize the body text to the user’s current localization. See Formatting and Styling for more information.
        • body_loc_key string
          The key to the body string in the app’s string resources that you want to use to localize the body text to the user’s current localization. See String Resources for more information.
        • click_action string
          The action that occurs when a user taps on the notification. Launches an activity with a matching intent filter when a person taps the notification.
        • color string
          The notification’s icon color in #rrggbb format.
        • icon string
          Sets the notification icon to myicon for drawable resource myicon. If you don’t send this key, FCM displays the launcher icon from your app manifest.
        • sound string
          The sound that plays when the device receives the notification. Supports "default" or the filename of a sound resource bundled in your app. Sound files must reside in /res/raw/.
        • tag string

          Identifier to replace existing notifications in the notification drawer. If empty, each request creates a new notification.

          If you specify a tag, and a notification with the same tag is already being shown, the new notification replaces the existing one in the notification drawer.

        • title_loc_arg string
          Variable string values used in place of the format specifiers in title_loc_key to localize the title text to the user’s current localization. See Formatting and Styling for more information.
        • title_loc_key string
          The key to the title string in the app’s string resources that you want to use to localize the title text to the user’s current localization. See String Resources for more information.
      • body string
        The body of your push notification.
      • title string
        The title of your push notification.

iOS custom push payload (FCM)

 This section is for iOS over Firebase only!

If you send push notifications to iOS using the Apple Push Notification service (APNs), you should see our APNs payload reference instead.

Before you send a push notification, make sure you understand how you’re integrated with Customer.io.

{
  "message": {
    "apns": {
      "payload": {
        "CIO": {
          "push": {
            "link": "string", //Deep link in the format remote-habits://deep?message=hello&message2=world
            "image": "string" //https URL to an image you want to include in the notification
          }
        },
        "aps": {
          "mutable-content": 1,
          "sound": "default",
          "alert": {
            "title": "string", //(optional) The title of the notification.
            "body": "string" //(optional) The message you want to send.
          }
        },
        // additional custom data
        "additionalProperties": "custom keys"
      }
    }
  }
}
            • body string
              The body of your push notification.
            • image string
              The URL of an HTTPS image that you want to use for your message.
            • link string
              A deep link (to a page in your app), or a link to a web page.
            • title string
              The title of your push notification.
          • alert
            string
            A simple alert message.
          • badge integer
            The number you want to display on your app’s icon. Set to 0 to remove the current badge, if any.
          • category string
            The notification’s type. This string must correspond to the identifier of one of the UNNotificationCategory objects you register at launch time.
          • content-available integer
            The background notification flag. Use 1 without an alert to perform a silent update. 0 indicates a normal push notification.
          • interruption-level string
            Indicates the importance and delivery timing of a notification.

            Accepted values:passive,active,time-sensitive,critical

          • mutable-content integer
            The notification service app extension flag. If the value is 1, your notification is passed to your notification service app extension before delivery. Use your extension to modify the notification’s content.
          • relevance-score number
            A number between 0 and 1. The highest score is considered the “most relevant” and is featured in the notification summary.
          • sound
            string
            The name of a sound file in your app’s main bundle or in the Library/Sounds folder of your app’s container directory. Use “default” to play the system sound. For critical alerts, you’ll pass an object instead.
          • target-content-id string
            The identifier of the window brought forward.
          • thread-id string
            An identifier to group related notifications.
        • Custom key-value pairs* any type
          Additional properties that you've set up your app to interpret outside of the Customer.io SDK.

When you send a custom notification, you can set a default message.notification with a body. The iOS custom payload portions of your notification appear in the apns object.

The following shows the basic shape of an iOS custom push payload for FCM. You’ll find a deeper explanation of the iOS payload options that FCM supports in Google’s documentation.

{
  "message": {
    "notification": {
      // default notification
      "title": "string",
      "body": "string"
    },
    "apns": {
      "headers": {
        // headers defined in Apple Push Notification Service.
        "apns-priority": 10
      },
      "payload": {
        "aps": {
          // iOS message options go here
          "mutable_content": true,
          "sound": "default"
        }
      }
    } 
  }
}
          • alert
            string
            A simple alert message.
          • badge integer
            The number you want to display on your app’s icon. Set to 0 to remove the current badge, if any.
          • category string
            The notification’s type. This string must correspond to the identifier of one of the UNNotificationCategory objects you register at launch time.
          • content-available integer
            The background notification flag. Use 1 without an alert to perform a silent update. 0 indicates a normal push notification.
          • interruption-level string
            Indicates the importance and delivery timing of a notification.

            Accepted values:passive,active,time-sensitive,critical

          • mutable-content integer
            The notification service app extension flag. If the value is 1, your notification is passed to your notification service app extension before delivery. Use your extension to modify the notification’s content.
          • relevance-score number
            A number between 0 and 1. The highest score is considered the “most relevant” and is featured in the notification summary.
          • sound
            string
            The name of a sound file in your app’s main bundle or in the Library/Sounds folder of your app’s container directory. Use “default” to play the system sound. For critical alerts, you’ll pass an object instead.
          • target-content-id string
            The identifier of the window brought forward.
          • thread-id string
            An identifier to group related notifications.

iOS custom push payload (APNs)

 This section is only for apps that use Apple’s Push Notification service (APNs)!

You can also send push notifications to iOS devices using Google’s Firebase Cloud Messaging (FCM) service. Make sure you use the correct payload for the messaging provider you set up in your Workspace Settings.

Whether you use our SDK or developed your own integration, your push notification will normally include a aps.alert object with a body, reflecting the message you want to send. You can pass additional options for the push in the aps object (outside of the alert). Where the alert represents the message, these settings tell the device how to handle the message—whether to play a sound or add the message to a thread of notifications, etc.

If you use our SDK, you’ll include additional options—like deep links or images—in the CIO.push object. Otherwise, you can pass additional, custom data outside the aps object. This custom data is something you’ve extended our SDK, or done your own development, to support. Talk to your app’s developer(s) to understand the custom data that you can pass to your app. You can omit the alert and send a silent push, with just custom data (setting "content-available": 1), though it’s not the most common use case.

{
  "aps": {
    "alert": { 
    //can be string or object
    //alert object keys
      "body": "string",
      "title": "string",
      "subtitle": "string",
      "launch-image": "string",
    // localization arguments
      "title-loc-key": "string",
      "title-loc-args": ["array", "of", "strings"],
      "subtitle-loc-key": "string",
      "subtitle-loc-args": ["array", "of", "strings"],
      "loc-key": "string",
      "loc-args": ["array", "of", "strings"]
    },
    // message options
    "badge": 0, // number
    "sound": "default",
    "thread-id": "string",
    "category": "string",
    "content-available": 0, // number, 0 (default) or 1
    "mutable-content": 0, // number, 0 (default) or 1
    "target-content-id": "string",
  },
  // options supported by Customer.io's SDK
  "CIO": {
    "push": {
        "link": "string", // deep links in the format remote-habits://deep?message=hello&message2=world
        "image": "string" // https URL to an image, including the file extension
    }
  },
  // additional custom data
  "additionalProperties": "custom keys"
}
      • image string
        The URL of an HTTPS image that you want to use for your message.
      • link string
        A deep link (to a page in your app), or a link to a web page.
    • alert
      string
      A simple alert message.
    • badge integer
      The number you want to display on your app’s icon. Set to 0 to remove the current badge, if any.
    • category string
      The notification’s type. This string must correspond to the identifier of one of the UNNotificationCategory objects you register at launch time.
    • content-available integer
      The background notification flag. Use 1 without an alert to perform a silent update. 0 indicates a normal push notification.
    • interruption-level string
      Indicates the importance and delivery timing of a notification.

      Accepted values:passive,active,time-sensitive,critical

    • mutable-content integer
      The notification service app extension flag. If the value is 1, your notification is passed to your notification service app extension before delivery. Use your extension to modify the notification’s content.
    • relevance-score number
      A number between 0 and 1. The highest score is considered the “most relevant” and is featured in the notification summary.
    • sound
      string
      The name of a sound file in your app’s main bundle or in the Library/Sounds folder of your app’s container directory. Use “default” to play the system sound. For critical alerts, you’ll pass an object instead.
    • target-content-id string
      The identifier of the window brought forward.
    • thread-id string
      An identifier to group related notifications.

Got feedback?

We’re hoping to get your feedback on how you’re using custom payloads, if there’s anything you’re struggling with, or if there’s anything you’re really enjoying about it and want to make sure we keep.

Let us know!

Copied to clipboard!
  Contents
Is this page helpful?