Subscription/Consent Management

The Crossengage system is very flexible and there is not only one correct way to manage subscriptions and unsubscriptions etc.. We can give pointers and maybe some recommendations, but in the end it depends on the scenario and environment it connects to.

Note: The information in this section is not legal advice. Each customer shall set up their subscription concept under their legal and technical considerations.

For the purpose of this documentation we will mostly cover scenarios that store necessary information in Crossengage and give context to the options.


In the beginning it is important to evaluate if there is more than one topic that a user can subscribe to or unsubscribe from, even if it is just a vague plan for the future. This will determin if the approach is mostly system functionalities only, or mostly custom functionality.

This step should not be taken lightly, because it can get tricky to introduce custom options later down the line.

System functionalities

Crossengage is an “opt out”-system, so technically it is not necessary to process Opt-Ins within it, but unless its only used for transactional communication, it is recommend to do so somewhere (usually also required by law and therefore also by the ESP).

The only actual system functionality that is connected here, is the opt-out status of a user. The default is “false”, which means that this user is not opted out and they can receive messages. If the status is set to “true” and the user is therefore opted out, the system will block any sendouts automatically, unless its marked as transactional in case of Realtime Campaigns.

Custom functionalities

On top of the system functionalities which will always apply, it is also possible to include custom functionalities. This could be the use of custom events and/or user traits, which can give more options to segment users (e.g. preferences), trigger campaigns, give information about the progress in a subscription workflow or similar.

User Ids

It is also important to know when exactly you will have which information about a user. User management in Crossengage can be done via “External Id” (e.g. a customer number), or (partly) via a combination of “Email” and “Business Unit” (short “BU”). But:

  • the external Id can only exist once in the system

  • the combination of “Email” and “BU” can also only exist once

  • if no “BU” is used, it will be an invisible “default” in the background

  • users with an external Id are managed with the API endpoint “users”

  • users without an external Id are managed with the API endpoint “leads”, once an update with the same combination of “Email” and “BU” is made with an “external Id” as well, this users management will get moved to the “users” endpoint and the “leads” endpoint can’t be used anymore

  • events can be send with the external Id as “id”, or with “email” and “businessUnit” (even for full users)

Recommendation for single subscriptions

In this scenario there is only one topic to subscribe to and from, so its basically an on/off switch. But there are still several steps to take and several API calls to make, in order for it to work.


Step 1: Preparation

If not already existing, the following need to get created (names of traits are examples):

  • user trait “doi” with the datatype “STRING”

  • event “Subscribe Newsletter” with a property that include the “doiLink”

  • Website: Landingpage which will serve as the property “doiLink”. Here its important to establish how a user is recognized. It might be necessary to use something like a hashed email-address.

  • RT campaign “DOI” which will send the user a DOI-mailing with the “doiLink”

  • event “Confirmed Subscription”

  • Website: Landingpage to confirm the subscription was successful

Step 2: Subscription Form

When a user sends his subscription information, several API calls need to get send:

  • API call to create/update user with the user trait “doi” to set the status: PUT{id} {"id": "USERID", "email":"", "businessUnit":"de", "doi": "pending"}

  • event “Subscribe Newsletter”: POST

    {"id": "USERID", "events": [ { "event": "Subscribe Newsletter", "properties": { "doiLink": "https://subdomain.domain.tld?id=USERID"}}]}

Step 3: DOI Mailing

The event “Subscribe Newsletter” triggers the RT campaign “DOI”, which sends a doi mailing to the users to confirm the subscription.

This mailing needs to be marked as “transactional”, just in case the user was already opted out for some reason and must contain the property “doiLink” with the help of a handlebar. In this example case it would be:


Usually handlebars have two curly brackets surrounding them, but in case of a URL its safer to user three, because it will enforce that the content is used as is and not accidentally url-encoded, which could cause problems at the destination.

See Event Helper Functions | Documentation for more information about handlebars, if needed.

If external templates from the ESP are used, this handlebar needs to get inserted into the value mapping to transfer this information to the ESP for rendering it into the template.

Step 4: Confirmation Landingpage

Once the user clicks on the “doiLink”-URL to confirm the subscription they get redirected to the confirmation page and again several API calls need to get send:

  • API call to create/update user with the user trait “doi” to set the status: PUT{id}

    {"id": "USERID", "email":"", "businessUnit":"de", "doi": "confirmed"}

  • events “Confirmed Subscription” and “Opt In” POST

    {"id": "USERID", "events": [{"event": "Confirmed Subscription"}, {"event": "Opt In", "channel.type":"MAIL"}]}

