> 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: August 19, 2026

# Live notification payload reference

Each payload constructor selects a template. `start` and `update` take the same shape—pass the complete state every time, because each update replaces the previous one rather than patching it.

`start` returns the notification’s ID. Keep it: `update` and `end` both take it, and it’s what you hand your server if you want it to take over.

The field names match the ones your server sends through the API. The plugin flattens them into a single payload: `header` is a static attribute, and everything else is content state.

## Multi-step tracker

```
final activityId = await CustomerIO.liveActivities.start(
  LiveActivityPayload.segments(
    header: "Chica's Tacos",
    status: 'Preparing your order',
    substatus: "We'll let you know when it's on the way",
    segmentsTotal: 4,
    segmentsComplete: 2,
    trailingText: '25 min',
  ),
);
```

Field

Type

Required

Description

`header`

`String`

Yes

Static header line. Set at start; can’t change.

`status`

`String`

Yes

Primary status line.

`substatus`

`String?`

No

Secondary status line.

`segmentsTotal`

`int`

Yes

Total number of steps. Capped at 20 steps.

`segmentsComplete`

`int`

Yes

Steps finished so far. Clamped to `0`–`segmentsTotal`.

`trailingText`

`String?`

No

Trailing text, such as an ETA. Typically matters for iOS. Android has a single slot for the message body; when both `substatus` and `trailingText` are set, the message body renders `substatus` and drops `trailingText`.

## Countdown timer

```
final activityId = await CustomerIO.liveActivities.start(
  LiveActivityPayload.countdownTimer(
    header: 'Summer Sale',
    title: 'Flash sale ends in',
    statusMessage: '30% off everything',
    endTime: 1753603600,
  ),
);
```

Field

Type

Required

Description

`header`

`String`

Yes

Static header line. Set at start; can’t change.

`title`

`String`

Yes

Primary title line.

`statusMessage`

`String?`

No

Status message below the title.

`endTime`

`int?`

No

Target time in **epoch seconds**, not milliseconds. Omit it to render the finished state.

## Custom

A custom notification has no schema—you render it, so the SDK passes your values through untouched.

```
final activityId = await CustomerIO.liveActivities.start(
  LiveActivityPayload.custom(
    data: {
      'driver': 'Sam',
      'vehicle': 'Blue Prius',
      'minutesAway': '4',
    },
  ),
);
```

Every value in `data` must be a string, and it carries the complete state on every update. Nested objects and arrays aren’t supported, and the platforms disagree on them—iOS drops them and Android turns them into strings. Flatten anything structured before you send it.

[GitHub project](https://github.com/customerio/customerio-flutter "View the Flutter SDK on GitHub")

Version

4.2.1 (Current)2.x (2.9.0)1.x (1.5.2)

©2026 Peaberry Software, Inc. [Status](https://status.customerio.com/) [Terms of Service](https://customer.io/legal/terms-of-service/) [Privacy Policy](https://customer.io/legal/privacy-policy/)

[](https://www.linkedin.com/company/customer-io)[](https://twitter.com/customerio)[](https://www.youtube.com/channel/UCkCaWdezRoa8ZyR9pEVaipA)[](https://www.instagram.com/customer.io/)
