Cover Page Preview
GET /api/v2/epds/{epd_id}/cover/ renders an EPD's cover page as a
standalone HTML document — the same page that ships as page one of the
generated PDF, rendered on demand with no PDF generation involved. Use it to
show a live cover preview on your own platform (a listing page, a review
screen, a "here's what will be published" step) without downloading and
rasterizing the full PDF.
- An API key with read access to the EPD's workspace (see API Quickstart)
Fetch the cover HTML
curl https://sandbox.smartepd.xyz/api/v2/epds/$EPD_ID/cover/ \
-H "Authorization: Bearer $TOKEN"
The response is Content-Type: text/html — a complete, self-contained HTML
document. Fonts and images are embedded inline (base64), so nothing else
needs to load for it to render correctly, including offline or inside a
sandboxed frame.
You can't point an <img> or <iframe src> at the URL directly
Like every other v2 endpoint, this one requires an Authorization header.
Browsers don't attach custom headers to element-level requests (<img src>,
<iframe src>, a plain link), so pointing one at this URL directly will
401 — there's no request for the header to ride along on. Fetch the HTML
with your API key first, then hand the resulting string to an iframe via
srcdoc:
<iframe id="epd-cover" title="EPD cover page" sandbox style="border: 0;"></iframe>
<script>
async function loadCoverPreview(epdId, apiKey) {
const res = await fetch(`https://sandbox.smartepd.xyz/api/v2/epds/${epdId}/cover/`, {
headers: { Authorization: `Bearer ${apiKey}` },
});
if (!res.ok) {
// See "Not every EPD has one" below for the 400 case.
console.error('Could not load cover preview', res.status);
return;
}
const html = await res.text();
document.getElementById('epd-cover').srcdoc = html;
}
</script>
Leave the sandbox attribute empty (as above) rather than adding allow
tokens — the document has no scripts of its own to run, so the most
restrictive sandbox is also the safest default. This is the exact pattern
Smart EPD's own web app uses to render this same preview.
Sizing
The rendered page is a fixed US Letter page — 8.5in × 11in, which is 816×1056
CSS pixels at 96dpi. It isn't a fluid/responsive layout, so don't just set the
iframe's width/height in your own CSS and expect it to reflow — render it
at its natural size and scale the whole iframe down with a CSS transform to
fit your layout instead:
.epd-cover-frame {
width: 816px;
height: 1056px;
transform: scale(var(--epd-cover-scale)); /* e.g. 0.4 to fit a 320px-wide card */
transform-origin: top left;
}
Set --epd-cover-scale to <your target width> / 816.
Not every EPD has one
A small number of EPDs use an alternate, paginated rendering pipeline whose
cover is a different page of that document rather than this template. For
those, the endpoint returns 400 with error.code: "validation_error"
instead of silently returning a cover that wouldn't match the EPD's actual
PDF. Treat a 400 here the same way you'd treat "no preview available" —
fall back to a placeholder, or to linking out to GET /epds/{epd_id}/pdf/
for the full document.
Related
- API Quickstart — generating an API key and the full EPD lifecycle
- API Reference — interactive endpoint explorer (EPDs tag)