> This page is part of the [Customer.io documentation](https://docs.customer.io). For the complete index, see [llms.txt](https://docs.customer.io/llms.txt).
> Last updated: July 30, 2026

# Live updates

[PremiumThis feature is available for Premium plans.](/accounts/billing/plan-features/) [EnterpriseThis feature is available for Enterprise plans.](/accounts/billing/plan-features/)

Live notifications let you push real-time, continuously updated notifications to Android devices—a delivery tracker, a live score, a countdown. Use built-in templates or create your own, and let Customer.io push real-time updates to the notification shade panel.

 Rollout in progress

We are currently rolling out this feature. If you’re on a premium or enterprise plan and can’t send live notifications yet, hang tight!

On Android 16 and later, live notifications render with the platform’s promoted “Live Updates” treatment; on earlier versions, they gracefully fall back to standard ongoing notifications with the same content.

Unlike iOS—where you build the activity UI yourself—the Android SDK ships **built-in templates** for common use cases: delivery tracking, flight status, live score, countdown timer, and auction bid. For anything else, define a custom type and render the notification in your own code.

See [How live notifications work](/messaging/channels/live-notifications/how-it-works/) to learn more about the live notification lifecycle.

 Live notifications are part of the push module

Live notifications require the `messagingpush` module. You need [push set up with FCM](/integrations/sdk/android/push/), notification permission (`POST_NOTIFICATIONS` on Android 13+), and an identified person.

## Step 1: Enable notification types

You must enable at least one type of live notification in your push module configuration. Enable built-in template types with `enableLiveNotificationTypes`, and your own app-rendered types with `enableCustomLiveNotificationTypes`. The calls are additive—use either or both.

Add the module when you initialize the SDK, and keep a reference if you plan to start live notifications locally.

```kotlin
import io.customer.messagingpush.MessagingPushModuleConfig
import io.customer.messagingpush.ModuleMessagingPushFCM
import io.customer.messagingpush.livenotification.LiveNotificationType

val pushModule = ModuleMessagingPushFCM(
    MessagingPushModuleConfig.Builder()
        // Built-in templates, rendered by the SDK
        .enableLiveNotificationTypes(
            LiveNotificationType.DELIVERY_TRACKING,
            LiveNotificationType.COUNTDOWN_TIMER
        )
        // Custom types, rendered by your callback (step 3)
        .enableCustomLiveNotificationTypes("io.yourapp.workout")
        .build()
)
```

Each built-in type has a reverse-DNS identifier that your server uses to target it:

Type

Identifier

`SEGMENTS`

`io.customer.liveactivities.segments`

`COUNTDOWN_TIMER`

`io.customer.liveactivities.countdowntimer`

The identifiers match the iOS sample types, so a cross-platform activity can share one `notification_type` server-side. Each template’s fields are documented in the [payload reference](/messaging/channels/live-notifications/payload-reference/).

## Step 2: Add branding (optional)

Built-in templates accept app-level branding. This includes an accent color and logo applied to every live notification the SDK renders from a template. You can also register image assets by key, so template fields like a team’s `logo` can reference bundled images.

```kotlin
import io.customer.messagingpush.livenotification.LiveNotificationBranding

MessagingPushModuleConfig.Builder()
    .setLiveNotificationBranding(
        LiveNotificationBranding(
            companyName = "Your Company",
            accentColor = Color.parseColor("#1B5E20"),
            logoDrawableName = null,
            logoAssetKey = "brand-logo"
        )
    )
    // Registers a bundled drawable, addressable as "brand-logo" from
    // templates and branding. Overloads accept a Uri or raw image bytes.
    .registerLiveNotificationAsset("brand-logo", R.drawable.brand_logo)
```

*   `accentColor` sets the notification’s accent color. Individual templates can override it per update with a `statusColor` field.
*   `logoAssetKey` this can be a registered asset key, a bundled drawable name, or an `https` URL. It resolves through the asset pipeline and renders as the large icon when the template doesn’t provide its own image.
*   `logoDrawableName` overrides the **small icon** (the status-bar glyph) for live notifications. Because it’s a status-bar resource, it must be a bundled, drawable name.

## Step 3: Render custom types

If you want to send a notification without a built-in template, you must render it yourself. Implement `createLiveNotification` and return a complete `Notification`—or `null` to fall back to the SDK’s template for built-in types.

```kotlin
import io.customer.messagingpush.data.communication.CustomerIOPushNotificationCallback
import io.customer.messagingpush.data.model.CustomerIOParsedPushPayload

class MyPushCallback : CustomerIOPushNotificationCallback {
    override fun createLiveNotification(
        payload: CustomerIOParsedPushPayload,
        context: Context
    ): Notification? {
        val extras = payload.extras
        // Return null for types you don't render—the SDK's templates
        // handle the built-in ones.
        if (extras.getString("notification_type") != "io.yourapp.workout") return null
        val ended = extras.getString("event") == "end"
        return NotificationCompat.Builder(context, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_workout)
            .setContentTitle(extras.getString("title"))
            .setOngoing(!ended)
            .build()
    }
}
```

The activity’s flattened fields arrive in `payload.extras` with `notification_type` and the `event` (`start`, `update`, or `end`). The SDK posts your notification keyed by the activity ID so updates replace it in place, and cancels it on end. Register the callback with `setNotificationCallback` on the module config builder.

## Step 4: Start an activity

There are two ways to start a live notification activity:

*   **From your server:** You call [the API](/integrations/api/app/#tag/live-notifications/startLiveNotification) when you’re ready to start a live notification and Customer.io delivers an FCM data message. The SDK renders the notification without your app needing to be open. This is the most common path for notifications like delivery tracking and live scores.
*   **From your app:** Start the activity locally through the push module. Built-in types use typed data classes; custom types take a field map. This is a common path for notifications like a workout progress tracker.

### From your server

Call the API to [start](/integrations/api/app/#tag/live-notifications/startLiveNotification) and [update](/integrations/api/app/#tag/live-notifications/updateLiveNotification) a live notification. Customer.io delivers the FCM data message, and the SDK renders the notification from your payload’s fields. See the [payload reference](/messaging/channels/live-notifications/payload-reference/) for each template’s fields.

### From your app

Start the activity locally through the push module:

```kotlin
import io.customer.messagingpush.livenotification.LiveNotificationData

// Built-in template type
val activityId = pushModule.startLiveNotification(
    LiveNotificationData.DeliveryTracking(
        title = "Order received",
        progress = LiveNotificationData.Progress(current = 1, total = 4)
    )
)
```

`startLiveNotification` returns the activity’s generated ID and registers the notification with Customer.io, so your server can take over updates from there. Local starts, updates, and ends are reported to Customer.io automatically, keeping the activity’s delivery timeline complete.

Then you can update the activity and end it later with the returned id.

```kotlin
// Update and end it later with the returned id
pushModule.updateLiveNotification(
    activityId,
    LiveNotificationData.DeliveryTracking(
        title = "Out for delivery",
        progress = LiveNotificationData.Progress(current = 3, total = 4)
    )
)
pushModule.endLiveNotification(activityId)
```

## Live notification updates and lifecycle

Live notifications are FCM **data messages**, not display notifications. The SDK renders them directly, updating the notification in place by its instance ID. Because Android renders each message as it arrives, the SDK guards against out-of-order and duplicate deliveries using the message timestamp. When a person logs out, the SDK ends and clears all live notifications on the device.

The notification lifecycle can also end when a person interacts with the notification. When this happens, the SDK ends the activity and clears the notification.

## Related pages

*   [Live notifications overview](/messaging/channels/live-notifications/overview/)
*   [How live notifications work](/messaging/channels/live-notifications/how-it-works/)
*   [Payload reference](/messaging/channels/live-notifications/payload-reference/)
*   [Push notifications on Android](/integrations/sdk/android/push/)

Version[](https://github.com/customerio/customerio-android/releases/tag/4.20.0 "See this release in GitHub")

4.20.0 (Current)3.11.12.1.1

*   *   [Step 1: Enable notification types](#step-1-enable-notification-types)
    *   [Step 2: Add branding (optional)](#step-2-add-branding-optional)
    *   [Step 3: Render custom types](#step-3-render-custom-types)
    *   [Step 4: Start an activity](#step-4-start-an-activity)
        *   [From your server](#from-your-server)
        *   [From your app](#from-your-app)
    *   [Live notification updates and lifecycle](#live-notification-updates-and-lifecycle)
    *   [Related pages](#related-pages)

Copy page

Copy page [Download .md](/integrations/sdk/android/push/live-notifications.md) [Download Android SDK bundle](/files/android-sdk-docs.md)

Is this page helpful?

![](https://docs.customer.io/images/export-success.png) ![](https://docs.customer.io/images/export-failure.png)

# How can we make it better?

Close

Do you need help from Customer.io support?  No  
 Yes

What part of Customer.io do you need help with? 

How can we improve this page?

Email (optional):  Please provide a valid email address

 I am not a bot

 

We appreciate your feedback!

Our support team will contact you as soon as possible
