Unsubscribe and Log an UnsubEvent with a LogUnsubEvent Execute Call

The LogUnsubEvent provides a convenient way of handling unsubscribes when you create your own unsubscribe landing page or profile center functionality. This call allows you to unsubscribe a subscriber and log an UnsubEvent that is tracked against a specific Job, which means that you will be able to track from which email they unsubscribed and see the results on the tracking dashboard. You can configure the call to either unsubscribe a subscriber from a specific list, publication list, or all subscribers, which will effectively unsubscribe them from receiving any emails.

What’s more important, if you’re using Marketing Cloud Connect to connect with your Salesforce Sales or Service Cloud org, the unsubscribe will be captured on the subscriber record in Sales/Service Cloud. It will automatically check the Email Opt Out (HasOptedOutOfEmail) flag and will also be visible in the Individual Email Results for the corresponding email send.

The LogUnsubEvent Execute call uses the following parameters:

  • SubscriberID – The Marketing Cloud generated ID that uniquely identifies a subscriber.
  • SubscriberKey – The client supplied ID that uniquely identifies a subscriber.
  • EmailAddress – The email address of the subscriber.
  • JobID – The ID of the Job that sent the message.
  • ListID – The ID of the List that the subscriber belonged to. You can use subscriber or publication lists (not suppression lists).
  • BatchID – The ID of the Batch within the Job.
  • Reason – (Optional) The reason the subscriber is being unsubscribed.

The parameters can be divided into 3 sections:

  1. Subscriber context
  2. Job context
  3. Unsub reason

If you make this call from the parent unit of an Enterprise 2.0 account, ensure that you include the ClientID of the child business account to return information specific to that business unit.

Subscriber Context

The Subscriber Context is defined by the SubscriberID, SubscriberKey and EmailAddress parameters. You must supply at least one of these parameters. If you provide more than one of these parameters, we retrieve the Subscriber using one of the values and validate that the other values match the retrieved Subscriber. If they don’t match, an error returns.

If the SubscriberKey permission is turned on and you supply the EmailAddress parameter, you must supply either the SubscriberID or the SubscriberKey.

Job Context

The Job Context is defined by the JobID, ListID and BatchID parameters. These values are used to determine which Job the UnsubEvent is tracked against. The subscriber is also unsubscribed from the List that the Job was sent to. You don’t need to supply all three values. The system looks up any missing values using the following rules:

  1. If the JobID is supplied, we can lookup a missing ListID and/or BatchID.
  2. If the ListID is supplied, we can lookup a missing JobID and/or BatchID.
    1. If the JobID is missing, we use the most recent JobID that the subscriber was sent to.
    2. This may not be the Job that the Subscriber is acting upon.
  3. If only the BatchID is supplied, we cannot lookup the remaining information and the job context is not defined.

If the job context cannot be established because you did not supply any of these parameters or only supplied the BatchID, the UnsubEvent is not created. The subscriber is also Master Unsubscribed from the system of being unsubscribed from a particular list. Remove the ListID to address the All Subscribers list in an account.

Unsub Reason

This is used to specify the reason the subscriber is being unsubscribed from the system. If the reason is not supplied, the default value is used: Unsubscribed via Log Unsub Event Execute call.

Here is an example SOAP Request envelope:

<soap-ENV:Body>
<ExecuteRequestMsg xmlns="http://exacttarget.com/wsdl/partnerAPI"&gt;
<Requests>
<Name>LogUnsubEvent</Name>
<Parameters>
<Name>SubscriberID</Name>
<Value>123456</Value>
</Parameters>
<Parameters>
<Name>SubscriberKey</Name>
<Value>Key for username@example.com</Value>
</Parameters>
<Parameters>
<Name>EmailAddress</Name>
<Value>help@example.com</Value>
</Parameters>
<Parameters>
<Name>JobID</Name>
<Value>18099</Value>
</Parameters>
<Parameters>
<Name>ListID</Name>
<Value>17914</Value>
</Parameters>
<Parameters>
<Name>BatchID</Name>
<Value>0</Value>
</Parameters>
</Requests>
</ExecuteRequestMsg>
</SOAP-ENV:Body>

We will now look at three different ways to implement this solution on a CloudPage.

LogUnsubEvent using AMPscript

This is probably the most common way to use the LogUnsubEvent call. Below script will retrieve the SubscriberKey, JobId, ListId and BatchId if you link to the unsubscribe page from your email using the CloudPagesURL function. Depending on whether a list/publication list was selected for the send, it will unsubscribe a subscriber from that particular list, or it will unsubscribe the subscriber from all emails if you used All Subscribers.

