Day 21
25 Days of Sitecore EXM!
Managing the Unsubscribe
21 days into 25 Days of Sitecore EXM, we conclude the mini-series Managing the Unsubscribe. Today we’re going to take a closer look at the EXM Client API. this is guaranteed to be a really interesting blog post for developers and a total snoozer for marketers.
The EXM Client API At a Glance
Sitecore comes packaged with an Email Experience Manager client API that can be used to execute the automatic sending of messages, as well as manage subscriptions to contact lists. Sitecore 9.1 changed the way the API worked in a pretty big way (read: breaking change) without a lot of fanfare. For the purposes of this post, I am going to be covering the 9.1 API in-depth. However, it is important for me to showcase the differences between the two API’s.
IClientApiService is intended to run only on Content Delivery Servers.
EXM Client – Sitecore 9.0.X
namespace Sitecore.EmailCampaign.Cd.Services
{
public interface IClientApiService
{
void SendAutomatedMessage(AutomatedMessage automatedMessage);
void Subscribe(SubscribeMessage subscribeMessage);
void Unsubscribe(UnsubscribeMessage unsubscribeMessage);
void ConfirmSubscription(ConfirmSubscriptionMessage confirmSubscriptionMessage);
void RegisterEmailOpen(EmailOpenMessage emailOpenMessage);
}
}
EXM Client – Sitecore 9.1.X
namespace Sitecore.EmailCampaign.Cd.Services
{
public interface IClientApiService
{
void SendAutomatedMessage(AutomatedMessage automatedMessage);
void ConfirmSubscription(ConfirmSubscriptionMessage confirmSubscriptionMessage);
void RegisterEmailOpen(EmailOpenMessage emailOpenMessage);
void UpdateListSubscription(UpdateListSubscriptionMessage message);
}
}
The biggest difference, as noted above is that the Subscribe() and Unsubscribe() methods in the 9.0.X API have been consolidated down to a single method: UpdateListSubscription().
The EXM Client API is available through Dependency Injection. To include the use of this in your project, simply add it to the controller constructor parameters like any other DI service.
From this point forward, I”ll be focusing only on the Sitecore 9.1 API. Concepts and design patterns for using the API in 9.1 are the same in the 9.0 API, so with a little inspection, developers shouldn’t have too much trouble.
SendAutomatedMessage
public IClientApiService ClientApiService { get; }
public ClientSamples(IClientApiService clientApiService)
{
ClientApiService = clientApiService;
}
public void SendAutomatedExample(Guid messageId, ContactIdentifier identifier)
{
var messageOpitons = new AutomatedMessage();
//Required Parameters
messageOpitons.MessageId = messageId;
messageOpitons.ContactIdentifier = identifier;
//Custom Tokens - Optional
var tokens = new Dictionary<string, object> {{"specialvalue", "Something Useful Here"}};
messageOpitons.CustomTokens = tokens;
//Query String Params - Optional
var queryParams = new Dictionary<string, string> { { "utm_campaign", "Some Value" },{"utm_media","Something Useful"} };
messageOpitons.CustomQueryStringParameters = queryParams;
//Language - Optional
messageOpitons.TargetLanguage = "en";
//Send Message
ClientApiService.SendAutomatedMessage(messageOpitons);
}
}
ConfirmSubscription
This part of the API has two parts that are important to recognize. This blog post is really only covering the Client API that is available on the Content Delivery Servers. However, as we’ll cover on Day 25’s post, EXM comes complete with a number of services, some that are only available on the Content Management server. Two of those services are introduced here: SubscriptionManager (only on the CM Server) and ManagerRootService (available globally).
Get a Confirmation Key
This part is intended to run on a CM or DDS server as part of a process to generate an email that contains a confirmation key for subscription to specific Contact List.
public IClientApiService ClientApiService { get; }
public ISubscriptionManager SubscriptionManager { get; }
public IManagerRootService ManagerRootService { get; }
public ClientSamples(IClientApiService clientApiService, ISubscriptionManager subscriptionManager, IManagerRootService managerRootService )
{
ClientApiService = clientApiService;
SubscriptionManager = subscriptionManager;
ManagerRootService = managerRootService;
}
public string GetConfirmationKey(Guid contactListId, ContactIdentifier identifier, Guid managerRootId)
{
//PART 1: Create a Subscription Confirmation Key - This Part Runs on CM or DDS Servers
//Get Manager Root
var managerRoot = ManagerRootService.GetManagerRoot(managerRootId);
//Get a Confirmation Key
var confirmationKey = SubscriptionManager.GetConfirmationKey(contactListId, identifier, managerRoot);
return confirmationKey;
}
Confirm Subscription
This part is intended to run on the CD Server by way of accepting a confirmation key. Maybe that key was part of a query string parameter. However the key was transmitted, you can use the method below for validating it.
public IClientApiService ClientApiService { get; }
public ClientSamples(IClientApiService clientApiService)
{
ClientApiService = clientApiService;
}
public void ConfirmSubscriptionExample(string confirmationKey)
{
//PART 2: Confirm a Subscription Confirmation Key - Runs on CD Servers
var subOpitons = new ConfirmSubscriptionMessage();
subOpitons.ConfirmationKey = confirmationKey;
ClientApiService.ConfirmSubscription(subOpitons);
}
This method is void, so there’s no way out of this method, to determine if this was successful. However, if successful, the contact is immediately added to the Contact List that was associated as part of the process to GET a key.
RegisterEmailOpen
This method is intended to run only on the Content Delivery servers and is the method ran when the Register Open tracking pixel is fetched when a message is opened. It is unlikely that you would use this. However, if you wanted to create your own, there are a number of variables that are collected as part of this service. I have included the list of properties that need to be included when making this call.

