Salesforce Certified Marketing Cloud Developer Exam Guide.

The Salesforce Marketing Cloud Developer credential is for developers who has experience developing dynamic, personalized marketing assets such as emails, landing pages, and forms leveraging HTML, CSS, SQL, AMPscript and Marketing Cloud APIs.

1. About Salesforce Marketing Cloud Developer Exam

  • Content: 60 multiple-choice/multiple-select questions, up to 5 unscored questions
  • Time allotted to complete the exam: 105 minutes
  • Passing score: 63% (38 out of 60 Questions)
  • Registration fee: USD 200, plus applicable taxes as required per local law
  • Retake fee: USD 100, plus applicable taxes as required per local law
  • Prerequisite: Salesforce Certified Marketing Cloud Email Specialist credential

2. Salesforce Marketing Cloud Developer Exam Guide

3. Salesforce Marketing Cloud Developer Trail

4. Salesforce Marketing Cloud Developer Exam Outline

Data Modeling: 14%

  • Configure account Contact model in Marketing Cloud.
  • Given a scenario, differentiate the various types and uses of data extensions in Marketing Cloud.
  • Describe how Contact Records relate across channels.
  • Explain the Contact Delete process.

Programmatic Languages: 35%

  • Given a scenario, demonstrate knowledge of AMPscript and SSJS language syntax and functions.
  • Implement standard development best practices using Marketing Cloud programming languages.
  • Describe how Marketing Cloud handles AMPscript processing.
  • Given a customer scenario, determine how to programmatically exclude a subscriber at email send time.

API: 22%

  • Given a scenario, describe API objects, methods, and routes.
  • Describe the OAuth authentication flow and how an access token is used in SOAP and REST headers.
  • Given a scenario, evaluate the significance of response handling.

Data Management: 22%

  • Configure import activity using various file formats within Marketing Cloud.
  • Given a scenario, apply SQL to produce the desired results.
  • Given a scenario, explain the different ways to extract data from Marketing Cloud.
  • Describe SQL best practices for managing data in Marketing Cloud.
  • Given a scenario, apply best practices for send logs.
  • Given a scenario, describe how data is affected by the Contact delete process.

Security: 7%

  • Identify different options to secure data in Marketing Cloud.
  • Describe security best practices in Marketing Cloud.

5. Important Topics for Salesforce Marketing Cloud Developer Exam

This article covers important topics not already covered in Salesforce Certified Marketing Cloud Consultant Exam Guide as both of these exams have a lot of overlapping topics.

5.1 Data Modeling: 14% (8 Questions)

  • Configure account Contact model in Marketing Cloud
  • Types of Data Extensions
    • Standard
    • Filtered
    • Random
  • Data extensions can be non-sendable or sendable
    • Non-sendable data extensions are reference data
    • Sendable data extensions have a send relationship and map to a subscriber. Contacts are added to All Contacts when you send to them
  • The view as web page link refers to a record in the sendable data extension, not the HTML of the email received
  • Email Studio vs Contact Builder Features
Email StudioContact Builder
Create/Import/Export/Delete
Create Filtered Data Extension
Clear Data From Data Extension
Add/Edit/Clear Individual Records
Manage Policies
View Related Tracking Information
  • By default, the data extension retention policy deletes unused data extensions after 6 months. The deletion process runs nightly
  • You cannot remove the configured data retention settings on a data extension once you configure them
  • Retention settings must be enabled when creating a data extension. You can modify the data retention policy for existing data extension where retention settings were enabled at creation
  • Contact information synchronized from Sales or Service Cloud appears in All Contacts, even if you don’t send a message to them
  • Attribute groups are data sources that are logically grouped together, and they allow you to organize data and configure relationships in Contact Builder
  • Populations are used to categorize distinct subgroups of contacts. Limit populations to three or fewer to improve performance
  • Contact Deletion Process – applies only to Email Studio, MobileConnect, MobilePush, and Contact Builder
  • For Enterprise 2.0, the enablement of Contact Deletion feature occurs at parent account level
  • Contact deletion deletes contact from lists and sendable data extensions
  • Default suppression for contact deletion is 14 days but can be changed to 0 to immediately delete contacts
  • Contact deletion limit per request batch is one million contacts
  • Synchronized data extensions can not be deleted
  • Use OperationID values to follow up on invalid or processing contact deletion requests with ‘/contacts/v1/contacts/actions/delete/status?operationID=’ resource
  • To make the deletion process faster, delete any sendable data extensions you don’t need
  • Marketing Cloud prevents contacts from reintroducing themselves into your account while the suppression period continues
  • Contact deletion process takes less precedence than other account activities, such as sends, imports, automations, and queries 
  • For Synchronized Data Sources, delete the information from the original data source in Sales Cloud, Service Cloud, or another cloud. This deletes the corresponding record in the Synchronized Data Extension, but it doesn’t delete the contact record from Marketing Cloud

