name: onesignal-segments
description: Use this skill when the user wants to create or reason about a OneSignal Segment, audience, cohort, targeting group, suppression list, engaged users, inactive / lapsed / dormant users, VIP users, purchasers, message clickers, custom-event audiences, or users matching behavior, attributes, tags, or subscription properties. Triggers on "create a segment", "build an audience", "target users who [behavior]", "find my [adjective] users", "build a suppression list", "exclude users from [message]", or any audience definition request even when the user doesn't say "Segment".
OneSignal Segments Skill
Purpose
Help the agent translate vague audience intent ("engaged users", "VIPs", "lapsed customers") into a precise OneSignal Segment definition that's ready to use in a campaign or Journey.
This is a reasoning guide, not a script. Synthesize questions and options based on what the user said and what your tool calls turn up.
When to Use
Trigger phrases: "create a segment / audience / cohort / targeting group", "build a suppression list", "find users who [opened / clicked / purchased / haven't returned]", "build my engaged-users audience", "exclude users from this campaign", "target VIPs / loyalty members / power users".
Lookalike intents that should NOT trigger this skill:
- A static CSV import or one-time recipient list — that's an Import.
- A dynamic API filter on a single send — set filters directly in the message API.
- A Journey audience question only — load
onesignal-journeys instead.
Key Concepts
A Segment is a live, dynamic audience definition built from filters; it re-evaluates as users change. Two categories:
- Subscription-based segments — filter on subscription attributes (device type, language, app version, country, location, tags, last/first session, session count).
- User-based segments — filter on user-level attributes: message events (opened / clicked / delivered / bounced / failed by channel) and Custom Events (e.g.
purchase).
Filters combine with AND (default) or OR (must be explicit).
Targeting behavior:
- Push, email, SMS only deliver to opted-in Subscriptions.
- In-app messages display to all mobile Subscriptions regardless of opt-in.
- Journeys evaluate Segments at the Subscription level then enter the matching Users.
For the full filter catalog, AND/OR semantics, API support boundaries, and channel-by-channel behavior, read REFERENCE.md.
Decisions That Shape a Segment
Each dimension has a priority tag:
- Purpose (Critical when not implied) — campaign targeting, suppression, analysis, re-engagement, internal cohort. Purpose nudges defaults.
- Signal family (Critical) — message engagement, app/website behavior, user attributes (tags/location/device), or subscription state.
- Specific signals within the family (Critical for behavior-based) — which message event, which Custom Event name, which tag values. Often stack (multi-select).
- Timeframe (Critical for behavior-based, n/a for static) — most behavior segments need a window ("last 7 / 30 / 90 days").
- Combination logic (Often defaultable to AND) — surface explicitly if the user said "any of" / "either" (= OR).
- Include vs exclude (Critical when used in a campaign) — is this the target list or the suppression list?
- Name (Almost always defaultable) — suggest a clear name; avoid "Segment 3".
- Call
list_segments first. If a similar Segment already exists ("VIP", "Engaged Users", a 7-day-inactive cohort), surface it and ask if the user wants to use, duplicate, or modify it instead of creating a new one. - For Custom-Event-based audiences, call
list_custom_events to confirm the event name actually exists. If it doesn't, flag it as a prerequisite. - For tag-based audiences ("VIP tier", "is_premium"), confirm the tag exists by inspecting recent users (the dashboard shows the tags currently set on Subscriptions).
- For channel-engagement audiences, check that the channel is set up via
get_platform_settings — channel-engagement filters are useless if the channel has never delivered messages.
How to Reason About Questions
- Walk Decisions; mark each Specified / Defaultable / Open.
- Ground in tools (above). Many "Open" dimensions become "Specified" or "Defaultable" once you've checked existing data.
- If 0 dimensions are still Open, skip AskUserQuestion entirely. Summarize with assumptions named.
- If 1–4 are Open, bundle into ONE AskUserQuestion call. Phrase questions in user terms ("What should count as engaged?"), not API terms ("Which
event_kind value?"). - Multi-select for stackable signals (engagement signals, inactivity signals, custom event names). Single-select for mutually exclusive choices (signal family, AND vs OR, include vs exclude).
Ambiguity to Watch For
- "engaged" / "most engaged" / "high intent" — usually "interacted with messaging recently". Multiple signals stack; clarify which signals + window.
- "inactive" / "lapsed" / "dormant" / "churn risk" — usually "no expected behavior in N time". Clarify which signal(s) + window.
- "VIP" / "high value" / "loyal" / "power user" — vertical-dependent (ecommerce: revenue + repeat purchase; SaaS: ARR + active seats; media: subscribed + reading frequency; gaming: high score + spend tier). Use page context to infer vertical when possible; otherwise ask.
- "new users" / "first-time users" — clarify against subscription date, first session, or a signup Custom Event.
- "active users" — needs both a signal (session, custom event, message open?) and a window.
- "purchasers" / "buyers" / "customers" — confirm the underlying signal: a
purchase Custom Event, a tag, a revenue threshold. - Tag without value — ask whether the value matters; tag-only Segments often miss intent.
- "unsubscribed" vs "uninstalled" vs "lapsed" — different signals; never conflate.
Defaults & Best Practices
Apply silently and surface as assumptions:
- AND logic unless the user said "any of" / "either".
- Include (not exclude) unless the user said "suppression" / "exclude".
- For channel-engagement Segments, default to OR across stackable signals ("opened OR clicked" counts).
- Behavior Segments without a timeframe default to 30 days; ask if the user might want a shorter window for hotter signals.
Best practices:
- For "VIP", "engaged", or "loyal", offer multiple atomic signals as multi-select rather than guessing one.
- Distinguish include vs exclude up front for any new Segment used in a campaign.
- Avoid PII in tag values or in tag-derived Segment criteria.
- Suggest a descriptive Segment name if the user didn't.
- Watch for "all users" Segments (no filters) — confirm that's truly intended.
For more depth (filter catalog, message-event filter mechanics, Custom Event Early Access limitations, AND/OR examples), read REFERENCE.md. For full reasoning traces (vague request, fully-specified, VIP, channel-not-set-up, push-back), read EXAMPLES.md.
Summary and Approval
Every summary must include:
- Segment name (or suggested name) and purpose.
- Signal family + specific filters in human-readable form.
- Timeframe.
- AND / OR logic.
- Include vs exclude.
- Assumptions — every default applied so the user can correct them.
- Must-mention warnings for this domain:
- Audience counts include both subscribed and unsubscribed Subscriptions for transparency, but only subscribed ones receive push/email/SMS sends. (In-app shows to all mobile Subscriptions regardless.)
- Counts may be exact or estimated — label estimates as such.
- Dashboard-created Segments using message-event or Custom Event filters may not be fully editable via the public Create/Update Segment API.
- Custom Event segmentation is in Early Access: not supported with Email Warm-Up or A/B tests, can't power Journeys, can't combine with other segment filters, and time filters reference event-received time (not original event time — for historical imports, use a tag-based timestamp instead).
Require explicit user approval before creating, updating, or deleting.
Anti-Patterns
Avoid:
- Adding combo options like "Opened AND clicked" — multi-select handles them natively.
- Asking for raw API field names ("Which
event_kind?") instead of user terms ("Which engagement signals?"). - Creating a Segment with no filters unless the user explicitly wants all users.
- Guessing "VIP" / "engaged" / "inactive" without clarifying — they vary too much by vertical.
- Inventing unsupported Segment filters (the public API supports a fixed set; see REFERENCE.md).
- Reproducing this skill's example wording verbatim — write your own questions from the user's prompt.
Supporting Files
REFERENCE.md — full filter catalog, message-event filter behavior, Custom Event segmentation Early Access limits, AND/OR examples, channel-by-channel delivery rules. Read when verifying a constraint.EXAMPLES.md — worked traces (vague request, fully-specified, VIP for various verticals, channel-not-set-up, user-pushes-back, skip-AskUserQuestion-entirely).