Overview

A nonprofit advocacy group’s petition journeys backfired when supporters received fundraising asks before getting confirmation or context. Website events landed out of order, multiple canvases competed, and Braze triggered messages without awareness of recent actions. We rebuilt journeys around Segment events, sequenced steps in Braze Canvas with explicit completion gates, and added concurrency controls so only one journey ran per supporter at a time. Messaging aligned to intent, complaints eased, and campaign planning moved from calendar triage to clear, event-driven design.

Client Profile

  • Industry: Nonprofit advocacy and public policy
  • Company size (range): National organization with regional chapters and a large supporter list
  • Stage: Scaling digital engagement and fundraising with tighter journey governance
  • Department owner: Marketing & Customer Engagement (Digital Engagement / Lifecycle)
  • Other stakeholders: Development/Fundraising, Web & Engineering, Data & Analytics, Legal & Privacy, IT/Integrations, Supporter Services

The Challenge

Supporters signed petitions on the website and expected a confirmation and next steps. Instead, some received an immediate donation ask because the fundraising canvas listened for generic form submissions and fired independently of the petition flow. Other times, the confirmation email arrived late because the web event posted after the fundraising trigger, or a supporter reopened a tab and fired duplicate events. Without a shared source of truth, Braze canvases made reasonable local decisions that combined into a confusing sequence.

The team tried list filters and send delays, but rules drifted across programs. New petitions launched frequently; each one recreated segments and timing from scratch. Editorial calendars listed intent by week, yet overlapping canvases didn’t respect those plans at send time. Analysts stitched together partial logs to explain why a supporter received messages out of order, which made root-cause analysis and fixes slow.

Why It Was Happening

Signals and state were fragmented. The website emitted events that were not normalized, the CDP stitched identities only some of the time, and Braze canvases evaluated entry criteria in isolation. There was no cross-journey lock to prevent a fundraising canvas from activating while a petition confirmation was still in flight. Event payloads lacked consistent IDs for the petition or campaign, so suppression rules had to guess based on recent activity.

Governance arrived late. Journeys were published with best-effort segments and informal send windows. There was no preflight check that all entry events existed or that a supporter’s current state allowed the next step. Concurrency and mutual exclusion were documented in wikis, not encoded as enforceable policy in the tools.

The Solution

We established an event-driven orchestration that sequenced messages by completion signals and prevented cross-journey collisions. Website actions flowed through Segment to Braze with normalized events and IDs. Braze Canvas used those events to gate each step: a supporter could not receive a fundraising message until a petition confirmation step completed. A lightweight lock attribute ensured only one high-priority journey ran at a time, with automatic release on completion. Suppression rules referenced shared attributes (last_petition_id, in_journey flag, intent) so canvases agreed on eligibility. Nothing was replatformed: Segment remained the event backbone, Braze remained the channel engine, and the new layer standardized sequencing, locks, and governance.

  • Normalized petition and donation events sent from the website to the CDP and into Braze with consistent IDs and traits (Segment Docs)
  • Braze Canvas sequencing that advanced only on explicit completion events; confirmation and education steps gated fundraising (Braze Canvas)
  • Cross-journey lock: a profile attribute set on entry and cleared on exit; other canvases checked the lock before starting
  • Mutual exclusion and suppression logic for conflicting intents (petition vs. donation vs. newsletter onboarding)
  • Backfill and deduplication rules to handle late or duplicate events; idempotent updates based on petition_id
  • Profile enrichment with campaign and petition metadata for better targeting and reporting
  • Monitoring dashboards for event freshness, journey progression, suppressions, and exception rates in Looker
  • Slack alerts for stuck locks, missing completion events, or high suppression due to conflicts (Slack API)
  • Role-based permissions for who can publish canvases, adjust suppression rules, and approve overrides (for example, Okta Groups)
  • Audit logging tying each message to the triggering event, journey state, and suppression decisions

