Reporting
There are two ways to get data on the performance of your ContextPush integration:
- We will prepare reports on measured open rates for all running campaigns and share them with you on a regular basis.
- You can integrate with our Webhook solution to track performance on your end, see next section.
Webhooks
To get started with ContextPush webhooks reach out to us under support@contextsdk.com and provide us with a URL where we should push the webhook events to.
For the intial setup you only need to share a secret with us that can be used to verify that the webhooks are coming from our service.
Format
The webhook request will be sent to you in the following format:
POST /your_webhook_endpoint HTTP/1.1
Host: your.host
X-ctx-secret: your_shared_secret
Content-Type: application/json
[
{
"device_token": "push_token",
"user_id": "your_user_id",
"campaign_id": "your_campaign_id",
"idempotency_key": "idempotency_key",
"delivery_status": "opened",
"delivery_method": "context_aware",
"planned_delivery_method": "context_aware",
"timestamp": "2025-02-07T15:20:40.599Z",
"content": {
"title": "James, it's time for your English course! 👑",
"body": "Start your English course now!"
}
},
...
]
Each request can contain multiple entries, the maximum being 100.
To illustrate the format here is the TypeScript type definition:
export type Webhook = {
device_token: string | undefined; // Will be undefined when the delivery_status is cancelled.
user_id: string;
campaign_id: string;
idempotency_key: string;
delivery_status: 'failed' | 'cancelled' | 'opened' | 'delivered' | 'pending';
delivery_method: 'context_aware' | 'traditional' | 'cancelled';
planned_delivery_method: 'context_aware' | 'traditional';
timestamp: string; // ISO 8601 Timestamp
content: MessageContent; // See the web request documentation for possible content options. Content will be copied here 1:1 from what is supplied in the request.
};
Your secret will be sent in the X-ctx-secret
header and should be verified by you before processing the request.
Attaching Extra Information
Since the full content when scheduling the notification is echoed back to you you can use the content.userInfo
property to attach any data you might require during later processing. Simply set it when scheduling the notification.
Explanation of Delivery Status
pending
- This notification has not been sent yet, the user has not seen this notification.delivered
- The APNS servers confirmed that they successfully accepted the request to send the notification, and it most likely was shown to the user. ContextPush currently does not implement confirmed deliveries using aUNNotificationServiceExtension
.opened
- The user has clicked on this notification.cancelled
- A request was sent to cancel this notification from being delivered, this status guarantees that the user will not have seen this notification.failed
- The notification could not be sent because thedevice_token
was no longer valid.
Explanation of Delivery Methods
context_aware
- This notification was delivered using ContextPush as a context-aware notification, in a good moment.traditional
- This notification was delivered as a traditional push notification, without considering the users real-world context.
Identifying a Single Message
Depending on if you care about delivery per user, or per device to uniquely define a single message the combination of: idempotency_key
, campaign_id
, user_id
and optionally device_token
will be unique. Consider that after 30 days messages are deleted from our system so the key may be reused at that time.
Other Implementation Notes
Due to the nature of distributed systems we can only guarantee at-least-once delivery of the final state change, you might not receive all intermediary state changes, and we cannot guarantee the order e.g. you might receive a delivered
event after an opened
event for the same message, and even the same device.
ContextPush will retry delivery of failed webhooks up to 10 times over a 2h window, after that they are dropped.