Menu

Email Screenshots

See a captured email the way Gmail, Outlook and other clients show it, light and dark, from the dashboard, the API and SDK, or an AI agent.

10 min read Updated

Email screenshots render a captured email the way a real email client displays it. Pick a client and a theme and you get back a picture of the message after that client has rewritten it: the CSS it dropped, the width it gave the message, the colours it swapped in dark mode. No device, no virtual machine.

Every render also comes with findings, a list of what the client changed, so a test or an agent can act on the result without looking at the picture.

Email screenshots are in beta. Every render runs in one browser engine standing in for the client's own, so read it as a guide to what a client drops, clips or recolours, not as a pixel match, and expect the occasional render that is off. Report one with the flag on the render.

Screenshots are available on every plan. The Free plan renders Gmail on the desktop web only; Basic and up render every client, light and dark.

Rendering from the dashboard

  1. Open a captured email and switch to the Client screenshots tab.
  2. Tick the clients and themes you want, or open one row and click Render.
  3. Click a rendered row to see it, or open it full size to zoom in.

A render is stored for seven days. Opening the same email again shows the stored picture without spending another preview; after seven days the row goes back to Render.

Reading a render

Each render carries a fidelity tier, because some clients are easier to reproduce than others:

TierMeaning
AThe client passes HTML through untouched. The render matches the viewport, fonts and chrome, and the picture is close to what lands in the inbox.
BThe client rewrites the message and the render applies that rewrite: the properties it strips, the tags it replaces, the dark-mode colour walk. Trust what was dropped and how the layout reflowed.
B-Same as B, against an engine the renderer cannot reproduce (a WebKit client, or classic Outlook's Word engine). Trust "this declaration is dropped"; do not trust the exact place a line wraps.

Two limits apply to what a render can show:

  • Remote images are fetched by the renderer, so a template that loads its logo from your CDN renders with the logo. Inline cid: images from the email's own attachments are embedded too, when they are PNG, JPEG, GIF or WebP. An SVG shows as the broken-image placeholder, remote or inline, and so it does in Gmail.
  • The HTML part must be under 2 MB. An email with no HTML part cannot be rendered.

Dark mode is a separate render, not a filter over the light one. Some clients recolour every colour in the message, some only the ones you did not set, and Gmail on the desktop web leaves the message alone, so it has no dark variant.

Clients

These are the clients you can render today. Each has been compared against the real client before it was published; we add more as they pass that check.

ClientDeviceTierDark mode
Gmail (desktop web)Desktop, 1600 px window, 1200 px columnBNo, Gmail on the web does not recolour messages
Gmail for AndroidPhone, 385 px, 336 px columnBYes
Gmail for iOSPhone, 390 px, 361 px columnBYes
Outlook.com (web)Desktop, 1600 px window, 1089 px columnBYes
Proton Mail (web)Desktop, 1600 px window, 1212 px columnALight only for now
Seznam Email (web)Desktop, 1600 px window, 1234 px columnAYes
Outlook for Windows (classic)Desktop, 1600 px window, 1016 px columnB-Yes
Outlook for Windows (new)Desktop, 1600 px window, 1073 px columnBLight only for now
Apple Mail (macOS)Desktop, 1024 px window, 800 px columnAYes

Rendering from the API and the SDK

The REST API renders the same way the dashboard does: same clients, same quota, same seven day storage. All three calls need the emails:screenshot scope on the API key.

CallWhat it does
GET /v1/email-clientsLists the clients in the table above with their ids, fidelity tier and whether your plan includes them, plus the monthly quota. Needs no email.
GET /v1/sandboxes/{sandboxId}/emails/{emailId}/screenshotsLists every client and theme you can render, marks the ones with a stored render, and returns the monthly quota.
POST /v1/sandboxes/{sandboxId}/emails/{emailId}/screenshotsRenders one client in one theme and returns the stored render with a signed url.

With the JavaScript SDK:

TYPESCRIPT
import { writeFile } from 'node:fs/promises';

const email = await client.emails.waitFor(sandbox.id, { subject: 'Welcome' });

const shot = await client.screenshots.create(sandbox.id, email.id, {
  client: 'gmail-web',
  theme: 'light'
});

await writeFile('welcome-gmail.png', await client.screenshots.download(shot));

The url on a render works without an API key for 30 minutes (urlExpiresAt); list the screenshots again for a fresh link to the same stored image. The REST API returns the picture and its fidelity fields. Findings come from the MCP tool below.

Rendering from an AI agent

The MCP server exposes two tools. Both need the emails:screenshot scope on your API key or OAuth grant.

list_email_clients returns the catalogue above, so the agent picks a client id it can actually get instead of guessing one.

screenshot_email renders one captured email:

ArgumentDescription
email_idThe captured email. It must belong to your organization.
clientsProfile ids from list_email_clients. Up to 4 per call; how many your plan allows per render is in the table below. Defaults to gmail-web.
themelight or dark. A client that does not support dark refuses the request rather than rendering light.
forceRender again although a stored render exists. Spends a preview; only useful when the stored image no longer loads.
block_imagesRender without fetching remote images, the way a client with images off shows the message. Counted as a preview, but not stored or shown in the dashboard.
tileReturn a tall email as several images instead of clipping it. Counted, not stored, like block_images.

Every call renders: the result carries, per client, the image, fidelityTier, engineMismatch, findings and approximations.

A render made by an agent is the same render as one made in the dashboard or through the API. It is stored for seven days, it appears under the email's Client screenshots tab, it counts against the same monthly previews, and asking again for the same email, client and theme returns the stored render (cached: true) at no cost. Each image also has a url that opens the render in a browser with no API key, valid for 7 days (urlExpiresAt). Treat the link as a secret: anyone who has it can view that render until it expires.

A finding is plain JSON with a stable rule id:

JSON
{
  "severity": "error",
  "rule": "css-property-unsupported",
  "property": "position",
  "value": "absolute",
  "message": "Gmail strips position; the badge falls into the flow"
}

severity is error, warn or info. The loop an agent runs is: send, wait_for_email, screenshot_email, read the findings, fix the template, send again until nothing comes back. The Agent Skill teaches that workflow.

Previews and plan limits

One preview is one email rendered in one client in one theme. One email in four clients, light and dark, is eight previews.

PlanPreviews per monthClientsClients per renderRenders a minuteRenders at once
Free20Gmail (desktop web)151
Basic500All4204
Pro3,000All4604
Ultra25,000AllAll1204

Every number here holds wherever the render is asked for: the dashboard, the REST API, the SDK and the MCP tools share one quota, one rate limit and one set of renders in flight per organization.

The Free plan needs a verified email address before it can render. A failed render counts as a preview; re-rendering an email whose stored render is still live does not.

"Renders at once" counts the dashboard, the API and MCP together. A render over that number waits its turn for up to 20 seconds rather than failing, so a batch simply runs a few at a time. An MCP call that names more clients than that renders them in rounds.

We notify you at 80% and 95% of the monthly cap. At 100%, rendering pauses until the next billing cycle or until you upgrade; capture, the inbox, webhooks and the API keep working.

Reporting a wrong render

Open the render and click the flag next to the client name. Say what is off, in a sentence or two; the email, the client, the theme and a link back to that render are attached for you. The report lands in support as a bug report and we check it against the real client.

Troubleshooting

PLAN_UPGRADE_REQUIRED: the client is not on your plan. Free renders Gmail on the desktop web only.

QUOTA_EXCEEDED: this month's previews are used up. The count beside the tabs shows how many were left.

RATE_LIMITED (RATE_LIMIT_EXCEEDED on the REST API): more renders started in one minute across your organization than the plan allows. Wait for the Retry-After and try again; the dashboard renders a batch one at a time for this reason.

EMAIL_NOT_VERIFIED: the Free plan renders only once an email address on the account is confirmed. Confirm it from the link we sent at signup, or request a new one from your profile.

CONCURRENCY_LIMIT: your organization already has its plan's number of renders running and the wait for a free slot ran out. Render the batch one after another, or retry after the Retry-After. The SDK does this for you.

RENDERER_BUSY: the renderer is at capacity for everyone. Nothing was rendered and no preview was spent; retry after the Retry-After.

NO_HTML: the email has no HTML part, so there is nothing to render. TOO_LARGE: the HTML part is over 2 MB.

UNKNOWN_CLIENT: the id is not in list_email_clients (MCP) or GET /v1/email-clients (REST).

RENDER_FAILED: the renderer could not produce the picture. The message says why; try again, and if it repeats, report it.