Skip to content

Salesforce Certified Marketing Cloud Developer Exam Guide

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 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
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 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 */ 

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

/* AMPscript tag */
<script runat=server language=ampscript>

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

/* Variable Assignment */
%%[ VAR @text
    SET @text = "Hello, world!"

/* 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 */

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 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('', 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, as well as information for the Authorization and User-Agent headings */
HTTPPost2('', '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

// Below SSJS statement will retrieve the value of AMPscript variable named newVar

//Set the Variable to be accessible in AMPscript

// Perform a Triggered Send to a List Using AMPscript and Server-Side JavaScript
SET @TSD = "TrigToAList"
<script runat=server>
    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

    //Set the Variable to be accessible in AMPscript
SET @PassedInListID = @ListID
FROM AMPscript ListID = %%=v(@PassedInListID)=%%
// Try Catch

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

// Retrieve data
<script runat="server">
   var dataRows = Platform.Function.LookupRows('Purchases', 'MemberID', memID);
  • 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}}
        { "target" : "@productList" }
    {{.datasource product type=nested maxRows = 10}}
            { "target" : "JSONVar.products" }

        <p>Name: {{name}}</p>
        <p>Colour: {{colour}}</p>
        <p>Price: {{=FormatCurrency(price, 'en-us', 2)}}</p>
  • 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

Continued on next page…

Pages: 1 2

Share this article...

Please Leave a Comment

error: Content is protected !!

Discover more from DYDC

Subscribe now to keep reading and get access to the full archive.

Continue reading