5.2 Programmatic Languages: 35% (21 Questions)

  • Salesforce Marketing Cloud Programming Languages
AMPscriptAMPscript suitable for efficient inline personalization or simple if-else statements
AMPscript can be used where each subscriber needs to see unique content
AMPscript has a shorter learning curve than SSJS
Server Side JavaScript
(SJJS)
Apply knowledge of JavaScript
SSJS can be executed as an activity in Automation Studio ( such as 3rd party integrations not achievable with FTP & SQL)
SSJS can’t interact with the DOM
Use SSJS when AMPscript function is not enough
SSJS can use Arrays, EVAL and Advanced Exception handling
Guided Template Language
(GTL)
GTL accelerates creation of repeatable content blocks using fewer lines of code than AMPscript
GTL is recommended way to parse JSON
GTL use cases – order receipts, abandoned carts
  • AMPscript Variables, Attributes and Constants
1. %%[
2.     VAR @productName, @inStock, @expirationDate /* Declare Variable */
3.     SET @productName = [Product Name] /* Product Name is an attribute */
4.     SET @inStock = true
5.     SET @expirationDate  = "01/01/2022" /* Declare Constant */
6. ]%%
  • AMPscript Syntax
/* Inline AMPscript */ 
%%=LOWERCASE(Name)=%%

/* AMPscript block */ 
%%[ LOWERCASE(Name) ]%%

/* AMPscript tag */
<script runat=server language=ampscript>
   Lowercase(Name)
</script>

/* For Loop */
%%[FOR @Position = '1' TO @Position = @rowCount DO ]%%
   SET @FirstName = FirstName
%%[NEXT @Position]%%

/* Variable Assignment */
%%[ VAR @text
    SET @text = "Hello, world!"
    Output(v(@text))]%%

/* Variable Assignment from DE */
set @attributeName = [attributeName]

/* AttributeValue function will return null if the attribute is not available in the data source*/
set @attributeName = AttributeValue("attributeName") 
/* Character Functions */
Concat('string1', 'string2', 'string3')

IndexOf('Variable to analyze'
,'Character position to return index begins with 1')

ReplaceList('String value to search', 'Replacement string
', 'String values to replace using replacement string'
)

Uppercase('Value to return')

Format(Now(), "MMMM d, yyyy")

FormatDate(Now(), "MMMM d, yyyy")
/* Data Extensions*/

Lookup('Name of data extension from which to return the specified value',
 'Name of column from which to return a value',
 'Name of column used to identify row containing lookup value',
 'Value to match string against')

/* Below example will return City as Somerset NJ. Less than 3 lookups is a best practice */
Lookup('PostalCode', 'City', 'PostalCode', 08873)

LookupRows('Name of data extension from which to return specified rows',
 'Column name used to identify rows to return',
 'Value used to match rows to return')

/* Below example returns the ZipCode rows where the City field matches for Edison.
   Returns a maximum of 2000 rows */
LookupRows('ZipCode', 'City', 'Edison')


LookupOrderedRows('Name of data extension from which to return specified rows',
 'Number of rows to return. A value less than 1 returns the default 2000 rows',
 'Defines order of return as field ASC or field DESC',
 'Field to use to build WHERE clause',
 'Value to use to build WHERE clause')

