Skip to content

Segments

A segment is a named, reusable predicate over the evaluation context. You define it once and reference it from any number of flag or config rules.

beta_testers = (
     plan = "enterprise"
  OR email ENDS_WITH "@example.com"
  OR userId IN ["u_42", "u_99", "u_123"]
)

Now any rule can say if user matches segment "beta_testers", return true. Update beta_testers in one place and every rule that references it immediately reflects the change.

Why segments

Without segments, the same predicate gets duplicated across every flag rule that needs it. The duplication has two costs: editing it requires touching every copy, and reading any individual rule becomes harder because the intent (this is the beta cohort) is buried in the implementation (these specific conditions).

Segments capture the intent as a first-class object. Rules read more like prose:

if user matches "beta_testers" → variant "new"
otherwise → variant "classic"

Anatomy of a segment

A segment carries three pieces of state:

  • Rules — a list of conditions. A user matches the segment if any rule's condition tree matches their context.
  • Allow list — explicit target IDs (typically user IDs) that always match, regardless of rules. Used for "always include person X" overrides.
  • Deny list — explicit target IDs that never match, regardless of rules. Used for "always exclude person X" overrides.

Membership semantics: allowList ∪ (matched-by-rules) \ denyList. Deny wins over both sources.

Segments do not have a "default value" — they're predicates, not values. A rule referencing a segment matches the user (or doesn't); what value the rule then returns is the rule's responsibility.

Project scope vs. environment scope

Like flags and configs, segments split identity from state:

  • Project-scope — key and description.
  • Environment-scope — rules, allow list, deny list. Per environment.

The same segment key can have a tighter rule set in production (e.g. only specific opted-in beta users) and a looser one in staging (any user who matches an email pattern).

Referencing a segment from a rule

Inside a rule's condition tree, use the $segment operator:

json
{
  "$segment": "beta_testers"
}

The segment is resolved from the same environment's segments. A rule can reference any number of segments and combine them with $and, $or, $not, and field-level operators (equals, in, matches, etc.). See Rules and contexts for the full operator catalog.

Reference checks before deletion

Deleting a segment that's referenced by a flag or config returns 409 in_use with the referrers listed under fields. The dashboard surfaces these so you can clear the references before retrying. There's also an explicit endpoint:

http
GET /api/v1/envs/{envId}/segments/{key}/references

…that lists every flag, config, or other segment whose rules name this segment. Useful as a pre-flight before a destructive change.

See also