The event “Opt In” is necessary to reverse the opt-out-status of a possible earlier unsubscription to “false”. But more about “Opt In” and “Opt Out” in the separate documentation about it. ”Confirmation Subscription” could trigger a welcome mailing or a welcome story and doesn’t necessarily need properties, but can always get enhanced with some, if needed.


For unsubscribing the previous steps need to get kind of reversed, but with less steps. Usually an unsubscription is done via an unsubscribe link in a mailing, which also usually should be one-click (meaning: with clicking the unsubscription should be already done and no other steps from the user are necessary).

There are two ways to do that:

  1. use the standard unsubscribe link of the ESP. This will automatically process the unsubscription through this provider, which then sends the event “mail.unsubscribe” to Crossengage, which will automatically trigger the change of the opt-out-status to “true”. No further message can get send to the user (unless its transactional) from this point on.

  2. using a custom unsubscribe link that leads to another landingpage, which then sends:

  • the first option will not update any custom trait, so the users will remain in any “subscribed” segment, even though they are opted out. No message will get send, but the numbers will be wrong.

  • even if the second option is used, it is still possible that there are unsubscriptions without the update of user traits, if some automatic process like the so-called list-unsubscribe-header is involved

  • more traits or events can be included as well, but these are the basics

Recommendation for multi-subscriptions

Most of the steps from the single subscriptions are the same here. But if a user can subscribe to and unsubscribe from multiple different newsletters or topics, the system functionalities for unsubscriptions need to get replaced by fully custom options and instead of one user trait “doi”, there needs to be at least one specific trait per option, maybe even two, if you want to add a date for the (un)subscription as well.


Example where the user can choose multiple categories, e.g. “kids”, “pets” and “shoes”.

  • Similar to the single subscription with the trait “doi” the subscription form could trigger: PUT{id}

    {"id": "USERID", "email":"", "businessUnit":"de", "newsletterKids": "pending", "newsletterPets": "pending", "newsletterShoes": "pending"}

The "doiLink"-property in the event “Subscribe Newsletter” should then also contain parameters that include the chosen categories:

  • POST

    {"id": "USERID", "events": [{"event": "Subscribe Newsletter", "properties": {"doiLink": "https://subdomain.domain.tld?id=USERID&kids=1&pets=1&shoes=1"}}]}

The rest of the steps are the same, just that after confirming not one, but all specified user traits get updated with “subscribed”.


Since using the system opt-out (via events “Opt Out” or the providers “mail.unsubscribe”) would result in a total opt-out from the whole channel, only the custom unsubscribe version without the events can be used here.

To stay with the above example, the API call would set the wanted category to “unsubscribed”

  • API call to update user with the wanted category user trait to “unsubscribed” PUT{id}

    {"id": "USERID", "email":"", "businessUnit":"de", "newsletterKids": "unsubscribed", "newsletterShoes": "unsubscribed"}

    In this example, the subscription for “newsletterPets” would still remain subscribed, the others are unsubscribed.

In this scenario there is no system functionality that takes care of the opt out status of the user! There should always be a check for the necessary traits in the segments that are used for campaigns and stories, otherwise opted out users could still receive messages!

Known issues

Segments have more users in it than newsletters are send

The reason is most likely, that some users did not use the regular custom unsubscribe link in a mailing, but the unsubscribe option that got automatically rendered from the so-called list-unsubscribe-header by the email client. Especially freemail providers like Gmail will sometimes show an unsubscribe link in the inbox overview, which contains the system opt-out of the ESP, which will then trigger a system opt-out in Crossengage.


  • create a workflow that regularely requests the users of recent system opt-outs

  • this list can then be used to custom opt-out the users in it. Usually all possible user traits should get the “unsubscribed” content, unless it is know exactly which option the user wanted to unsubscribe from.

  • after that the users should get send the event “Opt In”, to reverse the system opt-out- status:

    {"id": "USERID", "events": [{"event": "Opt In", "channel.type":"MAIL", "properties": {"status":"opt out via traits"}}]}

External Id is not known/doesn’t exist

The external Id is usually used as “id” to create/update users or sent events. If it does not exist or is unknown, its possible to use “Email” in combination with “Business Unit” instead.

  • for events its fairly easy, just use “email” and “businessUnit” instead of “id”. Example: events “Confirmed Subscription” and “Opt In” POST

    {"email": "", "businessUnit": "de" "events": [{"event": "Confirmed Subscription" }, { "event": "Opt In", "channel.type":"MAIL" }]}

  • for user trait updates its a bit more complicated, because there are two API endpoints, “leads” and “users”. If the external Id does not exists, the endpoint “leads” must be used instead of “users”. If the external Id might exist, but is not known at this point, you can only try to use “leads”, but in case the person already exists as a full user, the API will respond with "EXTERNAL_IDS_MISMATCH".

Last updated