Email Preview API.

Render raw HTML, an email you send us or a finished test in 50+ real clients and devices over REST, and read back a screenshot of each as JSON.

curl -X POST https://api.unspam.email/ext/v2/client-previews \
  -H "Authorization: Bearer $UNSPAM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email_source": "raw-data",
    "subject": "Your order shipped",
    "body": "<!DOCTYPE html><html>...</html>",
    "devices": ["iphone18pro_27", "iphone18pro_27_dm"]
  }'

# poll the id until status is completed
{
  "id": "3f9a2c8e-1d4b-4c7a-9f2e-7b1e5da0c62f",
  "status": "pending"
}
curl -X POST https://api.unspam.email/ext/v2/client-previews \
  -H "Authorization: Bearer $UNSPAM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "email_source": "spam-check", "source_id": "2Bl8rzTFN6VV" }'

# the other two sources
"email_source": "inbox-placement"  # source_id
"email_source": "email"            # inbox_address
curl https://api.unspam.email/ext/v2/client-previews/3f9a2c8e-1d4b-4c7a-9f2e-7b1e5da0c62f \
  -H "Authorization: Bearer $UNSPAM_TOKEN"

# response (200)
{
  "status": "completed",
  "previews": [
    {
      "device_key": "iphone18pro_27",
      "device_name": "iPhone 18 Pro (iOS 27)",
      "status": "completed",
      "original": "https://…/original.png",
      "thumbnail": "https://…/thumb.jpg",
      "download": "https://…/download"
    }
  ]
}
Endpoints
4
Email sources
4
Authentication
Bearer token
Rate limit
100 a minute

Why teams wire previews into their pipeline.

Real client captures, not simulations.

Every preview is your email opened in an actual copy of the client and device, then screenshotted. No CSS transforms, no browser emulation: the image you get is what a subscriber on that client sees.

Light and dark as separate renders.

Clients we capture in dark mode get a separate dark render with its own device key, so the inverted logo or unreadable dark-mode text shows up in your pipeline, not in production.

Scope renders with the devices parameter.

Pass devices with keys from the catalog to render only the clients you care about (just iOS Mail, just every Outlook), or omit it for every device on your plan. Newly requested devices come back pending; poll until each is completed or failed.

MCP tools for AI agents.

The preview endpoints ship as MCP tools (create_client_preview, list_client_preview_devices) on the Unspam MCP server, so Claude, Cursor, or any MCP client can pull real client renders mid-conversation.

What the preview endpoints return.

Real client screenshots as JSON: one entry per device, with a full-size image, a thumbnail and a download link.

Four ways to hand over the email.

Set email_source to spam-check or inbox-placement and pass the test id as source_id, to raw-data with your own subject and body HTML, or to email to get a draft with an inbox_address and send the message there.

The body of a raw-data preview has to be the full HTML of a designed email, at least 1,000 characters and 10 HTML elements, or it is refused with 422. A message sent to a draft with no HTML or too little of it is not rendered or charged: the draft keeps its address and sets rejection_reason.

  • spam-check source_id
  • inbox-placement source_id
  • raw-data subject, body
  • email inbox_address

Pixel-accurate renders, device by device.

GET /client-previews/{id} returns a top-level status and a previews[] array with one entry per device: device_key, device_name, its category, per-device status, and URLs for the original, thumbnail and download.

The image URLs stay null until that device is completed, so a simple poll loop drains the whole set. A device can also end as failed, so stop on that as well. GET /client-previews lists your raw-data and email previews; test previews are reached through the test's client_preview_id.

gmail · light
outlook · dark
iphone

A device catalog you can filter against.

GET /client-preview-devices lists every renderable client with its device_key, display name, and client-family category, such as Gmail, iPhone / iPad, or Outlook desktop (Windows). Cache it, show it in your own UI, or use it to build the devices filter for the render call.

Filtering is about signal and quota: each device in a request spends one device preview, so a CI job that runs on every template change can render just the three Outlook versions it cares about, spend three previews and review only those.

  • Gmail.com (Chrome, Windows 10) Gmail
  • iPhone 18 Pro (iOS 27) iPhone / iPad
  • Apple Mail 16 (macOS 13) Apple Mail (macOS)
  • Yahoo (Chrome) Yahoo
  • AOL (Chrome) AOL

The same previews, callable by AI agents over MCP.

