Delivery Receipts
Track notification delivery, opens, clicks, and dismissals in real time. Per-message stats, individual receipts, action stats, device history, app-wide stats, webhooks.
Track notification delivery, opens, clicks, and dismissals in real-time.
Receipt Statuses#
| Status | Description |
|---|---|
| sent | Message handed to the transport (APNs, Web Push, the Abrova connection or FCM) |
| delivered | Confirmed delivery to device |
| opened | User opened/viewed the notification |
| clicked | User tapped an action button |
| dismissed | User dismissed the notification |
| failed | Delivery failed (invalid token, etc.) |
APNs confirms only that Apple accepted a notification, never that it arrived, so
iOS devices stay at sent until you add a Notification Service Extension. It is
optional and takes a few minutes — see
iOS Delivery Confirmation. Notifications shown
while the app is in the foreground, tapped, or received over the real-time
connection are confirmed by the app itself. Android and Web confirm delivery on
their own, with no extra setup.
Per-device receipts are created for every send: to a user, a device, a list of devices, a topic, a segment, or a broadcast. Each targeted device gets one.
The Delivery page in the Abrova Console shows sent, delivered and failed counts per platform, with the most common failure reasons, and a filterable receipt log.
Transports#
Which path carried a notification. Every receipt records one.
| Transport | Description |
|---|---|
| apns | Apple Push Notification service (iOS) |
| voip | PushKit VoIP push (iOS calling apps) |
| webpush | Web Push (browsers) |
| pn | The Abrova connection (Android) |
| fcm | Firebase, when the optional [Android FCM bridge](/docs/push/android-fcm) is set up |
With the FCM bridge on, a push travels over both Android paths. deliveredVia then says which copy the device received first, pn or fcm.
Get Message Stats#
Aggregate delivery / open / click rates for a single message.
curl -X GET "https://push-api.abrova.ir/receipts/message/msg_abc123/stats" \ -H "x-api-key: ab_live_your_api_key" \ -H "x-server-secret: ab_srv_your_server_secret"
Response
{
"total": 1000,
"sent": 980,
"delivered": 950,
"opened": 450,
"clicked": 120,
"failed": 20,
"deliveryRate": 96.94,
"openRate": 47.37,
"clickRate": 12.63
}Get Individual Receipts#
Per-device receipt for a single message — includes timestamps for each lifecycle stage and the action button tapped.
curl -X GET "https://push-api.abrova.ir/receipts/message/msg_abc123" \ -H "x-api-key: ab_live_your_api_key" \ -H "x-server-secret: ab_srv_your_server_secret"
Response
Returns an array of receipts, newest first.
[
{
"id": "rcpt_1",
"messageId": "msg_abc123",
"deviceId": "dev_xyz",
"platform": "ios",
"status": "clicked",
"sentAt": "2024-01-15T10:00:00Z",
"deliveredAt": "2024-01-15T10:00:01Z",
"openedAt": "2024-01-15T10:05:00Z",
"clickedAt": "2024-01-15T10:05:30Z",
"actionId": "shop_now"
},
{
"id": "rcpt_2",
"messageId": "msg_abc123",
"deviceId": "dev_abc",
"platform": "android",
"status": "failed",
"sentAt": "2024-01-15T10:00:00Z",
"error": "InvalidRegistration"
}
]Get Action Stats#
See which action buttons users clicked most.
curl -X GET "https://push-api.abrova.ir/receipts/message/msg_abc123/actions" \ -H "x-api-key: ab_live_your_api_key" \ -H "x-server-secret: ab_srv_your_server_secret"
Response
[
{ "actionId": "shop_now", "count": "85" },
{ "actionId": "remind_later", "count": "35" }
]count is returned as a string.
Get Device Receipts#
Receipt history for a specific device, newest first. limit defaults to 50. Each receipt includes its parent message object (title, body, ...).
curl -X GET "https://push-api.abrova.ir/receipts/device/dev_xyz?limit=20" \ -H "x-api-key: ab_live_your_api_key" \ -H "x-server-secret: ab_srv_your_server_secret"
Response
[
{
"id": "rcpt_1",
"messageId": "msg_abc123",
"deviceId": "dev_xyz",
"status": "opened",
"sentAt": "2024-01-15T10:00:00Z",
"openedAt": "2024-01-15T10:05:00Z",
"message": { "id": "msg_abc123", "title": "New message", "body": "..." }
},
{
"id": "rcpt_2",
"messageId": "msg_def456",
"deviceId": "dev_xyz",
"status": "clicked",
"sentAt": "2024-01-14T15:30:00Z",
"clickedAt": "2024-01-14T15:32:00Z",
"actionId": "view_order",
"message": { "id": "msg_def456", "title": "Order update", "body": "..." }
}
]Get App-wide Stats#
Aggregate stats across the app that owns your API key, for a date range. Without startDate/endDate it covers the last 30 days. deliveryRate here is delivered / totalRecipients.
curl -X GET "https://push-api.abrova.ir/receipts/stats?startDate=2024-01-01&endDate=2024-01-31" \ -H "x-api-key: ab_live_your_api_key" \ -H "x-server-secret: ab_srv_your_server_secret"
Response
{
"totalMessages": 150,
"totalRecipients": 45000,
"delivered": 43500,
"opened": 18000,
"clicked": 4500,
"failed": 1500,
"deliveryRate": 96.67,
"openRate": 41.38,
"clickRate": 10.34
}SDK Integration#
Receipts are tracked automatically by the SDKs. The only manual hook is on iOS: if the SDK is not your UNUserNotificationCenter delegate, call AbrovaPush.shared.handleRemoteNotification(userInfo:) from application(_:didReceiveRemoteNotification:fetchCompletionHandler:). Each message is confirmed once per device, and redeliveries are not counted twice. Ensure you have the latest version installed:
| Platform | What confirms delivery |
|---|---|
| Android | The SDK, for every notification the device receives |
| iOS | The SDK for foreground, tapped and real-time messages; a Notification Service Extension for background APNs notifications |
| Web | The service worker for Web Push, and the SDK for messages received while the page is open |
Webhooks for Receipts#
When a device confirms delivery, a message.delivered webhook fires:
{
"event": "message.delivered",
"timestamp": "2024-01-15T10:00:01Z",
"webhookId": "wh_123",
"data": {
"messageId": "msg_abc123",
"deviceId": "dev_xyz",
"title": "New message"
}
}Available Webhook Events
message.sent— Message sentmessage.delivered— A device confirmed deliverymessage.failed— Delivery failedmessage.no_recipients— The target had no registered devicesdevice.registered,device.unregistered,device.updated— Device lifecycle
Opens, clicks and dismissals are recorded on the receipt but do not fire webhooks.