Skip to main content
Last Updated: July 2, 2026
Audience: Client developers integrating Zixflow SDK (Web)
Purpose: Track push notification lifecycle events — delivery, open, and action clicks — so Zixflow can measure campaign performance accurately.
See also: Web Push Notifications and the reference implementation sw.js.

Why Push Tracking Matters

When Zixflow sends a push notification to a user’s device, it records that the notification was sent. But it cannot know on its own:
  • Did the notification actually arrive on the device?
  • Did the user open it (tap the banner)?
  • Did the user tap an action button (“Shop Now”, “Remind Me”)?
Your app reports these three moments back to Zixflow using the SDK. This powers the delivery analytics you see in campaign dashboards — open rates, click rates, and conversion funnels after a push.

The Delivery Lifecycle at a Glance

Each of these SDK calls results in a delivery report event flowing to the Zixflow backend, updating the campaign’s live metrics.
Note: trackMetric is not available in a service worker context — call the Zixflow HTTP API directly from your service worker.

The Push Payload

Zixflow injects two special fields into every web-push JSON body. Your service worker uses these to associate the tracking event with the correct campaign delivery. The rest of the payload is the same official schema used on mobile Custom mode — display and routing keys live in the JSON body your service worker receives:
Important: action_buttons is a JSON string (not a nested object). Parse it before passing to showNotification({ actions }). There is no dashboard field named data.actions.

Complete Key Reference (web)

Mobile Native vs Custom wire format (FCM notification vs data, APNs aps) is documented on Android and iOS. Web push always delivers a JSON body to the service worker — treat it like Custom mode.

The Three Tracking Events

Event naming — read this first: On mobile SDKs, trackMetric() now sends the metric name itself as the event name — Delivered, Opened, Clicked — so each lifecycle stage is directly filterable/reportable by name in analytics and Journeys. The service worker cannot call trackMetric(); it posts to the HTTP track API. The event strings in the snippets below are unchanged (Push Notification Delivered, Push Notification Opened, Push Notification Action Clicked). Both old and new names are recognized by the backend. If you have older dashboards/segments filtering on "Report Delivery Event", update them to filter on "Delivered" / "Opened" / "Clicked" (and the action event name) instead.

1. Delivery Confirmed

Event name (sent to Zixflow): Delivered (mobile trackMetric) / Push Notification Delivered (service-worker HTTP)
When to fire: The moment the push data payload arrives on the device — inside your service worker push event handler.
What happens: Zixflow updates the campaign delivery record to delivered. No profile event is stored.

2. Notification Opened

Event name (sent to Zixflow): Opened (mobile trackMetric) / Push Notification Opened (service-worker HTTP)
When to fire: When the user taps the notification banner. Fire for both body taps and action button taps.
What happens: Zixflow updates the campaign delivery record to opened. No profile event is stored.

3. Action Button Clicked

Event name (sent to Zixflow): Push Notification Action Clicked
When to fire: When the user taps a named action button. Always fire Opened first, then fire this event.
What happens: Zixflow records a clicked delivery report and captures which button was tapped for campaign analytics.
Properties:

Platform-Specific Integration

Token Registration

Track Delivery (Service Worker — push event)

Track Open (Service Worker — notificationclick event)


Action Buttons Format

The action_buttons field is a JSON-encoded string of {name, deeplink} objects. Parse it before passing to showNotification({ actions }). Payload value (raw string):
Parsed structure:
Rules:
  • Maximum 2 buttons per notification (Chrome/desktop browsers support up to 2 actions)
  • deeplink may be an empty string — handle gracefully, don’t navigate to a blank URL
  • Button index is 0-based

Parsing action_buttons

Building the Buttons on the Notification

Chrome/desktop browsers support up to 2 actions per notification; unsupported browsers silently ignore the actions array and show a plain notification.

Handling the Tap (End-to-End)


Every Zixflow web push may carry a deeplink_url and per-button deeplinks in action_buttons. The service worker can’t render an in-app screen directly — it either focuses/navigates an existing tab or opens a new one.
Priority order for navigation on tap:
  1. If an action button was tapped → use action_buttons[index].deeplink
  2. If body was tapped → use deeplink_url
  3. If neither is set → open app to default screen

Write Key via SDK_CONFIG

Prefer receiving the write key from the WebPush plugin (not a hardcoded constant):

Setting User ID

After analytics.identify():

Decision Flowchart


Fallback Behaviour (No Zixflow-Delivery-ID)

If the push notification was sent by a non-Zixflow source, Zixflow-Delivery-ID and Zixflow-Delivery-Token will be absent from the payload. In this case, skip tracking with reserved event names. Push notification event names (Delivered, Opened, Push Notification Action Clicked) are reserved for Zixflow’s delivery pipeline only when their properties actually carry a Zixflow delivery identifier. If you send a custom event named exactly Delivered, Opened, or Clicked with no delivery identifier, it is stored as a normal profile event.

Testing

DevTools → Application → Service Workers → Console. Dashboard → MessagingPush Notifications.