GitHub project

Live notification payload reference

Updated August 19, 2026

Each payload’s type selects the 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 wrapper flattens them into a single object: header is a static attribute, and everything else is content state.

Multi-step tracker

import { LiveActivityTemplate } from 'customerio-reactnative';

const activityId = await CustomerIO.liveActivities.start({
  type: LiveActivityTemplate.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',
});
FieldTypeRequiredDescription
headerstringYesStatic header line. Set at start; can’t change.
statusstringYesPrimary status line.
substatusstringNoSecondary status line.
segmentsTotalnumberYesTotal number of steps. Capped at 20 steps.
segmentsCompletenumberYesSteps finished so far. Clamped to 0segmentsTotal.
trailingTextstringNoTrailing 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

const activityId = await CustomerIO.liveActivities.start({
  type: LiveActivityTemplate.CountdownTimer,
  header: 'Summer Sale',
  title: 'Flash sale ends in',
  statusMessage: '30% off everything',
  endTime: 1753603600,
});
FieldTypeRequiredDescription
headerstringYesStatic header line. Set at start; can’t change.
titlestringYesPrimary title line.
statusMessagestringNoStatus message below the title.
endTimenumberNoTarget 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.

const activityId = await CustomerIO.liveActivities.start({
  type: LiveActivityTemplate.Custom,
  data: {
    driver: 'Sam',
    vehicle: 'Blue Prius',
    minutesAway: '4',
  },
});
FieldTypeRequiredDescription
dataRecord<string, string>YesThe complete state, re-sent in full on every update.

Every value in data must be a string. Numbers and booleans are coerced, but 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.