Skip to main content

Hi Trailblazers,

We are designing consent management in our Nonprofit Cloud org and need community advice on this scenario:

Scenario:

  • A donor adds two email addresses.
  • Email A → Explicit Opt-in (via ContactPointConsent)
  • Email B → Explicit Opt-out (via ContactPointConsent)
  • Later, the same donor activates Global Consent.

Our Solution:

 

We want to

manage all contact points individually and use Global Consent only as a hard stop / full opt-out for the entire donor (suppress everything).

Questions:

  1. Is this a recommended approach in Nonprofit Cloud?
  2. When Global Consent (hard stop) is activated, it should override all specific consents — correct?
  3. When Global Consent is not activated, should we strictly respect the individual ContactPointConsent records (so Email B remains opted-out even if other points are opted-in)?
  4. Any gotchas or best practices when implementing this model with the Consent Data Model (Individual → ContactPointTypeConsent → ContactPointConsent)?

We prefer this design for maximum donor control and simplicity, but want to make sure it aligns with Salesforce recommendations and common nonprofit implementations.

Any insights, lessons learned, or alternative suggestions are highly appreciated!

Thank you! 

 

#Nonprofit Cloud

1 réponse
  1. 18 août, 20:06

    Good scenario to pin down before you build, because the behavior you want is actually the opposite of Salesforce's default consent precedence, so it is worth being deliberate here. 

     

    How native precedence works: when you evaluate consent through Salesforce's Consent API (the Apex Consent.getConsent aggregation), the MOST SPECIFIC record wins, in this order: 

    ContactPointConsent (a specific email) beats ContactPointTypeConsent (all email for the individual) beats PartyConsent (the whole donor, i.e. your 'Global Consent'). 

     

    What that means for your scenario: because ContactPointConsent is more specific than PartyConsent, an explicit opt-in on Email A takes precedence over a party-level (Global) opt-out. So Global Consent does NOT natively act as a hard stop that overrides the granular per-email consents, the granular record wins. Your intended model ('manage per contact point, Global = full suppression override') is therefore not what the standard precedence gives you out of the box. 

     

    To actually get 'Global = hard stop,' enforce it as an explicit gate in your own eligibility logic rather than relying on native precedence: 

    1. First check PartyConsent (Global). If it is Opted Out for that purpose, suppress everything, full stop, and do not evaluate anything else. 

    2. Only if Party is not a hard opt-out, fall through to ContactPointConsent per email for the granular decision. 

    Put that logic wherever you determine send eligibility (a Flow/Apex helper, or your segment filter if you send from Data Cloud / Marketing Cloud) and centralize it so every channel uses the same gate. 

     

    Two things to keep straight: 

    - Consent is always per DataUsePurpose (Marketing vs Transactional), so compare Global vs contact-point consent within the same purpose, do not let a Marketing opt-out suppress a transactional receipt. 

    - Since you are deliberately inverting the default precedence, document it and keep the 'Party opt-out overrides all' rule in ONE place, so a future admin does not wire a send straight off ContactPointConsent and accidentally email someone who globally opted out. 

     

    Net: granular-per-contact-point + global-hard-stop is a reasonable and common design, but you have to implement the 'global wins' override yourself, because the native Consent API precedence is specific-wins and will not enforce the hard stop for you. 

     

    If this helps, please mark it as the Best Answer so it is easy for the next person to find. Thanks :)

0/9000