UpdateListSubscription
This is a complex API method, which is intended to only run on the Content Delivery server, that is based on the options provided to the API method can perform 5 different functions:
- Subscribe
- Unsubscribe
- UnsubscribeFromall
- AddToList
- RemoveFromList
This is handled through an enum called ListSubscribeOperation.
namespace Sitecore.EmailCampaign.Model.Messaging
{
[Serializable]
public enum ListSubscribeOperation
{
Subscribe,
Unsubscribe,
UnsubscribeFromAll,
AddToList,
RemoveFromList,
}
}
Depending on which operation you are trying to do, determines which properties need to be included. As a whole, the method is executed as shown below.
public void UpdateListSubscription()
{
var subscribeOptions = new UpdateListSubscriptionMessage();
subscribeOptions.ListSubscribeOperation = ListSubscribeOperation.Subscribe;
//Include Additional Property Settings in Options
ClientApiService.UpdateListSubscription(subscribeOptions);
}
However, the UpdateListSubscriptionMessage has a number of properties that can be set. Not all properties need to be included and depend on the operation selected.

Each Operation requires a slightly different set of properties provided. Let’s review each operation.
Subscribe
Performs the actions of subscribing a contact to a Contact List.
- ContactIdentifier
- MessageId
- RequiresSubscriptionConfirmation
Unsubscribe
Unsubscribes the contact from a Contact List, following the process defined earlier in this mini-series on Day 17.
- ContactIdentifier
- MessageId
UnsubscribeFromAll
Unsubscribes the contact by placing them in the Global Opt-Out list, following the process defined earlier in this mini-series on Day 17.
- ContactIdentifier
- MessageId OR ManagerRootId
AddToList
Simple list operation to add a contact to a Contact List in List Manager.
- ContactIdentifier
- ListId
RemoveFromList
Simple list operation to remove a contact on a Contact List in List Manager
- ContactIdentifier
- ListId
4 Days Left in 25 Days of EXM
With only 4 days left before we wrap up 25 Days of EXM, we have finally wrapped up our mini-series Managing The Unsubscribe. Tomorrow we highlight how Marketing Automation can bring EXM Automated Messages to life and demonstrate how to create an acquisition campaign.
Did You Miss EXM Live!?
You’re in luck! You can now view EXM Live! On-Demand on YouTube!
Leave a Reply