Skip to main content

Notification Segmentation

Target notifications to specific user segments with rules-based filtering. Reach the right users with the right message.

Rules-Based Targeting

Filter by user properties and behavior

Built-in Segments

Active, inactive, new users out of the box

Custom Segments

Define reusable segments with complex rules

Composable Filters

Combine AND/OR conditions dynamically

Overview

Segmentation lets you send notifications to specific groups of users instead of broadcasting to everyone. Define segments based on user properties (plan, country, language), behavior (login frequency, feature usage), or custom metadata. Segments can be saved and reused, or defined inline as dynamic filters for one-off sends.

Quick Start

Send a notification to a predefined user segment:

import { platform } from '@/lib/platform'

// Send to a built-in or custom segment
await platform.notifications.sendToSegment({
  segment: 'premium_users',
  title: 'Exclusive Feature',
  body: 'New premium feature available',
  data: {
    featureId: 'advanced-analytics',
    deepLink: '/features/analytics',
  },
})

Segment Rules

Filter users by properties, behavior, and metadata using a rich set of operators:

OperatorDescriptionExample
equalsExact matchfield: "plan", value: "pro"
not_equalsNot equal tofield: "status", value: "banned"
inValue in arrayfield: "plan", value: ["pro", "enterprise"]
not_inValue not in arrayfield: "country", value: ["CN", "RU"]
containsString containsfield: "email", value: "@company.com"
gt / gteGreater than / greater or equalfield: "login_count", value: 10
lt / lteLess than / less or equalfield: "days_since_signup", value: 30
existsField is present and non-nullfield: "phone_number"
before / afterDate comparisonfield: "created_at", value: "2026-01-01"
// Complex filter with AND + OR logic
await platform.notifications.send({
  filter: {
    and: [
      { field: 'plan', operator: 'in', value: ['pro', 'enterprise'] },
      {
        or: [
          { field: 'country', operator: 'equals', value: 'US' },
          { field: 'country', operator: 'equals', value: 'CA' },
          { field: 'country', operator: 'equals', value: 'GB' },
        ],
      },
      { field: 'login_count', operator: 'gte', value: 5 },
      { field: 'email_verified', operator: 'equals', value: true },
    ],
  },
  title: 'Early Access',
  body: 'You have been selected for early access',
})

Nested Logic

Filters support arbitrary nesting of and and or conditions. Each leaf condition operates on a single field.

Built-in Segments

These segments are available out of the box with no configuration required:

All Users

Every registered user in your app

segment: "all_users"

Active Users

Users active in the last 7 days

segment: "active_users"

Inactive Users

Users with no activity in 30+ days

segment: "inactive_users"

New Users

Users who signed up in the last 7 days

segment: "new_users"

Customizable Thresholds

Built-in segment thresholds (e.g., 7-day active window, 30-day inactive window) can be adjusted in your app's notification settings.

Custom Segments

Define reusable segments with complex rules. Custom segments are evaluated at send time, so the user set is always current.

// Define a custom segment
await platform.notifications.createSegment({
  key: 'power_users',
  name: 'Power Users',
  description: 'Paid users with high engagement',
  rules: [
    { field: 'plan', operator: 'in', value: ['pro', 'enterprise'] },
    { field: 'login_count', operator: 'gte', value: 10 },
  ],
})

// Create a segment with nested logic
await platform.notifications.createSegment({
  key: 'engaged_free_users',
  name: 'Engaged Free Users',
  description: 'Free users who are highly active (upgrade candidates)',
  rules: {
    and: [
      { field: 'plan', operator: 'equals', value: 'free' },
      { field: 'login_count', operator: 'gte', value: 20 },
      {
        or: [
          { field: 'feature_usage_count', operator: 'gte', value: 50 },
          { field: 'referral_count', operator: 'gte', value: 3 },
        ],
      },
    ],
  },
})

Dynamic Templates

Use template variables to personalize notifications per user within a segment:

// Send personalized content to a segment
await platform.notifications.sendToSegment({
  segment: 'active_users',
  title: 'Hi {{user.name}}, check this out',
  body: 'You have {{user.unread_count}} unread messages',
  data: {
    userId: '{{user.id}}',
  },
})

// Template variables are resolved per-user at delivery time:
// - {{user.name}}       -> User's display name
// - {{user.email}}      -> User's email
// - {{user.id}}         -> User's ID
// - {{user.metadata.*}} -> Custom user metadata fields
// - {{user.*}}          -> Any user profile field

Template Safety

If a template variable cannot be resolved for a user (e.g., missing metadata field), it is replaced with an empty string. The notification is still delivered.

Best Practices

Preview Before Sending

Always use previewSegment() to check the audience size before sending to large segments.

Keep Segments Focused

Smaller, well-defined segments perform better than broad ones. Target specific behaviors.

Use Tags for Metadata

Store segmentation-relevant data as user metadata tags for flexible filtering.

Combine with Scheduling

Pair segments with scheduled delivery for campaigns like "Send to inactive users every Monday at 10 AM".

Layer Segments

Use a named segment as a base and add inline filters for one-off variations without creating new segments.

Clean Up Unused Segments

Delete segments that are no longer referenced to keep your segment list manageable.

API Reference

notifications.sendToSegment()

PropertyTypeDescription
segmentrequiredstringNamed segment key (built-in or custom)
titlerequiredstringNotification title (supports {{template}} variables)
bodyrequiredstringNotification body (supports {{template}} variables)
filterFilterExpressionAdditional filter applied on top of the segment
dataRecord<string, unknown>Custom payload attached to each notification
channel"push" | "email" | "in_app" | "sms"= "push"Delivery channel

notifications.send() with filter

PropertyTypeDescription
filterrequiredFilterExpressionDynamic filter to select target users
titlerequiredstringNotification title
bodyrequiredstringNotification body content
dataRecord<string, unknown>Custom payload attached to each notification
channel"push" | "email" | "in_app" | "sms"= "push"Delivery channel

notifications.createSegment()

PropertyTypeDescription
keyrequiredstringUnique identifier for the segment (lowercase, underscores)
namerequiredstringHuman-readable segment name
descriptionstringOptional description of the segment purpose
rulesrequiredRule[] | FilterExpressionArray of rule conditions or a nested FilterExpression with and/or logic

FilterExpression

PropertyTypeDescription
andArray<Rule | FilterExpression>All conditions must match
orArray<Rule | FilterExpression>At least one condition must match
fieldstringUser property or metadata field to evaluate (leaf rule)
operatorstringComparison operator: equals, not_equals, in, not_in, contains, gt, gte, lt, lte, exists, before, after
valuestring | number | boolean | string[]Value to compare against (not required for "exists" operator)

Management Methods

MethodDescription
notifications.sendToSegment(opts)Send a notification to a named segment
notifications.send(opts)Send with a dynamic inline filter
notifications.createSegment(opts)Create a reusable custom segment
notifications.updateSegment(key, opts)Update segment rules or metadata
notifications.deleteSegment(key)Delete a custom segment
notifications.listSegments()List all segments with user counts
notifications.previewSegment(key)Preview segment size and sample users before sending