Loading

Auditing Sender Domains and Email Addresses in Marketing Cloud Engagement

Publish Date: May 12, 2026
Description

This process automates the extraction of Domain Verification data via the Marketing Cloud REST API and logs it into a Data Extension. It then uses SQL to audit the log, specifically identifying individual user email addresses (e.g., user@gmail.com) that are verified in the system but send from domains not officially authenticated by a corporate Sender Authentication Package (SAP), Private Domain (PD), or registered domain.

Resolution

Part 1: Logging Domain Verification Data

To query the Domain Verification API, we first need a staging table to store the results, followed by a Server-Side JavaScript (SSJS) script to handle the API authentication and data routing.

1. Create the Staging Data Extension

Create a Data Extension to act as the target log for the API data.

  • Name: Domain_Verification_Log

  • External Key: Domain_Verification_Log

  • Fields:

    • Domain (Text 255) - Primary Key

    • Status (Text 50)

    • DomainType (Text 100)

    • IsSendable (Text 10)

2. Create the SSJS Script Activity

Create a Script Activity in Automation Studio and paste the following SSJS.

Note: You must replace the clientId, clientSecret, subdomain, and accountId variables with your specific Installed Package credentials and target Business Unit MID. Ensure the Installed Package has the Email -> Read or Administration -> Read scope.

<script runat="server">
Platform.Load("Core","1.1.1");

try {
    // 1. Setup API Credentials & Target BU
    var clientId = "YOUR_CLIENT_ID";
    var clientSecret = "YOUR_CLIENT_SECRET";
    var subdomain = "YOUR_TENANT_SUBDOMAIN"; 
    var accountId = "YOUR_BUSINESS_UNIT_MID"; // The MID of the specific BU you want to query

    var authUrl = "https://" + subdomain + ".auth.marketingcloudapis.com/v2/token";
    var domainRouteUrl = "https://" + subdomain + ".rest.marketingcloudapis.com/messaging/v1/domainverification"; 

    // 2. Authenticate with Account ID
    var authPayload = {
        grant_type: "client_credentials",
        client_id: clientId,
        client_secret: clientSecret,
        account_id: accountId // Scopes the token to the specific Business Unit
    };

    var authReq = new Script.Util.HttpRequest(authUrl);
    authReq.emptyContentHandling = 0;
    authReq.retries = 2;
    authReq.continueOnError = true;
    authReq.contentType = "application/json";
    authReq.method = "POST";
    authReq.postData = Stringify(authPayload);

    var authResp = authReq.send();
    var tokenData = Platform.Function.ParseJSON(String(authResp.content));
    var token = tokenData.access_token;

    if (token) {
        
        // 3. Fetch Domain Verification Data for the targeted BU
        var domainReq = new Script.Util.HttpRequest(domainRouteUrl);
        domainReq.emptyContentHandling = 0;
        domainReq.setHeader("Authorization", "Bearer " + token);
        domainReq.method = "GET";

        var domainResp = domainReq.send();
        var domainData = Platform.Function.ParseJSON(String(domainResp.content));
        var domains = domainData.items || [];
        
        var upsertCount = 0;

        // 4. Parse and Write to Data Extension
        for (var i = 0; i < domains.length; i++) {
            var item = domains[i];
            
            var domainName = item.domain;
            var status = item.status;
            var domainType = item.domainType;
            var isSendable = item.isSendable ? "True" : "False"; 
            
            if (domainName) {
                Platform.Function.UpsertData(
                    "Domain_Verification_Log", 
                    ["Domain"], [domainName], 
                    ["Status", "DomainType", "IsSendable"], 
                    [status, domainType, isSendable]
                );
                upsertCount++;
            }
        }
        
        Write("Successfully logged " + upsertCount + " domains from BU " + accountId + " to the Data Extension.");

    } else {
        Write("Authentication failed. Please check your Installed Package credentials and ensure it has access to BU " + accountId + ".");
    }
} catch (err) {
    Write("Error: " + Stringify(err));
}
</script>

Part 2: Identify Unverified/Rogue User Email Addresses

Once the Domain_Verification_Log Data Extension is populated, the next step is to audit the data to find individual email addresses that require manual review.

1. Create the Target Data Extension

Create a target Data Extension to store the results of the audit.

  • Name: Email addresses to review

  • External Key: Email_addresses_to_review

  • Fields:

    • domain (EmailAddress or Text 255) - Primary Key

2. Create the SQL Query Activity

Create an SQL Query Activity in Automation Studio with the following configuration:

  • Target Data Extension: Email addresses to review

  • Data Action: Overwrite

  • SQL Query:

SELECT 
    domain 
FROM 
    Domain_Verification_Log
WHERE 
    domaintype = 'userdomain' 
    AND SUBSTRING(domain, CHARINDEX('@', domain) + 1, LEN(domain) - CHARINDEX('@', domain)) 
    NOT IN (
        SELECT domain 
        FROM Domain_Verification_Log 
        WHERE domaintype != 'userdomain' 
        AND status = 'verified'
    )

Part 3: Automating the Process

To ensure your audit data remains up to date, place both activities into a single Automation in Automation Studio:

  1. Step 1: Add the SSJS Script Activity (populates the Domain_Verification_Log).

  2. Step 2: Add the SQL Query Activity (analyzes the log and populates Email addresses to review).

  3. Schedule: Set the Automation to run on your preferred auditing cadence (e.g., Weekly or Monthly).

Knowledge Article Number

005322014

 
Loading
Salesforce Help | Article