---
title: Segments · BuzzKit
description: Saved expressions over attributes and events, evaluated fresh at send time.
canonical: https://buzzkit.dev/features/segments
last-updated: 2026-09-02
---

# Who they are and what they did. Evaluated the moment you send.

A segment is a saved, versioned expression: attributes, events and how often, last activity on a device, and which channels can reach them. It is never stored as a member list, so every send reads the audience as it is right now.

## One grammar for every condition

Conditions nest in all, any and not groups. Attributes compare with equals, not equals, greater and less than, in, contains and exists; events count inside a window or never happened; activity and channel cover the rest.

```
{
  "all": [
    { "ref": "attributes.plan", "eq": "pro" },
    {
      "count": "workout.completed",
      "within": "7d",
      "gte": 3
    },
    { "lastSeen": { "within": "30d" } },
    { "channel": "push" }
  ]
}
```

## Preview before you save

The preview endpoint answers with how many subscribers match right now and the first twenty of them, without saving anything. The dashboard builder calls it as you type.

```
POST /v1/segments/preview
{
  "expression": {
    "count": "workout.completed",
    "within": "7d",
    "gte": 3
  }
}

{ "count": 1284, "sample": [ … ] }
```

## Versioned, and pinned on send

Changing an expression creates a new version, and a message pins the version it used. An edit never changes who an in-flight message reaches, and every message explains its audience.

```
POST /v1/messages
{
  "segment": "active-pro",
  "title": "Three evening slots opened up",
  "body": "Book before Maya’s class fills."
}

// The message remembers exactly who it went to
{
  "id": "msg_7g2h",
  "targets": {
    "segment": "active-pro",
    "segmentVersion": 4
  },
  "counts": { "total": 1284, "sent": 1279 }
}
```

## Capabilities

- **Event windows.** Count an event within minutes, hours or days, or its absence.
- **System attributes.** Country, timezone, language, app version and push permission, set from the device.
- **Fresh within seconds.** One query over the event stream, as fresh as the last event.
- **Inline on a send.** Write the expression on the message for a one-off audience.
- **Shared with workflows.** Triggers, branches and schedules read the same grammar.
- **Typed in the SDK.** Types and lint ship in the buzzkit package, before the request.

## Questions

### How fresh is a segment when I send to it?

Membership is evaluated at send time against the event stream, usually within seconds of the last event. Nothing is cached as a list.

### Can a segment filter on event data, not just the event name?

Today a segment counts events by name inside a window. Event data is stored as a queryable column, and predicates on it are the next step of the grammar.

### How large can an expression be?

Groups nest up to eight levels deep with at most fifty conditions, and an in condition takes up to a hundred values. The lint names the node when a limit is crossed.

## Related

- [Sending](https://buzzkit.dev/features/sending.md): One POST sends to a subscriber, a topic or a segment and lands on every device.
- [Workflows](https://buzzkit.dev/features/workflows.md): Event-triggered automation with waits, branches and sends, run per subscriber.
- [Topics & Preferences](https://buzzkit.dev/features/topics.md): Named notification categories with per-topic, per-channel choices for every subscriber.

## Start

- [Start sending](https://buzzkit.dev/dashboard)
- [API Reference](https://docs.buzzkit.dev)
- [BuzzKit on GitHub](https://github.com/buzzkit-dev/buzzkit)
