Skip to content

Recipe: course certificate

Goal: when a learner completes a course on your platform, a personalized certificate is generated and emailed to them.

You’ll use: serif fonts, default values, the export API from a webhook handler.

  1. Create a template named Certificate of completion.

  2. Frame — a large rectangle with a transparent fill, a 6 px stroke in a muted gold (#b08d57), corner radius 24. Add a second, thinner dashed rectangle inside it for an engraved look.

  3. Heading — Certificate of Completion in Crimson Text, 72 px, centered.

  4. Body — in Merriweather 32 px:

    This certifies that participantName has successfully completed courseTitle on completionDate.

    Set participantName in bold 56 px so it stands out.

  5. Signature area — a thin rectangle as a line, with instructorName underneath.

  6. Configure the variables:

    Variable Required Default
    participantName ✅
    courseTitle ✅
    completionDate ✅
    instructorName The Academy Team
    certificateId

A typical webhook handler (Express here) — generate, then email:

app.post('/webhooks/course-completed', async (req, res) => {
const { learner, course, completedAt, enrollmentId } = req.body;
const pdf = await fetch(
`https://app.imprime.io/api/export/${process.env.CERTIFICATE_TEMPLATE_ID}/pdf`,
{
method: 'POST',
headers: {
'x-api-key': process.env.IMPRIME_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
participantName: `${learner.firstName} ${learner.lastName}`,
courseTitle: course.title,
completionDate: new Date(completedAt).toLocaleDateString('en-US', { dateStyle: 'long' }),
certificateId: `CERT-${enrollmentId}`,
// instructorName omitted → "The Academy Team"
}),
},
);
if (!pdf.ok) return res.status(502).json({ error: await pdf.text() });
await mailer.send({
to: learner.email,
subject: `Your certificate for ${course.title}`,
attachments: [
{ filename: 'certificate.pdf', content: Buffer.from(await pdf.arrayBuffer()) },
],
});
res.sendStatus(204);
});
  • One template per course — duplicate the design and change the artwork; store the template ID on the course record.
  • Several languages — one template per language, selected from the learner’s locale.