Skip to main content

Campaign report

Click any campaign in the list. The report is the same for wizard campaigns, transactional sends and A/B tests; the A/B table simply appears when there is one.

A campaign report

Name, status badge, sent time, a one-line preview of the default locale's copy, and Download events CSV — see Export.

While the status is sending the page polls every few seconds; the counters move as the workers report.

Stat tiles

TileDefinition
SentPushes the transport accepted. Underneath: how many were held back by a delivery rule.
DeliveredDevices that reported delivered via the SDK. Underneath: delivery rate = delivered / sent.
Opens (open rate)opened / delivered — not / sent. A push that never arrived cannot be opened; dividing by sent understates every campaign.
Clicks (click rate)clicked / delivered. clicked means an action button; a tap on the body is opened.

Funnel

Sent → delivered → opened → clicked as bars, with the count and the rate against the previous stage. A line under it counts failures.

Hourly

Events per hour in UTC across the campaign's life. Sends cluster in the first minutes; deliveries trail as devices come online; opens spread over hours. For a user's local time campaign the send line is spread across the day, one bump per timezone.

A/B test table

An A/B test report

One row per variant: sent, delivered (+ rate), open rate, click rate. The row marked winner is the one you picked. The header says how much of the audience was in the test (sampleRate) and, if a remainder was held back, offers Send to the rest — one click sends the winning copy to exactly the subscribers who were not in the sample, as a new campaign linked from here. Details in A/B testing.

Failure reasons

The transport's own codes, counted:

CodePlatformPermanent?Meaning
Unregistered, BadDeviceToken, DeviceTokenNotForTopiciOSToken dead or for another app. Subscription invalidated.
UNREGISTERED, SENDER_ID_MISMATCH, INVALID_ARGUMENTAndroidToken dead / belongs to another Firebase project. Invalidated.
404, 410WebSubscription gone. Invalidated.
413WebPayload over 4 KB for that endpoint.
ServiceUnavailable, TooManyRequests, UNAVAILABLE, INTERNAL, 429, 503anyRetried up to PUSH_MAX_ATTEMPTS with backoff; counted here only if all attempts failed.
InvalidProviderToken, PERMISSION_DENIED, TopicDisallowedanycredentialYour key/service account is wrong. Whole platform fails at once — re-check Credentials.

Skip reasons

quiet_hours and frequency_cap counts. With quiet hours set to delay rather than skip, deferred pushes are not skips; they show up as sends later in the hourly chart.

Platform breakdown

Sent / delivered / opened / clicked / failed / skipped and open rate per platform. iOS delivery tracking needs the Notification Service Extension; without it iOS delivered stays at zero while opened still counts — the tell-tale sign of a missing NSE.

Export

Download events CSV streams every event of the campaign: ts, type, platform, userId, subscriptionId, reason, code, invalidated. Tokens and endpoints are never exported — the projection does not even read them. The download is a route handler on the dashboard server, so the admin token stays server-side.

Users and subscriptions have the same export on their own pages.