/* This call returns the 4 rows from the Cars data extension with the highest horsepower that match the value specified by MPG */
Set @rows2 = LookupOrderedRows("Cars", 4, "Horsepower Desc",  "MPG", Field(@cardata, "MPG"))


UpsertDE('Name of data extension from which to update the specified row',
 'Number of columns used to build WHERE clause',
 'Column name to build WHERE clause',
 'Value used to build WHERE clause',
 'Column name to build INSERT clause',
 'Value used to build INSERT clause')

/*Below example will update SendDE DateSent field with NOW() if a matching SubscriberKey is found or else will insert a row  */
UpsertDE('SendDE', 1, 'SubscriberKey', SubscriberKey, 'DateSent', Now())
/* Content Functions */

BuildRowSetFromString('Value used to create rowset',
 'Character used as delimiter, such as a comma')

/* Below example returns a rowset with three rows */
BuildRowsetFromString('123|456|789', '|')


ContentBlockbyKey('1. External key of the content block to return',
 '2. Name of the impression region to start',
 '3. Determines whether the function returns an error when the system cannot locate the specified content area or returns an invalid content area. A value of true returns an error. A value of false does not return an error. Defaults to true',
 '4. Default content to return if an error occurs. Defaults to an empty string',
 '5. Output parameter that returns the status of the call. A value of 0 indicates the function found the content area and successfully rendered the content. A value of -1 indicates either no content or an invalid content area')

/* Below example returns the content of content area myContentBlock */
ContentBlockbyKey("myContentBlock")


TreatAsContentArea('1. Key value used to identify the content specified in the second string',
 '2. Content stored for an email send under the key specified in the first string',
 '3. Impression region name for the virtual content area used for tracking purposes')

/* The sample code below pulls content from a data extension and saves it for reuse as a virtual content area under the key VirtualCA1 */
TreatAsContentArea('VirtualCA1', Lookup('DEName', 'DEContentColumn', 'KeyField',  KeyValue))
/* HTTP */

HTTPGet('1. URL from which to return content',
 '2. Defines whether the process continues on error. Defaults to false. A value of true ignores errors in process',
 '3. Defines whether the function allows empty content. A value of 0 allows for empty content. A value of 1 returns an error. A value of 2 skips the subscriber',
 '4. Output of function status. This function defaults to 0. A value of 0 indicates status is OK. A value of -1 indicates a missing URL. A value of -2 indicates an HTTP request error. A value of -3 indicates empty content; the function completed successfully but did not return any content')

/* Below example System returns the content of http://www.example.com. The function stops if it encounters an error, and it allows empty content. The status of the function is returned to the declared variable @CallStatus */
HTTPGet('http://www.example.com', false, 0, @CallStatus)


HTTPPost2('1. URL to receive posted content',
 '2. Specified content-type header value',
 '3. Content to post to specified URL',
 '4. Indicates whether call returns an exception for error. True indicates the system returns an exception',
 '5. Output parameter used to contain string representation for the status of the HTTP request, such as OK',
 '6. Output parameter used to contain returned response body information from the HTTP POST request',
 '7. Name of additional headers to add to HTTP POST request',
 '8. Value of additional headers to add to HTTP POST request')

/* This example posts a blank payload to www.example.com, as well as information for the Authorization and User-Agent headings */
HTTPPost2('http://www.example.com/', 'text/html', '', true, @output, @respheader, 'Authorization', 'Example', 'User-Agent', 'Example')

RedirectTo('URL sting or variable containing URL string to which to redirect')
  • Personalization strings return data from Email Studio lists. Use AMPscript functions to return content from data extensions in other Marketing Cloud functions
  • Impression Tracking
    • BeginImpressionRegion()
    • EndImpressionRegion()
  • AMPScript comment syntax:
    • /* Insert Comment Here */
  • AMPscript processes functions in this order :
    1. HTML Body (Any preheader values reside at the beginning of the body and process accordingly)
    2. Text Body
    3. Subject Line
  • Given a customer scenario, determine how to programmatically exclude a subscriber at email send time (Exclusion Script)
  • SSJS Core Function – To personalize landing pages and create applications to run on Marketing Cloud
  • SSJS Platform Functions – To work with messages, landing pages, and applications
  • SSJS Syntax