<script runat="server">
Platform.Load("Core","1.1.1");
try{
</script>
%%[
VAR @skey, @jid, @reason, @lue, @lue_prop, @lue_statusCode, @overallStatus, @requestId, @Response, @Status, @Error
SET @skey = _subscriberkey
SET @jid = RequestParameter("jobid")
SET @listid = RequestParameter("listid")
SET @batchid = RequestParameter("batchid")
SET @reason = "AMPscript one click unsubscribe"
SET @lue = CreateObject("ExecuteRequest")
SetObjectProperty(@lue,"Name","LogUnsubEvent")
SET @lue_prop = CreateObject("APIProperty")
SetObjectProperty(@lue_prop, "Name", "SubscriberKey")
SetObjectProperty(@lue_prop, "Value", @skey)
AddObjectArrayItem(@lue, "Parameters", @lue_prop)
SET @lue_prop = CreateObject("APIProperty")
SetObjectProperty(@lue_prop, "Name", "JobID")
SetObjectProperty(@lue_prop, "Value", @jid)
AddObjectArrayItem(@lue, "Parameters", @lue_prop)
SET @lue_prop = CreateObject("APIProperty")
SetObjectProperty(@lue_prop, "Name", "ListID")
SetObjectProperty(@lue_prop, "Value", @listid)
AddObjectArrayItem(@lue, "Parameters", @lue_prop)
SET @lue_prop = CreateObject("APIProperty")
SetObjectProperty(@lue_prop, "Name", "BatchID")
SetObjectProperty(@lue_prop, "Value", @batchid)
AddObjectArrayItem(@lue, "Parameters", @lue_prop)
SET @lue_prop = CreateObject("APIProperty")
SetObjectProperty(@lue_prop, "Name", "Reason")
SetObjectProperty(@lue_prop, "Value", @reason)
AddObjectArrayItem(@lue, "Parameters", @lue_prop)
SET @lue_statusCode = InvokeExecute(@lue, @overallStatus, @requestId)
SET @Response = Row(@lue_statusCode, 1)
SET @Status = Field(@Response,"StatusMessage")
SET @Error = Field(@Response,"ErrorCode")
]%%
<script runat="server">
}catch(e){
Write(Stringify(e));
}
</script>
@Response: %%=v(@Response)=%%<br>
@Status: %%=v(@Status)=%%<br>
@Error: %%=v(@Error)=%%<br>

LogUnsubEvent using Server-Side JavaScript

The implementation of the LogUnsubEvent call in SSJS will be almost identical to the AMPscript solution, as the methods for accessing SOAP object data with SSJS are primarily wrappers around AMPScript functions.

Like in the previous example, the script will retrieve the SubscriberKey, JobId, ListId and BatchId if you link to the unsubscribe page from your email using the CloudPagesURL function and will unsubscribe a subscriber either from a list or All Subscribers, depending on which one you use at send time.

<script runat="server">
Platform.Load("core","1");
var subkey, jid, lue, lid, bid, lue_prop, Response;
var subkey = Attribute.GetValue("_subscriberkey");
var jid = Attribute.GetValue("jobid");
var lid = Attribute.GetValue("listid");
var bid = Attribute.GetValue("_JobSubscriberBatchID");
lue = Platform.Function.CreateObject("ExecuteRequest");
Platform.Function.SetObjectProperty(lue,"Name","LogUnsubEvent");
lue_prop = Platform.Function.CreateObject("APIProperty");
Platform.Function.SetObjectProperty(lue_prop, "Name", "SubscriberKey");
Platform.Function.SetObjectProperty(lue_prop, "Value", subkey);
Platform.Function.AddObjectArrayItem(lue, "Parameters", lue_prop);
lue_prop = Platform.Function.CreateObject("APIProperty");
Platform.Function.SetObjectProperty(lue_prop, "Name", "JobID");
Platform.Function.SetObjectProperty(lue_prop, "Value", jid);
Platform.Function.AddObjectArrayItem(lue, "Parameters", lue_prop);
lue_prop = Platform.Function.CreateObject("APIProperty");
Platform.Function.SetObjectProperty(lue_prop, "Name", "ListID");
Platform.Function.SetObjectProperty(lue_prop, "Value", lid);
Platform.Function.AddObjectArrayItem(lue, "Parameters", lue_prop);
lue_prop = Platform.Function.CreateObject("APIProperty");
Platform.Function.SetObjectProperty(lue_prop, "Name", "BatchID");
Platform.Function.SetObjectProperty(lue_prop, "Value", bid);
Platform.Function.AddObjectArrayItem(lue, "Parameters", lue_prop);
lue_prop = Platform.Function.CreateObject("APIProperty");
Platform.Function.SetObjectProperty(lue_prop, "Name", "Reason");
Platform.Function.SetObjectProperty(lue_prop, "Value", "SSJS one click unsubscribe");
Platform.Function.AddObjectArrayItem(lue, "Parameters", lue_prop);
var statusAndRequest = [0,0];
try{
Response = Platform.Function.InvokeExecute(lue, statusAndRequest);
Write(Stringify(Response))
}catch(e){
Write(Stringify(e));
}
</script>

LogUnsubEvent using WSProxy

WSProxy is a new object for Server-Side JavaScript, introduced by Salesforce in 2018. It acts as a proxy between the Marketing Cloud SOAP Web Service and SSJS. The WSProxy object is native to the platform and simpler to use than the SSJS methods. The object reduces overhead and increases the speed of your API calls.

