Certificate generation is a high-volume, design-sensitive use case. Each certificate needs to look identical, print correctly, and be generated on-demand or in batch. REST API-based generation handles all three: consistent Chromium rendering, custom page dimensions, and trivially parallel requests.
Certificate HTML Template (Landscape A4)
certificate-template.htmlhtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700&family=Lato:wght@300;400&display=swap');
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: 'Lato', sans-serif;
width: 297mm; height: 210mm;
display: flex; align-items: center; justify-content: center;
}
.cert {
text-align: center; padding: 48px 64px;
border: 3px solid #b8860b; width: 100%; height: 100%;
display: flex; flex-direction: column; align-items: center; justify-content: center;
}
h1 { font-family: 'Playfair Display', serif; font-size: 42px; color: #b8860b; margin-bottom: 8px; }
.name { font-size: 36px; font-weight: 700; color: #1e293b; margin: 24px 0 8px; }
.course { font-size: 20px; color: #475569; }
.date { font-size: 13px; color: #94a3b8; margin-top: 32px; }
</style>
</head>
<body>
<div class="cert">
<h1>Certificate of Completion</h1>
<p style="color:#64748b">This certifies that</p>
<div class="name">{{recipient_name}}</div>
<p style="color:#64748b">has successfully completed</p>
<div class="course">{{course_name}}</div>
<div class="date">Issued {{date}} · {{issuer}}</div>
</div>
</body>
</html>API Request: Landscape, Zero Margins
Request bodyjson
{
"html": "...certificate HTML with variables replaced...",
"paper_size": "a4",
"orientation": "landscape",
"margin_top": 0,
"margin_bottom": 0,
"margin_left": 0,
"margin_right": 0
}Batch Generation
For course completions, generate certificates in parallel. Each API call is independent: See the certificate PDF use case for landscape layout and batch generation examples.
Node.js parallel batchjs
const certificates = await Promise.all(
students.map(student =>
fetch('https://platform.htmltopdfapi.co/api/v1/pdf/generate', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.HTMLTOPDF_API_KEY}`,
'Content-Type': 'application/json', Accept: 'application/pdf' },
body: JSON.stringify({
html: renderTemplate(certHtml, student),
paper_size: 'a4',
orientation: 'landscape',
margin_top: 0, margin_bottom: 0, margin_left: 0, margin_right: 0,
}),
}).then(r => r.arrayBuffer())
)
)