// SSJS Blocks

<script runat="server">
Platform.Load("Core", "1")
// SSJS Code here
</script>

// Below SSJS statement will retrieve the value of AMPscript variable named newVar
Variable.GetValue("@newVar");

//Set the Variable to be accessible in AMPscript
Variable.SetValue("@ListID",Stringify(ListID));

// Perform a Triggered Send to a List Using AMPscript and Server-Side JavaScript
%%[
VAR @TSD, @ListID
SET @TSD = "TrigToAList"
]%%
<script runat=server>
    Platform.Load("Core","1");
    var TSD = Variable.GetValue("@TSD");
    var results = TriggeredSend.Retrieve({Property:"CustomerKey",SimpleOperator:"equals",Value:TSD});
    var count = results.length;
    var ListID = results[0].List.ID;

    //Write the result
    Write(Stringify(ListID));

    //Set the Variable to be accessible in AMPscript
    Variable.SetValue("@ListID",Stringify(ListID));
</script>
%%[
SET @PassedInListID = @ListID
]%%
FROM AMPscript ListID = %%=v(@PassedInListID)=%%
// Try Catch

<script>
    try {
        //SSJS Code
    } catch(error) {
        Write('Error: ' + Stringify(error)); 
    }
</script>

// Retrieve data
<script runat="server">
   var dataRows = Platform.Function.LookupRows('Purchases', 'MemberID', memID);
</script>
  • Display values in HTML using SSJS
<!-- Display value in HTML -->

<!-- Accessing an Attribute Name -->
<ctrl:field name=AttributeName />

<!-- Accessing a DE Field -->
<ctrl:field name=DEFieldName />

<!-- Accessing an Attribute Name with Default Value-->
<ctrl:field name=AttributeName default = "Default Value"/>

<!-- Accessing a Variable -->
<ctrl:var name=AttributeName />

<!-- Accessing Functions -->
<ctrl:eval language=javascript default=none format=G>MyVal.toUpper()</ctrl:eval>
  • SSJS supports the following methods:
    • Add – Invokes the web service API Create method on an API object
    • Remove – Invokes the web service API Delete method on an API object
    • Update – Invokes the web service API Update method on an API object
    • Retrieve – Invokes the web service API Retrieve method on an API object
  • Guide Template Language (GTL) is a Salesforce Marketing Cloud proprietary language bases on MustacheJS and HandleBarsJS. Recommended for parsing JSON and creation of repeatable content blocks. GTL + JSON is fater than AMPscript + XML
  • GTL Data Sources
    • AMPscript
    • Data Extension
    • REST API Service
GTL to display content in an email

%%[ 
    var @productList 
    set @productList = '{ "products":[ { "name":"iphone 13", "colour":"blue", "price":"999.99"}, { "name":"apple watch", "colour":"grey", "price":"399.99"} ] }' 
]%%

{{.datasource JSONVar type=variable maxRows = 10}}
    {{.data}}
        { "target" : "@productList" }
    {{/data}}
    {{.datasource product type=nested maxRows = 10}}
        {{.data}}
            { "target" : "JSONVar.products" }
        {{/data}}

        <p>Name: {{name}}</p>
        <p>Colour: {{colour}}</p>
        <p>Price: {{=FormatCurrency(price, 'en-us', 2)}}</p>
        <br>
    {{/datasource}}
{{/datasource}}
  • You can change a Data Extension into a Suppression List without exporting and importing your Subscribers using the Exclusion script feature with Triggered Send or User-Initiated Send Definitions. The Exclusion script uses AMPscript and the personalization strings on the Data Extension to match email addresses in the Data Extension with email addresses defined in the Triggered Send. If a match is found, the row count value returned is 1. Because the value is greater than zero, the condition has been met and the subscriber is not sent to.