Therefore, the below script is the most simple, and what’s more important, the fastest way to execute the LogUnsubEvent API call. In a speed test ran using the Chrome DevTools, it proved to be the fastest one to load on a CloudPage, with AMPscript just slightly slower and SSJS the slowest one, taking twice as much time to load.

Just like in the previous examples, the script will retrieve the SubscriberKey, JobId, ListId and BatchId if you link to the unsubscribe page from your email using the CloudPagesURL function and will unsubscribe a subscriber either from a list or All Subscribers, depending on which one you use at send time.

<script runat="server">
Platform.Load("Core","1.1.1");
var subkey = Attribute.GetValue("_subscriberkey");
var jid = Attribute.GetValue("jobid");
var lid = Attribute.GetValue("listid");
var bid = Attribute.GetValue("_JobSubscriberBatchID");
var prox = new Script.Util.WSProxy();
var props = [
{ Name: "SubscriberKey", Value: subkey },
{ Name: "JobID", Value: jid },
{ Name: "ListID", Value: lid },
{ Name: "BatchID", Value: bid },
{ Name: "Reason", Value: "WSProxy one click unsubscribe" }
];
try{
var data = prox.execute(props, "LogUnsubEvent");
Write(Stringify(data));
}catch(e){
Write(Stringify(e));
}
</script>

If you would like to find out more about logging an UnsubEvent or WSProxy, check out the following articles:

11 thoughts on “Unsubscribe and Log an UnsubEvent with a LogUnsubEvent Execute Call

  1. Stefano Crepaz

    Hi Zuzanna!
    thank you for this piece of documentation that helped me understand a customer’s use case.
    Yet, I do struggle to understand how LogUnsubEvent Execute Call interacts with Salesforce field “EmailOptOut”.
    Cheers!
    Stef

    Like

  2. Clare

    Hi Zuzanna, thank you for this.

    I have the same query as Stefano, how exactly does this interact with HasOptedOutOfEmail on the salesforce lead and contact objects? (I am using the connector) Is this just inbuilt?

    Clare

    Like

      1. Hi Zuzanna, thank you for the article! So just to be sure I understand. As long as Connect is feeding HasOptedOutOfEmail into Marketing Cloud contacts it will automatically suppress all commercial sends to those emails? I set up our CloudPage preference center to change HasOptedOutOfEmail to True, so want to be sure that works.

        Like

      2. Hi Koozie. In Sales/Service Cloud, you need to use the “Marketing Cloud Unsubscribe” button to make sure sends are suppressed. Take a look at the documentation: Enabling the Email Opt Out field only in Sales or Service Cloud does not synchronize the subscriber status in the Marketing Cloud. Always click Marketing Cloud Unsubscribe on the record. (https://help.salesforce.com/articleView?id=sf.mc_co_unsubscribes.htm&type=5). So in the direction Sales Cloud –> Marketing Cloud, it won’t suppress anything unless you click “Marketing Cloud Unsubscribe” for a given person.
        In the other direction, Marketing Cloud –> Sales Cloud, if you use LogUnsubEvent, the status in All Subscribers list will be changed to “unsubscribed” (which will suppress from sending) and it will sync back to Sales Cloud (the Email Opt Out field will be checked for that person).

        Like

  3. Hi Zuzanna,

    Thank you for the blog. In one of my use case, we have custom preference center by which we unsubscribe from different fields in sales cloud as per the selection. We do not have any “unsubscribe from all” in the cloud page and we would like to track the un-subscription of the different individual fields in Journey reporting. Any approach I can take on this!!
    Thanks ^_^

    Like

  4. Bertrand

    Hi Zuzanna, thank you for the article, awesome content !

    In the ampscript section, I guess it would be better to use “AttributeValue” function rather than “RequestParameter” for JobId, ListID and BatchID variables (as CloudPagesUrl function would probably not provide values this way, unless you add them as additional parameters in the function, which is not necessary as they are provided by default)

    So basically this part…
    SET @jid = RequestParameter(“jobid”)
    SET @listid = RequestParameter(“listid”)
    SET @batchid = RequestParameter(“batchid”)

    …should probably rather look like something like this 🙂
    SET @jid = AttributeValue(“jobid”)
    SET @listid = AttributeValue(“listid”)
    SET @batchid = AttributeValue(“_JobSubscriberBatchID”)

    cheers !

    Like

  5. Pragyanshu

    Hi,

    I have one question regarding unsublog event, can anyone confirm on the exact working of unsubevent?

    When i run this within Child BU it only unsubscribe a record from child BU which is because we have setup to unsub a record at BU level
    but when runnign this event on ent account, it again does not unsubscribes it from all the child BUs.

    Is there a way to mark a particular record unsubscribed for some specific BUs? consider there are 5 BUs then running the unsub log event should unsubscribe records from only 4 Business units ?

    Thanks for your response in advance

    Like

  6. Lindsay Shearstone

    Hi,

    A lot of the records on our seed lists for b2c email sends are being unsubscribed by an API Call. These records are not clicking the unsubscribe button at the bottom of the emails. Have you come across this at all or do you know how this can be prevented?

    Like

Leave a comment