Connect the Unspam MCP server over OAuth and your assistant gets the preview tools next to spam checks and inbox placement. Ask it to render the campaign and flag anything broken in Outlook dark mode, and it chains the calls itself.

MCP support means your agent workflows can check renders from real clients without a human opening a dashboard.

  • Render this campaign create_client_preview
  • Which clients can you render? list_client_preview_devices
  • Run the full check start_spam_check

How the email preview API works in four steps.

Previews are asynchronous: choose where the email comes from, create the preview, then read the renders per device.

  1. 01

    Choose where the email comes from

    A finished spam or inbox test, your own subject and HTML, or a message you send to a draft address.

  2. 02

    Create the preview

    POST /ext/v2/client-previews with email_source and what that source needs. The 201 response carries the preview id, plus the inbox_address to send to for the email source.

  3. 03

    Read the renders

    Poll GET /ext/v2/client-previews/{id} on a back-off. Each device moves from pending to completed or failed, and its image URLs appear as it completes.

  4. 04

    Filter devices when you need to (optional)

    Pull the catalog from GET /ext/v2/client-preview-devices and pass devices in the POST body to render a subset. Unknown keys are ignored, and the call answers 422 only when none of them is available.

The endpoints behind it.

4 endpoints, on the same token as the rest of the API. The OpenAPI document has every parameter and response code.

OpenAPI document
Client Previews 4 calls
  • GET /client-preview-devices
  • GET /client-previews
  • POST /client-previews
  • GET /client-previews/{id}

Frequently asked questions about the API.

Integration, device filtering, MCP access for AI agents, and how the preview endpoints behave.

How do I get API access?
API access is included with the Custom plan, which you buy online: pick the monthly volume of each test on the pricing page, from a $5 minimum, and the rates drop as you grow. You can build it into your own product and resell it under your own brand. For anything else, open a support ticket.
How does the email preview flow work?
Pick a source and call POST /ext/v2/client-previews: raw-data with a subject and body for HTML you have not sent, email for a draft address you send a message to, or spam-check or inbox-placement with the test id as source_id. Then GET /ext/v2/client-previews/{id} returns one entry per device with per-device status and image URLs. Devices complete independently, so poll until the set you need has finished.
Can I render only specific clients?
Yes. Pass devices in the POST /ext/v2/client-previews body with keys from GET /ext/v2/client-preview-devices to render a subset, for example only iOS Mail or only the Outlook family. Each device in the request spends one device preview from your allowance, so scoping changes both what comes back and what it costs. On the Custom plan the catalog also lists renders from the newest devices: iPhone 18 Pro, the Gmail app on Pixel 10 and iPhone 16, the Outlook Microsoft 365 app on Windows 11 and macOS, New Outlook for Windows, and Gmail web in Chrome.
Are the previews real clients or simulations?
Real clients. Each render is your email opened in an actual copy of the client and device and captured as a screenshot, with a separate dark render for the clients we capture in dark mode. That is the difference between an email rendering API built on live clients and the CSS-transform simulations most free preview tools return.
Can I use it for rendering QA in CI?
That is the main use case. Run a template change through the API in a CI step, pull the renders for your critical clients, and attach them as build artifacts or diff them against the previous run. Use a spam test as the source and the same run returns the spam score, so one job covers rendering and deliverability together.
Can AI agents run email previews?
Yes. The preview endpoints are exposed as tools on the Unspam MCP server: create_client_preview, list_client_previews and list_client_preview_devices, next to the spam-check and inbox-placement tools. Connect Claude, Cursor, or ChatGPT over OAuth and ask for renders in plain language; no keys to paste.
How is this different from the screenshots endpoint?
/spam-check/{id}/screenshots returns three viewport renders (desktop, tablet, mobile) of the message. POST /client-previews renders the email inside 50+ real client applications, with dark renders for the clients we capture in dark mode, so it catches client-specific breakage like the Outlook Word engine or a dark-mode logo inversion.
What are the rate limits?
The public limit is 100 requests per minute per IP or per authenticated account. Preview polling fits comfortably inside it with a normal back-off. If you need a higher limit, open a support ticket with your expected throughput.
Can I build this into my own product and resell it?
Yes, on the Custom plan. Every preview comes back as JSON with an image URL for each client and device, so you can show the renders in your own interface and resell them to your clients under your own brand.

Ready to render emails from your own stack?

API access is included with the Custom plan, bought online from a $5 monthly minimum. Build it into your own product and resell it under your own brand.