Contact Us

May 4, 2026

May 8, 2026 12:47 am

Building a Permanent Email Copy Library in SFMC: Screenshot APIs, AWS, and the View Email URL Problem

Share with

Here is a question that stops most Marketing Cloud teams cold: “Can you show me what our email from 18 months ago actually looked like?”

The instinct is to reach for the “View as Webpage” link — the %%view_email_url%% personalisation string that every sent email carries. Click it, the email renders. Simple. Except it isn’t, because that link is not a snapshot. It re-renders the email on demand by referencing the original Data Extension. When that Data Extension is deleted — by retention policies, cleanup scripts, or routine maintenance — the link renders an empty or broken email. Sometimes silently.

For businesses that need a genuine historical record of their email communications — for content strategy, compliance, creative review, or stakeholder reference — the view email URL is not a reliable archive. You need to capture the email at the moment it was sent and store it permanently.

Email archive and documentation

Why the View Email URL Is Not an Archive

When a subscriber clicks “View as Webpage,” Marketing Cloud doesn’t serve a saved copy of the email. It re-renders the email template in real time, pulling personalisation values from the subscriber record and any Data Extensions referenced in the email content.

If any of those referenced Data Extensions have been cleaned up — or if the subscriber record has changed — the rendered email will look different from, or nothing like, what was actually sent. For highly personalised sends, the link is essentially unreliable as a historical reference almost immediately after data retention policies kick in.

The compliance angle: In regulated industries — financial services, healthcare, insurance — there may be a legal requirement to retain copies of customer communications for defined periods. The view email URL cannot satisfy this requirement. A properly archived screenshot stored in durable storage can.

The Solution: Capture at Send Time, Store Permanently

The architecture captures a visual screenshot of each email at send time using a third-party screenshot API, then stores the screenshot URL permanently — both in a Marketing Cloud Data Extension and on AWS S3 for durable, stakeholder-accessible storage.

Step 1: Capture the View Email URL in the Send Log

Add view_email_url as a column in your Send Log Data Extension. Marketing Cloud automatically populates this personalisation string for every send record. A nightly SQL query identifies new Job IDs with no screenshot yet and selects one representative subscriber per job — you only need one URL per Job ID for template-level archiving.

SQL — Select One Representative URL Per New Job ID

SELECT DISTINCT s.JobID, s.EmailName,
    s.EventDate AS SendDate,
    FIRST_VALUE(s.ViewEmailURL) OVER (
        PARTITION BY s.JobID ORDER BY s.EventDate
    ) AS RepresentativeURL
FROM SendLog s
LEFT JOIN EmailCopyLibrary lib ON lib.JobID = s.JobID
WHERE lib.JobID IS NULL  -- Only new sends not yet screenshotted
  AND s.EventDate >= DATEADD(day, -90, GETDATE())

Step 2: Call the Screenshot API

ScreenshotOne (screenshotone.com) accepts a live URL, opens it in a headless browser, and returns a screenshot — ideal for new emails where you have a valid view email URL. Pricing is ~$17/month for 2,000 screenshots, which comfortably covers most enterprise email programmes.

HTML/CSS to Image (hcti.io) accepts raw HTML content directly — ideal for archiving older emails where you don’t have view email URLs but can retrieve the email HTML via Marketing Cloud’s Assets API.

SSJS — Calling ScreenshotOne API and Storing the Result

Platform.Load("Core", "1");
var jobID    = /* from current DE record */;
var emailURL = /* view email URL from Send Log */;
var apiKey   = "YOUR_SCREENSHOTONE_API_KEY";
var endpoint = "https://api.screenshotone.com/take?access_key="
             + apiKey + "&url=" + Platform.Function.URLEncode(emailURL)
             + "&format=jpg&full_page=true&delay=5";
var response = HTTP.Get(endpoint);
if (response.StatusCode === 200) {
    var screenshotURL = response.Headers["X-Screenshot-URL"];
    Platform.Function.UpsertDE("EmailCopyLibrary",
        ["JobID"], [jobID],
        ["ScreenshotURL", "CapturedAt"],
        [screenshotURL, Platform.Function.Now()]);
}

Step 3: Handling Old Emails Without View Email URLs

For emails sent before this system was implemented, the Marketing Cloud Assets API provides a fallback — it returns the raw HTML of any email template by Asset ID, which is passed directly to HTML/CSS to Image for rendering.

Cloud storage and AWS architecture

The Email Copy Library Cloud Page

Once screenshots are captured and URLs stored, a secure Cloud Page gives business stakeholders a browsable, searchable library of all sent emails — without requiring Marketing Cloud access. It supports search by email name, journey, date range, and business unit, with each result card showing the screenshot, send date, and key KPIs. All behind Okta SSO authentication.

Screenshot Service Comparison

  • ScreenshotOne — Best for live view email URLs. Headless browser render. ~$17/month for 2,000 screenshots. Configurable render delay for image-heavy emails.
  • HTML/CSS to Image — Best for raw HTML from Assets API (old emails). Handles SFMC encoding artifacts natively. Returns permanent image URL.
  • JavaScript (html2canvas) — Free but cannot capture SFMC-hosted images due to CORS restrictions. Not suitable for image-heavy emails.
  • AWS S3 storage — Screenshot URLs stored permanently. Negligible cost. Independently durable with no dependency on SFMC data retention.

Frequently Asked Questions

If we send to 100,000 subscribers, do we take 100,000 screenshots?
No — one screenshot per unique Job ID. A single send to 100,000 subscribers has one Job ID. You capture one representative subscriber’s view email URL and screenshot that. The result is a template-level snapshot, not a personalised copy for each recipient.
What about highly personalised emails where each subscriber sees different content?
For significant personalisation, you can capture multiple representative snapshots per job — one per major content variant — by selecting one subscriber per personalisation segment. This increases API calls but gives a more complete picture.
Is there a risk of SSJS timeout when processing large backlogs?
Yes — batch the processing to 20–50 records per automation run and iterate over days or weeks until the backlog is cleared. Don’t attempt to process all historical assets in a single execution.
What if we prefer not to use a Cloud Page for the library?
AWS S3 is a perfectly functional fallback. Screenshot files stored in S3 are accessible directly via S3 URLs or through a simple S3-hosted static website — fully independent of Marketing Cloud.
Genetrix Technology · Salesforce Marketing Cloud Partner

Need a permanent archive of your Marketing Cloud email history?

Genetrix designs and implements email archiving systems, screenshot capture pipelines, and stakeholder-accessible copy libraries for Marketing Cloud. Whether you’re building forward or need to recover historical records, we can help.

Get in Touch with Genetrix →

Blogs for the

Business-Savvy!​

Let’s Connect

A 30 min no cost strategy session
with cloud support expert

Let’s Connect

A 30 min no cost strategy session
with cloud support expert