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:
| Operator | Description | Example |
|---|---|---|
| equals | Exact match | field: "plan", value: "pro" |
| not_equals | Not equal to | field: "status", value: "banned" |
| in | Value in array | field: "plan", value: ["pro", "enterprise"] |
| not_in | Value not in array | field: "country", value: ["CN", "RU"] |
| contains | String contains | field: "email", value: "@company.com" |
| gt / gte | Greater than / greater or equal | field: "login_count", value: 10 |
| lt / lte | Less than / less or equal | field: "days_since_signup", value: 30 |
| exists | Field is present and non-null | field: "phone_number" |
| before / after | Date comparison | field: "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
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
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 fieldTemplate Safety
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()
| Property | Type | Description |
|---|---|---|
segmentrequired | string | Named segment key (built-in or custom) |
titlerequired | string | Notification title (supports {{template}} variables) |
bodyrequired | string | Notification body (supports {{template}} variables) |
filter | FilterExpression | Additional filter applied on top of the segment |
data | Record<string, unknown> | Custom payload attached to each notification |
channel | "push" | "email" | "in_app" | "sms"= "push" | Delivery channel |
notifications.send() with filter
| Property | Type | Description |
|---|---|---|
filterrequired | FilterExpression | Dynamic filter to select target users |
titlerequired | string | Notification title |
bodyrequired | string | Notification body content |
data | Record<string, unknown> | Custom payload attached to each notification |
channel | "push" | "email" | "in_app" | "sms"= "push" | Delivery channel |
notifications.createSegment()
| Property | Type | Description |
|---|---|---|
keyrequired | string | Unique identifier for the segment (lowercase, underscores) |
namerequired | string | Human-readable segment name |
description | string | Optional description of the segment purpose |
rulesrequired | Rule[] | FilterExpression | Array of rule conditions or a nested FilterExpression with and/or logic |
FilterExpression
| Property | Type | Description |
|---|---|---|
and | Array<Rule | FilterExpression> | All conditions must match |
or | Array<Rule | FilterExpression> | At least one condition must match |
field | string | User property or metadata field to evaluate (leaf rule) |
operator | string | Comparison operator: equals, not_equals, in, not_in, contains, gt, gte, lt, lte, exists, before, after |
value | string | number | boolean | string[] | Value to compare against (not required for "exists" operator) |
Management Methods
| Method | Description |
|---|---|
| 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 |