---
title: "@playstack/audiences"
description: "Local-authoritative lists, consent evidence, subscriptions, signed preference flows, tags, and data-only segments."
tags: ["package","communication","audiences","consent","segments","pro"]
---

{/* package-access:start */}

> **Pro.** Covered by the Playstack Pro License. Registry access is required; check preview availability before installing. See [package access](/docs/packages#access-policy).

{/* package-access:end */}

`@playstack/audiences` owns the durable meaning of an audience: lists, subscribers, per-list subscription edges, append-only consent evidence, tags, and versioned segment definitions. It resolves recipients; it never composes or sends a campaign.

## Install

```sh
npm install @playstack/audiences @playstack/delivery @playstack/events
```

## Compose and subscribe

```ts
import { createAudiences } from '@playstack/audiences'

const audiences = createAudiences({
  persistence,
  suppression: delivery,
  tokens,
  normalizer: { normalize: normalizeEmail },
  abuse: signupAbuseGate,
  segments,
  events,
  clock,
  ids,
})

await audiences.createList({
  key: 'release-notes',
  name: 'Release notes',
  topic: 'release-notes',
  authority: 'local',
  doubleOptIn: true,
})

const result = await audiences.subscribe('release-notes', {
  email: form.email,
  source: 'launch-page',
})
```

The trusted server result contains the token required to send a confirmation. Public controllers must return only a uniform accepted state and must never echo confirmation, preference, or unsubscribe tokens.

## Configuration reference

| `AudiencesOptions` property | Required | Purpose                                                                                              |
| --------------------------- | -------- | ---------------------------------------------------------------------------------------------------- |
| `persistence`               | Yes      | Transactional lists, subscribers, subscriptions, tags, and segment queries.                          |
| `suppression`               | Yes      | Topic suppression writer from `@playstack/delivery`; it must share the persistence transaction kind. |
| `tokens`                    | Yes      | Issues and verifies purpose-bound confirmation, preference, and unsubscribe tokens.                  |
| `normalizer`                | Yes      | Applies the application's email normalization policy.                                                |
| `abuse`                     | Yes      | Runs rate-limit, CAPTCHA, honeypot, or other signup policy before mutation.                          |
| `segments`                  | Yes      | Validates and compiles data-only segment definitions where subscriber data lives.                    |
| `remote`                    | No       | Queue and provider authority for remote-owned lists.                                                 |
| `events`                    | Yes      | Emits list, consent, subscription, and remote-operation lifecycle events.                            |
| `clock`, `ids`              | Yes      | Application-owned time and identifiers.                                                              |
| token TTL properties        | No       | Override confirmation, preference, and unsubscribe token lifetimes.                                  |
| `onTokenError`              | No       | Observes token failures without exposing them to a public response.                                  |

## Bridge contracts

| Contract                     | Boundary                                                                |
| ---------------------------- | ----------------------------------------------------------------------- |
| `AudiencePersistence`        | Transactional audience storage and database-side subscriber queries.    |
| `AudienceTokenIssuer`        | Purpose-bound signed tokens; exposes its application-owned client.      |
| `AudienceEmailNormalizer`    | Explicit normalization without provider-specific alias assumptions.     |
| `AudienceAbuseGate`          | Pre-mutation public signup policy.                                      |
| `AudienceSegmentCompiler`    | Validates and compiles versioned data-only segment trees.               |
| `AudienceRemoteCommandQueue` | Transactional, endpoint-free subscribe and unsubscribe intent.          |
| `AudienceRemoteAuthority`    | Provider-specific segment validation, mutations, and recipient queries. |

Remote-authoritative lists enqueue idempotent commands and resolve current subscriber data when a worker executes them. Mirrored authority is deliberately unsupported.

`@playstack/audiences-resend` implements the remote-authority boundary with Resend Contacts and Segments. Playstack retains consent, confirmation, suppression, and idempotent command state while Resend becomes the explicitly selected contact authority. Removing one subscription removes only that segment membership; fresh explicit consent may clear the contact's global unsubscribe state.

## Prisma and testing

`@playstack/audiences/prisma` exports `PrismaAudiencePersistence` and `PrismaAudienceSegmentCompiler`. Built-in segment nodes compile to parameterized SQL and application resolvers return predicates with separately supplied values. The managed `audiences.prisma` artifact remains application-migrated.

`@playstack/audiences/testing` supplies deterministic in-memory persistence, token, topic-suppression, segment, queue, and remote-authority fixtures. They are not production persistence or cryptography.

## Boundary

Fresh consent removes only the exact list suppression retained by the removed subscription. It never clears channel-wide or unrelated list suppressions. Email equality also never links a subscriber to a user; `verifiedUserId` is accepted only through a trusted application call.

{/* package-reference:start */}

## API entry points and requirements

Reference snapshot: `@playstack/audiences@0.1.0-beta.1`. Import only the entry point your runtime needs. Paths below are relative to the installed package; use **Go to Definition** in your editor to inspect exact parameters, return types and overloads. Do not import the declaration-file paths directly.

| Public entry point | Declaration file |
| --- | --- |
| `@playstack/audiences` | `./dist/index.d.ts` |
| `@playstack/audiences/errors` | `./dist/errors.d.ts` |
| `@playstack/audiences/prisma` | `./dist/prisma.d.ts` |
| `@playstack/audiences/testing` | `./dist/testing.d.ts` |
| `@playstack/audiences/package.json` | No TypeScript declaration (asset or metadata export). |

Node.js engine requirement: `>=20`. This is not a claim that every entry point works in browsers or Workers.

### Peer dependencies

This package declares no peer dependencies. Its ordinary dependencies are resolved by the package manager.

For a complete first program, start with [Getting started](/docs/getting-started). For API lookup and partial-example conventions, see [Reading the reference](/docs/packages#reading-the-reference). Provider failures, lifecycle requirements and application responsibilities remain described in the guide above; types alone do not establish production safety.

{/* package-reference:end */}