ROWCOUNT(LOOKUPROWS("1. Suppression", "2. Email Address", "3. emailaddr"))> 0

/*
1. Suppression -  Name of the Data Extension to exclude from.
2. Email Address -  Name of the Email field in your Data Extension.
3. emailaddr - The email address value you're passing in the API call. emailaddr is a system defined personalization string so you'll use emailaddr if you want to match on email address or _subscriberkey if you want to match on Subscriber Key
*/

5.3 API: 22% (13 Questions)

  • Given a scenario, describe API objects, methods, and routes
  • Describe the OAuth authentication flow and how an access token is used in SOAP and REST headers
  • Given a scenario, evaluate the significance of response handling
  • SOAP Vs REST
SOAPREST
 Email Sending
Templates and Content Areas
Data Extensions
Folders
Administration (Users, BUs)
Automation Studio
Email Tracking Data
Subscribers and Lists
SOAPREST
MobileConnnect (SMS)
MobilePush
Salesforce Sends
Contact Model
Journey Builder
OAuth Tokens
Content Builder
  • Marketing Cloud REST API routes
REST APIRoute
Content Builder/asset/v1/content
Event Notification Service/platform/v1
Journey Builder/interactions/v1
Transactional Messaging
/messaging/v1/email
/messaging/v1/sms
Triggered Send/messaging/v1/messageDefinitionSends
  • REST API
    • JSON
    • Maximum Payload Size is 4MB
    • Request time out – 120 seconds and 300 seconds for tracking requests
  • SOAP API
    • XML
    • Supports Username and password authentication
    • Request time out – 3 second for single email send, 30 second for tracking data
    • Most API objects return results in batches of 2,500
  • SOAP API – 20 or fewer synchronous API threads per request with references to up to 50 objects per synchronous call or 100 objects per asynchronous call
  • You can retrieve tracking information on the send using JobID
  • You can retrieve the status of API call using RequestId property on ResultItem object  
  • Marketing Cloud SOAP API common key methods
    • Retrieve – Get information on a single object type
    • Configure – Configure a Marketing Cloud account
    • Perform – Perform an asynchronous action
    • Extract – Extract a file to the Marketing Cloud FTP site
  • DataExtension – Represents a Data Extension (name, attributes, retention policies, etc) where as DataExtensionObject – Represents a row within a Data Extension
  • Installed package Integration Type
    • Server-to-Server with Client Credentials Grant Type
    • Web and Public App Integrations with Authorization Code Grant Type
  • A web app can securely store a client secret, but a public app cannot
  • OAuth token is only valid for 18 minutes (actual expiry is 20 minutes but needs to refreshed before 18 minutes)
  • LogUnsubEvent call allows you to unsubscribe a subscriber and log an UnsubEvent that is tracked against a specific Job
    • The Subscriber Context is defined by the SubscriberID, SubscriberKey and EmailAddress parameters
    • The Job Context is defined by the JobID, ListID and BatchID parameters
    • Unsub Reason is used to specify the reason the subscriber is being unsubscribed from the system
  • REST Error Codes
Error CodeCause
401Unauthorised – token expired
429API throttling
  • SOAP Error Codes
Error CodeCause
Error Code 2Authentication
Error Code 5Cannot perform {method} on objects of type {object}
Error Code 8This operation does not support the APIObject of type [type]
Error Code 11SOAP Web Service API feature is not enabled

5.4 Data Management: 22% (13 Questions)

  • Configure import activity using various file formats within Marketing Cloud
  • Types of Data Extract
    • Convert XML
    • Data Extension
    • ZIP Data
    • Tracking Data
  • Given a scenario, apply SQL to produce the desired results
  • Given a scenario, explain the different ways to extract data from Marketing Cloud
  • Describe SQL best practices for managing data in Marketing Cloud
  • Given a scenario, apply best practices for send logs
  • Send Logging can be enabled at Parent or Child Business Unit
  • It’s best practice to add 10 or fewer custom fields to the Send Log
  • Content Builder test sends are not recorded on Send Log Data Extensions
  • To record the new send log, ensure that you pause, republish, and restart triggered sends and Journey Builder triggered sends
  • SQL commands are not case sensitive: select is the same as SELECT
  • SQL Queries time-out after 30 minutes
  • SQL Query Activity is based on Microsoft SQL Server 2016
  • Avoid Data Extensions where the sum of the length of all attributes is greater than 4000 characters
  • SQL Join Statement
