Docs
Dashboard
HoneyNotify SDKs

Choose your platform

Select a platform to open its public SDK repository on GitHub.

AndroidKotlin and Firebase Cloud MessagingiOSSwift and Apple Push Notification serviceWebBrowser push and service worker support
Core concepts

Segments and targeting

Segments are reusable audience definitions. HoneyNotify evaluates their filter rules against enabled devices, user attributes, and recorded events.

Create a segment#

POST /v1/segments
{
  "name": "Recently active paid iOS users",
  "description": "Paid iOS users who opened a notification in the last 30 days",
  "filter": {
    "all": [
      {"field": "platform", "operator": "eq", "value": "ios"},
      {"field": "tag.plan", "operator": "eq", "value": "paid"},
      {"field": "event.opened", "operator": "within_days", "value": 30}
    ]
  }
}
{"segment_id":"a7f7b391-15e8-47b9-a123-f1bea3994a82","version":1}

Filter grammar#

A filter is either one condition or one group. A group contains a non-empty all or any array:

  • all requires every child to match;
  • any requires at least one child to match.

Groups can be nested up to five levels, with at most 50 leaf conditions total.

{
  "any": [
    {"field": "locale", "operator": "eq", "value": "en-GB"},
    {
      "all": [
        {"field": "timezone", "operator": "eq", "value": "Europe/London"},
        {"field": "tag.region", "operator": "eq", "value": "uk"}
      ]
    }
  ]
}

Fields#

Field Source
platform Device platform
locale Device locale, falling back to user locale
timezone Device timezone, falling back to user timezone
app_version Registered app version
enabled Device enabled state
created_at Device creation time
last_seen_at Device last-seen time
tag.<key> Value from user tags
event.<type> Standard event such as opened
custom_event.<name> Named custom event

Operators#

General fields accept eq, neq, in, not_in, contains, gt, gte, lt, lte, exists, and not_exists. The in and not_in operators accept between 1 and 100 values.

Event fields accept only exists, not_exists, within_days, and not_within_days. Day windows are integers from 0 to 3650.

Estimate before sending#

Estimate a saved segment:

POST /v1/segments/estimate

{"segment_id":"a7f7b391-15e8-47b9-a123-f1bea3994a82"}

Or estimate an unsaved filter:

{
  "filter": {
    "all": [
      {"field": "platform", "operator": "eq", "value": "android"},
      {"field": "tag.plan", "operator": "in", "value": ["pro", "unlimited"]}
    ]
  }
}

The result is a point-in-time count of enabled, non-invalidated devices. Audience membership can change between estimation and send.

{"estimated_recipients":1842}

Versioning and snapshots#

Creating a segment starts at version 1. Each PATCH creates a new immutable version. When a notification is created, HoneyNotify snapshots the selected version and filter into the notification, so later segment edits do not rewrite the historical audience definition.

GET /v1/segments
GET /v1/segments/{segment_id}
PATCH /v1/segments/{segment_id}
DELETE /v1/segments/{segment_id}

Deleting archives the segment rather than erasing its history.

Include and exclude combinations#

Notification payloads may include up to 50 UUIDs in each of included_segment_ids and excluded_segment_ids. This is useful for rules such as “paid users, except anyone who purchased today.”

{
  "title": "Complete your upgrade",
  "body": "Your saved offer expires tonight.",
  "target": {"type": "segment", "segment_id": "11111111-1111-4111-8111-111111111111"},
  "included_segment_ids": ["11111111-1111-4111-8111-111111111111"],
  "excluded_segment_ids": ["22222222-2222-4222-8222-222222222222"]
}

Every referenced segment is resolved and snapshotted when the notification is created. Use /segments/estimate for the primary filter and a controlled test audience before a large campaign.