Implementation

  • Discovery: Mapped website events for petitions and donations, current Segment setup, and Braze journeys in market. Cataloged failure cases where fundraising preceded confirmation. Reviewed identity stitching across email, phone, and site user IDs, and captured business rules for when fundraising is appropriate after advocacy actions.
  • Design: Authored a normalized event schema (petition_started, petition_signed, confirmation_sent, donation_started, donation_completed) with IDs, timestamps, and campaign metadata. Defined the journey lock strategy, mutual exclusion groups, and suppression logic. Planned Braze Canvas entry/exit criteria, re-entry rules, and hold behavior for late events. Scoped dashboards, alerts, and audit fields.
  • Build: Updated the website to emit normalized events to Segment; configured mappings to Braze. Implemented Canvas flows that listened for petition_signed and required confirmation_sent before branching to education or fundraising. Added profile attributes for lock and last_petition_id. Built suppression segments for conflicting intents and enabled Slack alerts for anomalies. Stood up Looker dashboards for progression and exceptions.
  • Testing and QA: Ran shadow mode where canvases logged “would send” decisions without messaging. Tested out-of-order, duplicate, and missing events; verified that fundraising held until confirmation completed; and confirmed mutual exclusion behavior. Validated identity stitching on multi-channel supporters and ensured audit logs linked events to messages.
  • Rollout: Enabled sequencing and locks for a subset of petitions first, then expanded as behavior proved consistent. Kept overrides for priority campaigns with approver notes and expiry. Conducted regular reviews of suppression and exception patterns to tune rules.
  • Training and hand-off: Delivered guides for lifecycle managers on building canvases with event gates, for web teams on emitting normalized events, and for analysts on reading dashboards. Established change control for event schemas, lock behavior, and suppression rules.
  • Human-in-the-loop review: Routed edge cases—such as multi-petition signers and urgent fundraisers tied to breaking news—to a review queue. Decisions updated allowlists, suppression logic, or journey templates to reduce repeats.

Results

Journeys respected supporter intent. Petition signers received confirmations and context before any donation asks, and conflicting canvases stood down when a lock was present. When events arrived late or out of order, backfill logic corrected the state and canvases advanced appropriately. Supporter complaints about mismatched messaging receded as flows aligned to actions taken on the website.

Operationally, planning simplified. Teams built around a common event schema and reusable journey templates rather than bespoke segments and timing tricks. Dashboards surfaced where suppressions or stuck states clustered, which guided fixes to event emission or identity stitching. Managers trusted that canvases would not collide, and content teams focused on message quality instead of firefighting sequence errors.

What Changed for the Team

  • Before: Fundraising and petition canvases ran independently. After: Event gates and a journey lock coordinated steps and prevented collisions.
  • Before: Website events were inconsistent and late. After: Normalized Segment events drove sequencing and backfill behavior.
  • Before: Segments and delays tried to approximate intent. After: Canvases advanced on explicit completion signals.
  • Before: Root causes required log dives. After: Dashboards and audit trails showed event order, locks, and suppression reasons.
  • Before: Every petition recreated logic. After: Reusable templates encoded suppression, locks, and progression rules.

Key Takeaways

  • Sequence by completion events, not time; petition flows should confirm before asking for a gift.
  • Add a simple journey lock; a shared attribute prevents cross-program collisions without custom code.
  • Normalize web events through a CDP; consistent IDs and traits make gating and suppression reliable.
  • Design for messy reality; dedupe and backfill handle late or duplicate events so journeys stay correct.
  • Instrument everything; dashboards, alerts, and audit logs shorten troubleshooting and improve planning.

FAQ

What tools did this integrate with?
Website events flowed through Segment to Braze Canvas, where journeys sequenced on explicit completion signals. Monitoring and progression dashboards ran in Looker, and Slack delivered alerts for anomalies (Slack API). Role-based access was governed via identity groups such as Okta Groups.

How did you handle quality control and governance?
We defined a normalized event schema and enforced it at the website and CDP layers. Braze canvases required explicit events to advance, and a journey lock attribute prevented cross-program entry. Suppression rules handled conflicting intents, and all decisions logged the triggering event, state, and rule versions. Dashboards tracked event freshness, progression, and suppressions, and changes to schemas or locks followed change control.

How did you roll this out without disruption?
Journeys ran in shadow mode first, logging “would send” decisions while legacy flows continued. After comparing behavior and tuning event emissions and suppression logic, we enabled sequencing and locks for a subset of petitions, then expanded. Overrides existed for priority campaigns with expiry and approver notes.

How did you prevent fundraising from firing before confirmation?
Fundraising canvases checked for both the petition_signed event and a confirmation_sent gate before entry. If a supporter lacked the gate, the canvas held or exited with a logged reason. A shared lock attribute also prevented entry if another high-priority petition journey was active.

What happened when events arrived late or duplicated?
Events carried petition_id and timestamps. Idempotent rules updated profile state only when new or corrective, and late completions advanced the appropriate step instead of skipping ahead. Duplicate events were ignored after state changed, and a backfill action ensured that confirmation and education steps completed before any fundraising branch.

You need a similar solution?

Get a FREE
Proof of Concept
& Consultation

No Cost, No Commitment!