Broadcasts

Audience Filter

Define who receives a broadcast with a list of profile conditions

The audience is the set of contacts the broadcast will fire for. It is defined by a list of profile conditions ANDed together, edited in Step 1 — Audience of the wizard.

Audience filter editor with multiple conditions and live preview count

Filter Shape

Each condition is a triplet:

fieldKey  operator  value
  • fieldKey — any field on a person: a system field (tags, country, language, lastSeenAt, firstSeenAt, etc.) or a custom field defined by your org.
  • operator — see the table below.
  • value — the comparison value. Ignored for IS_EMPTY and IS_NOT_EMPTY.

Conditions are joined with AND — every one must match for a contact to be included.

There is no OR connector in v1. To express OR semantics, create separate broadcasts (one per branch) or restructure the data so the same tag/field is set for all relevant contacts.

Empty filter

If you add no conditions, the audience is every contact in the organisation. This is occasionally what you want (org-wide announcement) — most of the time you'll want at least one condition like optedOut NOT_EQUALS true or language EQUALS en.

Operators

OperatorApplies toNotes
EQUALSAnyExact match. Strings are case-sensitive.
NOT_EQUALSAnyInverse of EQUALS.
CONTAINSString, arraySubstring match for strings, membership for arrays (e.g. tags).
NOT_CONTAINSString, arrayInverse of CONTAINS.
STARTS_WITHStringPrefix match.
ENDS_WITHStringSuffix match.
IN_ARRAYAnyField's value is one of the listed values.
NOT_IN_ARRAYAnyField's value is not in the listed values.
GREATER_THANNumber, dateStrict >.
GREATER_THAN_OR_EQUALNumber, date>=.
LESS_THANNumber, dateStrict <.
LESS_THAN_OR_EQUALNumber, date<=.
IS_EMPTYAnyField is missing, null, empty string, or empty array. No value needed.
IS_NOT_EMPTYAnyField has a non-empty value. No value needed.
MATCHES_REGEXStringFull regex match. Use sparingly — slow on large directories.

Common Field Examples

FieldUse caseExample
tagsAudience segmentstags CONTAINS "vip"
languageLocalisationlanguage EQUALS "en"
countryGeographic targetingcountry IN_ARRAY ["ES", "PT"]
firstSeenAtRecency cohortsfirstSeenAt GREATER_THAN "2026-04-01"
lastSeenAtRe-engagementlastSeenAt LESS_THAN "2026-03-01"
Custom fieldsDomain logicsubscriptionTier EQUALS "pro"

Custom fields are listed alongside system fields in the field picker. Define them in People → Custom Fields.

Live Preview Count

While you edit, the wizard shows a count next to the filter — "≈ 1 284 contacts match".

  • The query runs against your current people directory.
  • It's debounced (300ms) so it doesn't fire on every keystroke.
  • For template-mode broadcasts, the preview accounts for template routes — only contacts whose chat is on one of your route integrations are counted, since the rest can't receive the template anyway.
  • It's an estimate, not a guarantee. The actual fan-out is computed at fire time.

The number is also shown on the broadcast detail page as long as the broadcast is SCHEDULED, so you can revisit it without re-opening the wizard.

Estimate vs Actual

The broadcast stores two audience numbers:

FieldWhen it's setWhat it represents
audienceSizeEstimateAt save timeThe live preview count when you confirmed the wizard
audienceSizeActualAt fire timeThe count produced by re-running the filter against the live directory

After firing, the detail page shows both side-by-side so you can spot drift:

Estimated: 1 284 · Actual: 1 251 (delta −33)

A delta is normal — contacts can be added, removed, or have their fields change between save time and fire time.

Re-evaluation Semantics

The filter runs at fire time, not at save time.

Change between save and fireEffect
Contact created that matches the filterIncluded.
Contact deleted or archivedExcluded.
Contact's field changed and now matchesIncluded.
Contact's field changed and no longer matchesExcluded.

This is "everyone currently tagged X on Apr 30" semantics — almost always what you want for marketing-style sends. If you need a frozen audience, capture the contact IDs into a custom field at save time and filter on that.

Capacity

There's no hard limit on audience size — broadcasts of 100 000+ contacts work. The wizard shows a soft warning above ~100k recommending you tighten the filter, but the save still succeeds.

The dispatcher streams the audience in pages (default 500 contacts per page) so memory stays flat regardless of audience size. Per-batch concurrency is bounded so providers don't get overwhelmed; rate-limit responses are absorbed automatically with exponential back-off.

Targeting Specific Contacts (Power-User)

For advanced flows that already know exactly which contacts to target — typically retryFailedContacts or external orchestration — the audience can be a hand-picked list of contact IDs. This bypasses filter resolution entirely. It's used internally by Retry Failed Contacts and is exposed via the API but not via the standard wizard.

On this page