Docs
Dashboard
HoneyNotify SDKs

Choose your platform

Choose a ready-made website integration or open an SDK repository.

WordPressReady-made installable Web Push pluginMagento, Drupal & JoomlaReady-made Web Push modules and pluginsAndroidKotlin and Firebase Cloud MessagingiOSSwift and Apple Push Notification serviceFlutterDart with native APNs and Firebase Messaging tokensReact NativeJavaScript and TypeScript with React Native FirebaseWebBrowser push and service worker support
Engagement

Events and analytics

Events connect provider delivery with recipient behaviour. SDKs can report notification lifecycle events, your application can report business events, and outcomes can attach numeric value to a conversion.

Submit an event#

POST /v1/events
{
  "event_type": "opened",
  "notification_id": "b39ddcd7-2892-4c3d-8145-0ce3bc9e3ec4",
  "device_id": "0e83059e-715d-45b8-911b-30d36519c863",
  "occurred_at": "2026-09-16T14:22:08Z",
  "metadata": {
    "action_id": "view_order"
  }
}

Accepted event types are:

Event Use it when
received Client code receives the provider payload
confirmed_delivered Client confirms device-side delivery
opened User opens the notification
clicked User chooses a notification action
dismissed Client/platform can reliably report dismissal
custom A named application event occurs
outcome A named conversion or value occurs

custom and outcome require event_name of up to 120 characters. notification_id and device_id are optional UUIDs, but when present they must belong to the authenticated app.

The response is 202 Accepted:

{"accepted":true}

Custom events#

Use custom events for meaningful product behaviour, not every UI interaction. They can drive segment membership and start event-triggered journeys.

{
  "event_type": "custom",
  "event_name": "checkout.abandoned",
  "device_id": "0e83059e-715d-45b8-911b-30d36519c863",
  "metadata": {
    "basket_id": "basket_441",
    "currency": "GBP"
  }
}

Event names may be used in segment fields such as custom_event.checkout.abandoned. Establish a consistent naming convention before integrating several clients.

Outcomes and value#

Outcome events measure conversions. Put an optional numeric amount in metadata.value.

{
  "event_type": "outcome",
  "event_name": "purchase",
  "notification_id": "b39ddcd7-2892-4c3d-8145-0ce3bc9e3ec4",
  "device_id": "0e83059e-715d-45b8-911b-30d36519c863",
  "metadata": {
    "value": 49.95,
    "currency": "GBP"
  }
}

An outcome with a notification ID is recorded as direct; one without it is unattributed. HoneyNotify aggregates the numeric value but does not perform currency conversion, so do not combine different currencies under one outcome name unless your application normalises them first.

Event timing and duplication#

If occurred_at is omitted, the API uses the current time. Prefer the real client occurrence time for offline or delayed uploads.

The event endpoint is not idempotent. Avoid double submission in client callbacks, and use your application state to deduplicate revenue outcomes when that matters to reporting.

HoneyNotify's engagement rates count a device at most once for each notification and event type. Repeated opened or clicked callbacks remain visible in the event history, but they do not inflate the unique open or click rates.

Notification event history#

GET /v1/notifications/{notification_id}/events?page=1&limit=50

This returns a paginated event stream scoped to one notification, including each event's source, properties, and occurrence time.

Aggregate analytics#

GET /v1/analytics?days=30

days is clamped between 1 and 365 and defaults to 30. The response contains a notification-cohort summary, daily activity, platform and notification breakdowns, the existing raw daily metrics, and outcomes grouped by name and attribution.

{
  "summary": {
    "notifications": 4,
    "sent": 2000,
    "accepted": 1940,
    "failed": 60,
    "confirmed_delivered": 1810,
    "received": 1832,
    "opened": 522,
    "clicked": 91,
    "dismissed": 38,
    "delivery_rate": 97,
    "confirmed_delivery_rate": 93.2989690722,
    "open_rate": 26.9072164948,
    "click_through_rate": 4.6907216495,
    "click_to_open_rate": 17.4329501916
  },
  "daily": [
    {"day":"2026-09-15","sent":420,"accepted":405,"opened":104,"clicked":18}
  ],
  "platforms": [
    {"platform":"ios","sent":1100,"accepted":1072,"confirmed_delivered":1011,"opened":318,"open_rate":29.6641791045}
  ],
  "campaigns": [
    {"notification_id":"b39ddcd7-2892-4c3d-8145-0ce3bc9e3ec4","title":"Saved items","sent":800,"accepted":774,"opened":246,"open_rate":31.7829457364}
  ],
  "metrics": [
    {"metric_date":"2026-09-15","event_type":"opened","platform":"ios","total":184}
  ],
  "outcomes": [
    {"name":"purchase","attribution":"direct","total":12,"value":"748.40"}
  ],
  "days": 30
}

The summary and notification breakdown use notifications created within the selected period. Daily send counts use the notification creation day, while daily engagement counts use the day on which each event occurred; the daily series therefore provides activity trends rather than daily rates. delivery_rate is accepted divided by recipients, confirmed_delivery_rate is confirmed delivered divided by accepted, open_rate is unique opened recipients divided by accepted, click_through_rate is unique clicked recipients divided by accepted, and click_to_open_rate is unique clicked recipients divided by unique opened recipients.

Provider acceptance, SDK-confirmed delivery, and user engagement answer different questions. Report them separately rather than labelling all provider-accepted sends as delivered. A zero confirmed-delivery or open rate commonly means the corresponding client callbacks have not been integrated; it does not by itself prove delivery failed.

SDK reporting requirements#

The API cannot infer an open from APNs, FCM, or Web Push acceptance. Each application must submit the notification UUID from the HoneyNotify payload:

  • call the SDK received or confirmed-delivery tracking at the point where the client can genuinely observe that state;
  • call the opened helper only from the notification interaction callback, not every app launch; and
  • pass the action identifier so an explicit notification action is recorded as clicked.

The Swift, Kotlin, Flutter, React Native, and web SDK generic track methods preserve confirmed_delivered as a standard lifecycle event. Mobile SDKs also provide received/opened convenience methods; connect them to the correct foreground, background, and notification-tap callbacks without reporting the same callback twice.