-- Inner Join
SELECT customerID as ‘customerID’, amount as ‘Total_Amount’
FROM CustomerDataExtension c
INNER JOIN BillingDataExtension b
ON c.customerID = b.customerID
WHERE b.amount is not NULL

-- Some other joins important for exam LEFT JOIN, RIGHT JOIN and FULL OUTER JOIN
  • Sample SQL Queries
-- Query Complaint Data view
SELECT SubscriberKey, JobID, SMTPBounceReason 
FROM _Complaint

-- Get Parent Account data by adding ent prefix to the Data Extension name
SELECT Name 
FROM ent.DataExtension

-- Get All the fields by using * 
SELECT *
FROM DataExtension

-- Select random 10 percent records
SELECT TOP 10 PERCENT Id, Name FROM customerNames
ORDER BY NEWID()
  • Queries that include both a join and a Select * statement are not permitted
  • Query Failure Possible Reasons
    • Query failed during execution. Error: Violation of PRIMARY KEY constraint. Can’t insert duplicate key in object ‘{{DE name}}’
    • Query failed: Timeout
    • Query failed during execution. Error: Conversion failed when converting the nvarchar value ‘123ABC’ to data type int
    • Query Source has a longer field length than the Destination field
    • Inserting null into a field which does not allow null values

5.5 Security: 7% (5 Questions)

  • Identify different options to secure data in Marketing Cloud
  • Audit Trail is available to all Marketing Cloud accounts and provides 30 days of information
  • Describe security best practices in Marketing Cloud
  • Transparent Data Encryption
  • Type of Encryption
    • Asymmetric – requires a pre-created certificate uploaded from your computer to your Salesforce Marketing Cloud account
    • Symmetric – requires you to create a passphrase for use with the key
    • Initialization vector – requires you to enter the block of bits to be used as the initialization vector
    • Salt – requires a hex value longer than 8 bits for use as a salt value
    • SAML -allows you to provide either the required metadata or the URL from which to retrieve that metadata to use this feature
  • Encrypt and Decrypt Data with AMPscript 
%%[
     SET @encData=EncryptSymmetric("ExampleData", "AES", "passwordExternalKey", @null, "saltExternalKey", @null, "IVExternalKey", @null)
     SET @clearData=DecryptSymmetric(@encData, "AES", "passwordExternalKey", @null, "saltExternalKey", @null, "IVExternalKey", @null)
]%%
  • Salt keys can be used to encode JSON Web Token (JWT) information in a Journey Builder activity
  • Use SSL Certificates to Secure
    • CloudPage URLs
    • Landing Pages
    • Links included in email messages from Email Studio
    • Portfolio Content
  • Field Level Encryption – converts encrypted fields to plain text at the time of sending
  • Data at Rest Encryption (Transparent Data Encryption) – encrypts data at rest using SQL Server’s built-in data protection technology
  • Tokenized Sending – take information from your own data systems and transmit it to the Marketing Cloud only at send time via an API call. Instead of storing sensitive information in your Marketing Cloud account database, your account stores a single token per send attribute. This token resembles a standard email address or phone number but does not include any information about the contact
  • Data at Rest Encryption is not available for
    • Predictive Intelligence
    • Audience Builder
    • Social Studio
  • Marketing Cloud Shield combines security products to provide trusted encryption solutions with advanced Audit Trail functionality
  • Marketing Cloud supports PGP or GPG decryption and encryption

6. Additional Resources

Salesforce Marketing Cloud Developer Certificate

Recommended Reading

Please Leave a Comment