Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
version: 1.0.0
title: Customer.io Journeys API Reference Live Notifications API
description: Customer.io provides REST APIs to send real-time customer data, retrieve data from your account, and trigger messages.
servers:
- url: https://track.customer.io
description: The base URL for the Track API. Track endpoints use basic authentication with your Site ID as the user name and your secret key as the password.
- url: https://track-eu.customer.io
description: The base URL for the Track API (EU region). Track endpoints use basic authentication with your Site ID as the user name and your secret key as the password.
- url: https://api.customer.io
description: The base URL for broadcasts, transactional messages, and data-retrieval APIs. These endpoints use bearer authorization, and require a [token that you generate in the UI](https://fly.customer.io/settings/api_credentials?keyType=app).
- url: https://api-eu.customer.io
description: The base URL for broadcasts, transactional messages, and data-retrieval APIs (EU region). These endpoints use bearer authorization, and require a [token that you generate in the UI](https://fly.customer.io/settings/api_credentials?keyType=app).
tags:
- name: Live Notifications
description: Start, update, and end live notifications—real-time activities on the iOS Lock Screen and Dynamic Island, and in the Android notification shade. Your server drives the activity's content; Customer.io handles token lookup and push delivery.
paths:
/v1/live_notifications/start:
servers:
- url: https://api.customer.io
description: The base URL for broadcasts, transactional messages, and data-retrieval APIs. These endpoints use bearer authorization, and require a [token that you generate in the UI](https://fly.customer.io/settings/api_credentials?keyType=app).
- url: https://api-eu.customer.io
description: The base URL for broadcasts, transactional messages, and data-retrieval APIs (EU region). These endpoints use bearer authorization, and require a [token that you generate in the UI](https://fly.customer.io/settings/api_credentials?keyType=app).
post:
summary: Start a live notification
operationId: startLiveNotification
security:
- Bearer-Auth: []
description: 'Start a live notification for a profile. Customer.io mints an `instance_id` for the new activity and returns it. You''ll use this ID to update, end, or check the status of the activity.
On iOS, this delivers a push-to-start event through APNs, so the person''s device must have a registered push-to-start token for the `notification_type` (the SDK registers one automatically when your app registers the activity type). Push-to-start requires iOS 17.2 or later. iOS starts also require a `push_payload.alert` with a title and body.
On Android, this delivers an FCM data message, which the SDK renders without your app being open.'
tags:
- Live Notifications
requestBody:
content:
application/json:
schema:
type: object
required:
- identifiers
- notification_type
- attributes
- content_state
properties:
identifiers:
type: object
description: Identifies the profile you want to start the activity for. You must provide exactly one of `id`, `email`, `phone`, or `internal` (our internal identifier, `cio_` followed by an alphanumeric string). You cannot target anonymous profiles.
properties:
id:
type: string
description: The profile's `id` attribute.
email:
type: string
description: The profile's email address.
phone:
type: string
description: The profile's phone number.
internal:
type: string
description: Our internal identifier for the profile, prefixed with `cio_`.
notification_type:
type: string
description: The reverse-DNS identifier of the activity type, like `io.customer.livenotifications.segments`. Must match a type your app registered with the SDK.
device_id:
type: string
description: The device token identifying the device to start the activity on.
platform:
type: string
enum:
- ios
- android
description: The device platform.
app_identifier:
type: string
description: 'The identifier of the app to start the activity on—a bundle ID on iOS or a package name on Android. This only matters when your workspace has multiple apps: set it to target a device belonging to that app, or omit it to target the workspace''s default app. Workspaces without multiple apps ignore this field. If you provide a value that doesn''t match an app in your workspace, the request fails with a `400`.
'
attributes:
minProperties: 1
description: 'Static fields used to create the activity—an order number, a flight''s origin and destination, or the teams in a match. On iOS they can''t change after start. On Android, include the static fields your renderer needs on update and end calls too, because the SDK renders from a merged payload. The shape depends on your `notification_type`: pick the free form variant for iOS or a free form Android activity, or the matching bundled-template variant below. Template fields are documented for [iOS](/integrations/sdk/ios/live-activities/reference/#built-in-templates) and [Android](/integrations/sdk/android/live-notifications/reference/#built-in-templates).
'
anyOf:
- $ref: '#/components/schemas/liveNotificationFreeFormAttributes'
- $ref: '#/components/schemas/SegmentsAttributes'
- $ref: '#/components/schemas/CountdownTimerAttributes'
content_state:
minProperties: 1
description: 'The initial dynamic content for the activity—the status, score, or ETA the device renders. Send the complete state on every call; partial updates aren''t supported. The shape depends on your `notification_type`: pick the free form variant for iOS or a free form Android activity, or the matching bundled-template variant below. Date fields are epoch seconds.
'
anyOf:
- $ref: '#/components/schemas/liveNotificationFreeFormContentState'
- $ref: '#/components/schemas/SegmentsContentState'
- $ref: '#/components/schemas/CountdownTimerContentState'
push_payload:
type: object
description: The alert shown when the activity starts. Required for iOS.
properties:
alert:
type: object
required:
- title
- body
properties:
title:
type: string
description: The alert title.
body:
type: string
description: The alert body.
sound:
type: string
description: The sound to play when the activity starts.
deep_link:
type: string
description: A link to open when the person taps the activity.
expiration:
type: integer
description: 'A unix timestamp (in seconds) for when the activity should expire. Must be no more than 6 hours in the future—values outside the range between now and that 6-hour maximum are rejected with a `400`. If you omit it (or pass `0`), the activity expires 6 hours after it starts.
'
responses:
'200':
description: The activity was queued. Returns the instance ID for the new activity.
content:
application/json:
schema:
type: object
properties:
instance_id:
type: string
description: The unique identifier (ULID) for the new activity instance. Use it to update, end, or check the status of the activity.
'400':
description: The request was malformed—a missing required field, an invalid platform, more or fewer than one identifier, or a missing iOS alert.
'404':
description: Live notifications aren't enabled for this workspace.
/v1/live_notifications/update:
servers:
- url: https://api.customer.io
description: The base URL for broadcasts, transactional messages, and data-retrieval APIs. These endpoints use bearer authorization, and require a [token that you generate in the UI](https://fly.customer.io/settings/api_credentials?keyType=app).
- url: https://api-eu.customer.io
description: The base URL for broadcasts, transactional messages, and data-retrieval APIs (EU region). These endpoints use bearer authorization, and require a [token that you generate in the UI](https://fly.customer.io/settings/api_credentials?keyType=app).
post:
summary: Update a live notification
operationId: updateLiveNotification
security:
- Bearer-Auth: []
description: 'Push a new content state to a running activity, referenced by its `instance_id`. The device re-renders the activity from the state you send.
Send the **full** content state on every update, not just the fields that changed—the platforms don''t support partial updates.
`push_payload` is optional on updates, whether Customer.io delivers directly through APNs or relays through Firebase Cloud Messaging (FCM). If you include a `push_payload.alert`, it must contain both a `title` and a `body`.'
tags:
- Live Notifications
requestBody:
content:
application/json:
schema:
type: object
required:
- instance_id
- content_state
properties:
instance_id:
type: string
description: The activity's instance ID (ULID), returned when you started it.
content_state:
minProperties: 1
description: The complete new content state for the activity. The content state's shape depends on the activity's `notification_type`. For iOS or a free form Android activity, pick the free form variant. For other Android notification types, pick the matching variant below. Date fields are epoch seconds.
anyOf:
- $ref: '#/components/schemas/liveNotificationFreeFormContentState'
- $ref: '#/components/schemas/SegmentsContentState'
- $ref: '#/components/schemas/CountdownTimerContentState'
attributes:
type: object
description: Static activity fields, for renderers that need them alongside the content state. On iOS, attributes can't change after start.
additionalProperties: true
push_payload:
type: object
description: The alert to accompany the update. Optional whether Customer.io delivers directly through APNs or relays through Firebase Cloud Messaging (FCM). If you include an alert, provide both its `title` and `body`.
properties:
alert:
type: object
required:
- title
- body
properties:
title:
type: string
description: The alert title.
body:
type: string
description: The alert body.
sound:
type: string
description: The sound to play with the update.
deep_link:
type: string
description: A link to open when the person taps the activity.
responses:
'200':
description: The update was queued.
content:
application/json:
schema:
type: object
properties:
instance_id:
type: string
description: The activity's instance ID.
'400':
description: The request was malformed, `instance_id` isn't a valid ULID, or a `push_payload.alert` was missing a `title` or `body`.
'404':
description: Live notifications aren't enabled for this workspace.
/v1/live_notifications/end:
servers:
- url: https://api.customer.io
description: The base URL for broadcasts, transactional messages, and data-retrieval APIs. These endpoints use bearer authorization, and require a [token that you generate in the UI](https://fly.customer.io/settings/api_credentials?keyType=app).
- url: https://api-eu.customer.io
description: The base URL for broadcasts, transactional messages, and data-retrieval APIs (EU region). These endpoints use bearer authorization, and require a [token that you generate in the UI](https://fly.customer.io/settings/api_credentials?keyType=app).
post:
summary: End a live notification
operationId: endLiveNotification
security:
- Bearer-Auth: []
description: 'End a running activity, referenced by its `instance_id`. On iOS, the system dismisses the activity from the Lock Screen. On Android, the SDK normally renders the final content as a non-ongoing notification; it cancels the notification only when there''s no final notification to render. You can include a final `content_state` to show before the activity ends.
`push_payload` is optional on the end call, whether Customer.io delivers directly through APNs or relays through Firebase Cloud Messaging (FCM). If you include a `push_payload.alert`, it must contain both a `title` and a `body`.'
tags:
- Live Notifications
requestBody:
content:
application/json:
schema:
type: object
required:
- instance_id
properties:
instance_id:
type: string
description: The activity's instance ID (ULID), returned when you started it.
content_state:
description: The final content state to show before the activity ends. Defaults to the last state you sent. The content state's shape depends on the activity's `notification_type`. For iOS or a free form Android activity, pick the free form variant. For other Android notification types, pick the matching variant below.
anyOf:
- $ref: '#/components/schemas/liveNotificationFreeFormContentState'
- $ref: '#/components/schemas/SegmentsContentState'
- $ref: '#/components/schemas/CountdownTimerContentState'
attributes:
type: object
description: Static activity fields, for renderers that need them alongside the content state.
additionalProperties: true
push_payload:
type: object
description: The alert to accompany the end event. Optional whether Customer.io delivers directly through APNs or relays through Firebase Cloud Messaging (FCM). If you include an alert, provide both its `title` and `body`.
properties:
alert:
type: object
required:
- title
- body
properties:
title:
type: string
description: The alert title.
body:
type: string
description: The alert body.
sound:
type: string
description: The sound to play with the end event.
deep_link:
type: string
description: A link to open when the person taps the activity.
responses:
'200':
description: The end event was queued.
content:
application/json:
schema:
type: object
properties:
instance_id:
type: string
description: The activity's instance ID.
'400':
description: The request was malformed, `instance_id` isn't a valid ULID, or a `push_payload.alert` was missing a `title` or `body`.
'404':
description: Live notifications aren't enabled for this workspace.
/v1/live_notifications/{instance_id}:
servers:
- url: https://api.customer.io
description: The base URL for broadcasts, transactional messages, and data-retrieval APIs. These endpoints use bearer authorization, and require a [token that you generate in the UI](https://fly.customer.io/settings/api_credentials?keyType=app).
- url: https://api-eu.customer.io
description: The base URL for broadcasts, transactional messages, and data-retrieval APIs (EU region). These endpoints use bearer authorization, and require a [token that you generate in the UI](https://fly.customer.io/settings/api_credentials?keyType=app).
get:
summary: Get a live notification's status
operationId: getLiveNotification
security:
- Bearer-Auth: []
description: Look up a live notification's current state, lifecycle timestamps, and the status of its most recent delivery.
tags:
- Live Notifications
parameters:
- name: instance_id
in: path
required: true
schema:
type: string
description: The activity's instance ID (ULID), returned when you started it.
responses:
'200':
description: The activity's current status.
content:
application/json:
schema:
type: object
properties:
instance_id:
type: string
description: The activity's instance ID.
notification_type:
type: string
description: The activity's reverse-DNS type identifier.
platform:
type: string
description: The device platform—`ios` or `android`.
state:
type: string
enum:
- active
- ended
- expired
- failed
description: The activity's lifecycle state.
failure_reason:
type: string
nullable: true
description: Why the activity failed, when `state` is `failed`.
started_at:
type: integer
description: When the activity started (unix timestamp).
ended_at:
type: integer
nullable: true
description: When the activity ended (unix timestamp).
expires_at:
type: integer
nullable: true
description: When the activity expires (unix timestamp).
last_delivery:
type: object
nullable: true
description: The most recent delivery for the activity.
properties:
id:
type: string
description: The delivery ID.
operation:
type: string
enum:
- start
- update
- end
description: The lifecycle operation the delivery carried.
status:
type: string
enum:
- queued
- sent
- failed
- undeliverable
description: The delivery's status.
source:
type: string
description: Where the operation originated—the API or the device.
created_at:
type: integer
description: When the delivery was created (unix timestamp).
'400':
description: '`instance_id` isn''t a valid ULID.'
'404':
description: The activity wasn't found—a recently started one may not be processed yet—or live notifications aren't enabled for this workspace.
components:
schemas:
liveNotificationFreeFormAttributes:
x-scalar-ignore: true
title: Free-form (iOS or Android custom type)
type: object
description: Your own static fields. On iOS, field names must match the `ActivityAttributes` type in your app. For Android custom types, fields pass through to your app's renderer as-is.
additionalProperties: true
SegmentsContentState:
x-scalar-ignore: true
title: Multi-step tracker
type: object
description: 'Dynamic fields for the multi-step tracker template. `notification_type`: `io.customer.livenotifications.segments`.'
required:
- status
- segmentsTotal
- segmentsComplete
properties:
status:
type: string
description: Primary status line, like `Out for delivery`.
substatus:
type: string
description: Secondary line under the status.
segmentsTotal:
type: integer
minimum: 1
maximum: 20
description: The total number of segments in the progress bar. Values above 20 are capped at 20.
segmentsComplete:
type: integer
description: How many segments are filled; the remainder render as incomplete. Values above segmentsTotal are capped at segmentsTotal.
trailingText:
type: string
description: Short text on the Dynamic Island trailing edge, e.g. \"5 min\". Keep it brief; the trailing region is narrow.
liveNotificationFreeFormContentState:
x-scalar-ignore: true
title: Free-form (iOS or Android custom type)
type: object
description: Your own dynamic fields. On iOS, field names must match your `ContentState` type. For Android custom types, fields pass through to your app's renderer as-is. Date fields are epoch seconds.
additionalProperties: true
SegmentsAttributes:
x-scalar-ignore: true
title: Multi-step tracker
type: object
description: 'Static fields for a multi-step tracker template. `notification_type`: `io.customer.livenotifications.segments`.'
required:
- header
properties:
header:
type: string
description: Top-row label
CountdownTimerAttributes:
x-scalar-ignore: true
title: Countdown timer
type: object
description: 'Static fields for the countdown timer template. `notification_type`: `io.customer.livenotifications.countdowntimer`.'
required:
- header
properties:
header:
type: string
description: Top-row label of the notification.
CountdownTimerContentState:
x-scalar-ignore: true
title: Countdown timer
type: object
description: 'Dynamic fields for the countdown timer template. `notification_type`: `io.customer.livenotifications.countdowntimer`.'
required:
- title
properties:
title:
type: string
description: Primary status line.
statusMessage:
type: string
description: Secondary line under the title.
endTime:
type: integer
description: Countdown target, in whole seconds since 1970 UTC. A time in the future renders a live countdown; omit it to render no timer. The countdown does not clear itself when it reaches zero — it rests at \"0:00\" until you send an update with a finished title and no endTime.
securitySchemes:
Tracking-API-Key:
type: http
scheme: basic
description: 'The Track API uses a basic authentication scheme. Your credentials are your **Site ID** and your **API key**, **Base-64 encoded** in the format `site_id:api_key`.
You can find your Site ID and API key on the [Track API Keys page](https://fly.customer.io/settings/api_credentials).
'
Bearer-Auth:
type: http
scheme: bearer
description: 'The App API uses a bearer authentication scheme.
You can generate a bearer token, known as an **App API Key**, with a defined scope in [your account settings](https://fly.customer.io/settings/api_credentials?keyType=app). [Learn more about bearer authorization in Customer.io](/accounts/settings/managing-credentials).
'
ServiceAccount-Auth:
x-scalar-ignore: true
type: http
scheme: bearer
bearerFormat: sa_live_
description: 'Transactional send endpoints (`/v1/send/email`, `/v1/send/push`, `/v1/send/sms`, `/v1/send/whatsapp`, `/v1/send/in_app`, `/v1/send/inbox_message`) also accept a service-account bearer token, prefixed with `sa_live_`. Service-account tokens work across workspaces, so you must pass the target workspace as the `X-Workspace-Id` header on each request.
Service-account tokens are intended for testing and one-off sends—for example, using the Customer.io CLI with an AI agent like Claude to verify that a transactional message renders correctly before wiring it into your production backend. **For the production integration that triggers the message from your application, use an App API Key instead**: it''s workspace-scoped, easier to rotate, and has a smaller blast radius.
Service-account tokens are server-side credentials. Treat them like any API key—keep them in environment variables or a secret manager, and never embed them in client-side code, mobile apps, or other untrusted contexts.
'
bearerAuth:
type: http
scheme: bearer
description: API key passed as a Bearer token.
x-tagGroups:
- name: Track API v2
tags:
- track_v2
- Object Schemas
- Person Schemas
- Deliveries
- name: Track API
tags:
- trackOverview
- trackJsOrBackend
- trackLimit
- trackRegion
- Track Customers
- Track Events
- Forms
- Track Segments
- Track v1 Overview
- name: App API
tags:
- appOverview
- appLimit
- appAuth
- Activities
- Automations
- Broadcasts
- Collections
- Customers
- Data Index
- ESP Suppression
- Exports
- Imports
- Info
- Live Notifications
- Messages
- Newsletters
- Opt-outs
- Reporting Webhooks
- Segments
- Sender Identities
- Snippets
- Subscription Center
- Transactional
- Workspaces
- Send Messages
- Objects
- Newsletter Variants
- Newsletter Metrics
- Assets
- name: Design Studio API
tags:
- Folders
- Components
- Emails
- Email link and publish
- Email testing
- SMS
- SMS link and publish
x-provenance:
method: harvested
publisher: Customer.io
source: https://docs.customer.io/openapi.yaml
note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
stamped by stamp-openapi-provenance.py (roadmap#793)