Skip to main content
Audience: Client developers integrating a Zixflow SDK
Purpose: How to report push delivery, opens, and action clicks so campaign analytics stay accurate.
For step-by-step platform code, use the SDK guides:

Why Push Tracking Matters

When Zixflow sends a push, it records the send. Your app must report what happens on the device:
  • Did it arrive?
  • Did the user open it?
  • Did they tap an action button?
Those callbacks power open rates, click rates, and post-push conversion funnels.

Delivery Lifecycle


The Push Payload

Zixflow injects two tracking fields into every push. trackMetric() requires both. They appear in message.data (Flutter/Android/RN) or userInfo (iOS). The rest of the payload depends on the dashboard rendering mode:
  • Native (OS-rendered): display content lives in FCM notification / APNs aps.alert; data (or top-level iOS keys) carries tracking + routing (deeplink_url, action_buttons, template_id, notif_id, workspace_id).
  • Custom (app-rendered): no notification block — title, body, image, sticky, and other display keys live in data.
Custom data example:
Use template_id to branch to a template-specific renderer. Full key reference and Native vs Custom wire format: Android · iOS · Flutter.

The Three Tracking Events

Event naming — read this first: trackMetric() used to always send a single generic internal event name, Report Delivery Event, for every metric type. The SDK now sends the metric name itself as the event nameDelivered, Opened, Clicked — so each lifecycle stage is directly filterable/reportable by name in analytics and Journeys. You still call trackMetric(event: MetricEvent.delivered) exactly as before; only the resulting event name on the backend changed. If you have older dashboards/segments filtering on "Report Delivery Event", update them to filter on "Delivered" / "Opened" / "Clicked" instead. Both old and new names are still recognized by the backend.

Delivered / Opened parameters

Action Clicked properties

Action clicks use track(), not trackMetric(). Always fire opened first, then the action event.

Minimal Flutter example

Full handlers for every platform (foreground, background, terminated, service worker) are in the SDK links at the top of this page.

Action Buttons Format

Not a Zixflow-defined field. If you add buttons in custom data, one convention is a JSON array of {name, deeplink}:
  • name — button label
  • deeplink — optional URL; empty string means no navigation

Zixflow sends deeplink_url for body taps and per-button deeplink values inside action_buttons. Route them in your app. Tracking and navigation are separate: always report metrics even if routing fails. FCM click_action is a platform field that needs a matching <intent-filter> on the Native path. Sample apps may also read data.click_action tokens (OPEN_SALE / OPEN_DASHBOARD) for in-app routing, taking priority over deeplink_url.

Decision Flow

Fallback (no Delivery ID)

If Zixflow-Delivery-ID is missing (e.g. a push not sent by Zixflow), do not call trackMetric. Reserved names (Delivered, Opened, Push Notification Action Clicked) are only treated as delivery reports when properties include a Zixflow delivery identifier. You may still show the notification and handle deep links locally.
Related: Devices & Push Notifications · Channels Overview