Targeting

Send to everyone, specific users, tags or segments, and understand read-time audience evaluation.

Every notification has an audience. There are four types; tags and segment need the Growth plan and up (see plan features).

Everyone

{ "audience": { "type": "all" } }

Every user of the project, including users who sign up after you sent it (as long as the notification is still inside your plan's retention window and not expired).

Specific users

{ "audience": { "type": "users", "userIds": ["user_123", "user_456"] } }
  • 1 to 1,000 of your user ids per notification. Duplicates are ignored.
  • Users who never opened the SDK are created as empty placeholder project users, so they see the notification on their first visit.
  • The recipients are fixed when you send. For more than 1,000 users, or an audience that should follow your users' current profiles, use tags or segments.
  • When you read the notification back, its audience only has the count: { "type": "users", "count": 2 }.

Use it for transactional notifications: "Your export is ready", "Ada mentioned you".

Tags

{ "audience": { "type": "tags", "tags": ["beta", "admin"], "match": "any" } }
  • 1 to 20 tags. match is any (default: the user has at least one of the tags) or all (the user has every tag).
  • Tags match case-insensitively (Beta matches beta), like tag conditions in segments and the GET /v1/project-users?tag= filter.
  • Tags are set only from your backend: PUT /v1/project-users/{userId} with tags replaces the list, POST /v1/project-users/{userId}/tags adds and removes. The SDK can't set tags, so users can't add themselves to a tag audience.
curl -X POST https://api.notificationstream.com/v1/project-users/user_123/tags \
  -H "Authorization: Bearer $NOTIFICATIONSTREAM_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "add": ["beta"], "remove": ["trial"] }'

Tags may contain letters, digits, _, -, : and . (1 to 64 characters), so namespaced tags like team:42 or plan.pro work.

Segments

{ "audience": { "type": "segment", "segmentId": "seg_9QwErTy0uIoP1aSdFgHj" } }

A saved condition tree over profile fields, attributes and tags. The segment must exist when you send (otherwise 400 bad_request). See Segments.

Read-time evaluation

all, tags and segment notifications have no fixed list of recipients. Whether a user sees one is decided each time their feed loads, against their profile at that moment:

  • users who sign up, get a tag or start matching a segment after you sent the notification will see it too (if it's still within retention and not expired);
  • users who lose a tag or stop matching a segment stop seeing it, even if they had read it;
  • editing a segment changes the audience of every notification that targets it;
  • deleting a segment makes its notifications match nobody.

If you need a fixed list of recipients at send time, use a users audience.

Note

A broadcast is one API call however large its audience, and server API calls don't count towards your plan's monthly requests. A broadcast can reach users up to about 30 seconds later than a users notification. See Polling, realtime and performance.

Feed limits

A feed considers at most the newest 500 live (published, not expired or canceled) broadcasts of the project (all, tags and segment). In practice this only matters for projects that send many narrowly targeted broadcasts: if a user matches only a few of them, older matches beyond the newest 500 broadcasts drop out of their feed. Notifications sent directly to the user have no such limit: the whole retention window can be paged through.

Examples

Announce a feature to beta testers in English and German:

{
  "audience": { "type": "tags", "tags": ["beta"] },
  "contents": {
    "en": { "title": "Dark mode is here", "actionLabel": "Try it" },
    "de": { "title": "Der Dark Mode ist da", "actionLabel": "Ausprobieren" }
  },
  "category": "product",
  "actionUrl": "/settings/appearance"
}

Tell admins of every Pro organization about a billing change, using a segment:

{
  "audience": { "type": "segment", "segmentId": "seg_7KdP2xQm9LwT4vNb1RaZ" },
  "contents": { "en": { "title": "Invoices are moving to a new billing portal" } },
  "category": "billing"
}