PlunkPlunk
Concepts

Segments

Group and target your contacts with dynamic or static segments

Segments let you create named groups of contacts that can be targeted in campaigns and used as triggers in workflows. There are two types: Dynamic and Static.

Dynamic vs Static

DynamicStatic
MembershipComputed from filter conditions in real timeManually curated — you decide who is in
condition fieldRequired — describes the filtersMust be omitted
Add/remove members via APINot allowed (the filter decides)POST / DELETE /segments/:id/members
Membership recomputationRe-evaluated in the background when trackedN/A — membership only changes when you call the API
Entry/exit eventsFired only when Track membership changes is enabledNot fired by add/remove API calls
Updating the filterMember count is recomputedcondition is silently ignored on update

Use dynamic segments for behavioural targeting ("subscribed users on the Pro plan who opened any email in the last 14 days"). Use static segments for one-off curated lists like beta testers, conference attendees, or contacts imported from an external system.

Filtering on a dynamic segment

A dynamic segment's membership is defined by a filter — a set of conditions evaluated against your contacts. You can filter on:

  • Built-in contact fields: email, subscribed, createdAt, updatedAt.
  • Custom fields you've stored on contacts (anything under data.*).
  • Custom events tracked via /v1/track (event.signed_up, event.purchased, etc.).
  • Email engagement (email.opened, email.clicked, email.bounced, etc.).
  • Membership of another segment.

Filters can be combined with AND or OR and nested into groups for more complex audiences — for example "subscribed Pro users and (opened or clicked an email in the last 14 days)".

For the full list of fields, operators, and value types — plus worked examples — see the Segment filter reference.

Static segments

Static segments are manually curated lists. Membership doesn't change automatically — you decide exactly who is in.

Creating

Go to Segments in the dashboard and click Create Segment, then choose Static. You can optionally add initial members straight away using the contact search.

Adding and removing members

Open a static segment and use the Add Members search to find contacts. The search looks up contacts already in your project, so you can't accidentally add someone who doesn't exist. Contacts already in the segment are greyed out.

Programmatically, use:

  • POST /segments/:id/members — add contacts by email. Body: { emails: string[], createMissing?: boolean, subscribed?: boolean }. With createMissing: true, contacts that don't exist yet are created (and start subscribed unless you pass subscribed: false). The response reports { added, created, notFound }.
  • DELETE /segments/:id/members — remove contacts by email. Body: { emails: string[] }. Returns { removed }.

Both endpoints only accept static segments. Calling them on a dynamic segment returns 400.

Membership changes via these API calls are immediate but do not fire entry/exit events — those are reserved for dynamic, tracked segments.

Tracking membership changes

Dynamic segments can opt into Track membership changes. When enabled, Plunk fires events whenever a contact enters or leaves the segment:

  • segment.<slug>.entry — contact joined
  • segment.<slug>.exit — contact left

The <slug> is derived from the segment name: lowercased, accents and punctuation stripped, whitespace replaced with hyphens, repeated hyphens collapsed. "VIP Customers" becomes segment.vip-customers.entry. Pick segment names that produce stable slugs — renaming a segment changes the event name.

Use these events to drive workflows (welcome a contact when they enter a "Trial users" segment, send a re-engagement email when they exit "Active users", etc.). See Webhooks for the payload format.

How tracking works

The member count updates immediately when you create or change a dynamic segment's filter. After that, Plunk recomputes membership in the background on a regular cadence — diffing current matches against the previous set, recording entries and exits, and emitting the corresponding events.

Because of this background cadence, the memberCount shown in the dashboard can lag the live state by a few minutes. If you need a fresh value or want to drive a workflow off entry / exit immediately:

  • POST /segments/:id/refresh — force a count refresh (cheap, no events).
  • POST /segments/:id/compute — force a full membership recomputation, which fires any pending entry/exit events.

Using segments

Segments can be used to:

Performance notes

  • Date filters on data.* rely on ISO 8601 string ordering — store dates as ISO 8601 strings (2026-05-06T12:00:00Z) rather than Unix timestamps if you want to use within / olderThan on them.
  • Nesting many untracked dynamic segments inside one another increases evaluation cost. If a segment is referenced by others, enable Track membership on it so its members are looked up directly instead of recomputed each time.
  • The cached memberCount may be a few minutes behind reality. Treat it as approximate; use POST /segments/:id/refresh to force a refresh if you need an exact count.

Deleting a segment

Deleting a segment that's referenced by an active campaign (in DRAFT, SCHEDULED, or SENDING state) returns 409 Conflict. Cancel the campaign or pick a different audience first.

API reference

See the segments API endpoints in the API overview — list, get, create, update, delete, list members, add/remove static members, refresh count, and compute membership.

What's next