Skip to Content
GuidesAutomations & playbooksCross-campaign suppression

Cross-campaign suppression

Cross-campaign suppression is how you stop a contact from receiving messages they shouldn’t — for example, a recent customer who shouldn’t see “first-purchase discount” promotions, or a contact in an active support thread who shouldn’t receive promotional pings.

The mechanic: define a suppression segment once, then attach it to any campaign, journey, or playbook. The platform subtracts those contacts from delivery at send time.

What a suppression segment is

A regular segment with one extra property: it can be referenced as a negative filter during send-time evaluation.

Examples of useful suppression segments:

Segment nameRule
Recent buyers (7d)transaction.purchase in last 7 days
In support threadActive inbox conversation, agent assigned
Opted out — promotionalconsent.promotional is false
High frequency cap proximityTouched 5+ times in last 24h
In a competing journeyCurrently enrolled in journey X
DNC listExternally maintained do-not-contact list, imported via CSV or API

You can build any segment as a suppression segment — it’s the attachment that makes it act as a suppression, not the definition.

Attaching suppression to a playbook

Open the playbook drawer

Go to Engage → Automations → {playbook} and open the configuration drawer.

Find the suppression panel

In the drawer, scroll to Suppression segments. Click Add segment.

Pick one or more segments

You can attach multiple suppression segments — they’re combined with OR semantics (a contact in any attached suppression segment is suppressed).

Save

When you save, the playbook stores a snapshot of the suppression segments’ contact members at that moment. From then on, every send through this playbook excludes any contact in the snapshot.

How the suppression is applied

When a journey send node (or campaign delivery, or playbook touch) reaches the dispatcher, the engine:

  1. Looks up the contact’s identity
  2. Iterates through every attached suppression segment
  3. Checks the canonical aegis.segment_members table in ClickHouse for membership
  4. If the contact is in any attached segment, the send is suppressed — recorded with a reason on the contact’s timeline

This is fast (segment membership is indexed) and consistent (the same canonical substrate that powers segments themselves).

Snapshot vs live

Suppression can be configured in two modes:

ModeWhat happens
Snapshot (default)When you attach the segment, its current member list is frozen for the playbook. Subsequent changes to the segment don’t affect this playbook.
LiveMembership is re-evaluated at every send. Newly added members are suppressed immediately.

Snapshot is the default because it’s predictable — the operator sees who’s suppressed at activation time, and the playbook behaves consistently for its lifetime. Live mode is useful for global suppression lists (DNC, opt-outs) that should always be current.

Configure mode per attachment.

Where you’d use this

Recent-buyer suppression

A “new customer welcome” campaign should never go to someone who bought a week ago. Attach a “recent buyers (7d)” suppression segment to the campaign — anyone who purchased in the past week is dropped from delivery.

Cross-journey conflict avoidance

Running two journeys with overlapping triggers? Attach each journey’s enrolled-contacts segment as a suppression on the other. Contacts enter only the first journey that matches.

Support-thread silence

When a contact has an open inbox thread, suppress all promotional sends. Attach “in support thread” to every promotional playbook — sends pause until the thread closes.

External DNC list

Maintain a do-not-contact list outside Active Reach (via API or CSV upload). Sync it into a segment and attach as live-mode suppression on every promotional surface.

In-app suppression via frequency_cap

Playbook-driven in-app touches opt into the same cross-campaign suppression as catalog campaigns via the frequency_cap field on contact_in_app_queue. The signal flows end-to-end:

  • Journey send → enqueue with frequency_cap JSONB
  • get_queued_messages and /v1/in-app/active honour the cap
  • notifyConversion silences pending journey-queued cart-recovery touches, not just catalog campaigns

Targeting bypass on already-enqueued rows is preserved by design — once a contact is queued, the original targeting decision stands.

The dead-column anti-pattern (developer note)

Suppression segments were defined as a column on playbook_execution_instances for a long time before being wired end-to-end. The lesson: if a column exists in the schema, it must be reachable from the operator UI and enforced at send time, or it’s a maintenance hazard. Today the wire-up is complete — UI to schema to send-time enforcement.

Visibility on the contact timeline

When a send is suppressed for a contact, the contact’s timeline records:

  • The send node / campaign / playbook that was attempted
  • The suppression segment that matched
  • The mode (snapshot vs live)
  • Timestamp

Operators can audit suppression decisions per contact and bulk-export the suppression-events log for compliance / reporting.

What’s next