297 × 210 mm
Certificates
Course completion certificate
A landscape A4 certificate for training providers and online courses. It names the recipient, course, hours and completion date, prints two instructor signature lines from a list, and adds a certificate ID with a QR code for public verification inside a decorative SVG frame.
Opens Dynamic Document API with this template preloaded in a free workspace.
Template language features
- Loops
- Conditionals
- Filters
- QR code
- Date formatting
Filters such as format_currency and qrcode are described in the template language reference.
Variables
Derived from the sample data: 5 top-level fields, 20 paths in total. Send the same shape as data.
| Path | Type | Example |
|---|---|---|
| issuer | object | |
| issuer.name | string | "Aldermoor Institute of Applied Technology" |
| issuer.website | string | "aldermoor.example.org" |
| certificate | object | |
| certificate.id | string | "AMI-CSE-2026-04817" |
| certificate.completion_date | date | "2026-09-11" |
| certificate.verify_url | string | "https://verify.example.org/c/AMI-CSE-2026-0481…" |
| certificate.locale | string | "en-US" |
| recipient | object | |
| recipient.name | string | "Jordan A. Whitcombe" |
| course | object | |
| course.title | string | "Foundations of Cloud Security Engineering" |
| course.hours | number | 36 |
| course.delivery | string | "Live online cohort" |
| course.start_date | date | "2026-07-20" |
| course.modules | array<string> · 5 | "Identity and access" |
| course.distinction | boolean | true |
| signatories | array<object> · 2 | |
| signatories[].name | string | "Dr. Selene Oyelaran" |
| signatories[].title | string | "Lead Instructor" |
Sample data
Fictional records used for previews. Replace them with your own data when you call the API.
{
"issuer": {
"name": "Aldermoor Institute of Applied Technology",
"website": "aldermoor.example.org"
},
"certificate": {
"id": "AMI-CSE-2026-04817",
"completion_date": "2026-09-11",
"verify_url": "https://verify.example.org/c/AMI-CSE-2026-04817",
"locale": "en-US"
},
"recipient": {
"name": "Jordan A. Whitcombe"
},
"course": {
"title": "Foundations of Cloud Security Engineering",
"hours": 36,
"delivery": "Live online cohort",
"start_date": "2026-07-20",
"modules": ["Identity and access", "Network segmentation", "Secrets management", "Logging and detection", "Incident response"],
"distinction": true
},
"signatories": [
{ "name": "Dr. Selene Oyelaran", "title": "Lead Instructor" },
{ "name": "Marcus Feldhaus", "title": "Director of Professional Programs" }
]
}Source
The body markup with Jinja, the stylesheet placed in <head>.
{#- Course completion certificate on a single A4 landscape sheet. The frame is inline SVG in
millimetre units (viewBox 297 × 210); the corner ornaments are placed with a loop. Signatures come
from the signatories array and the QR code links to the public verification page. -#}
{%- set locale = certificate.locale | default("en-US") -%}
<div class="sheet">
<svg class="frame" viewBox="0 0 297 210" preserveAspectRatio="none" aria-hidden="true">
<defs>
<pattern id="weave" width="5" height="5" patternUnits="userSpaceOnUse">
<path d="M0 2.5C1.25 0.6 2.5 0.6 2.5 2.5S3.75 4.4 5 2.5" fill="none" stroke="#b08d57" stroke-width="0.28"/>
<path d="M0 2.5C1.25 4.4 2.5 4.4 2.5 2.5S3.75 0.6 5 2.5" fill="none" stroke="#1b2a4a" stroke-width="0.18"/>
</pattern>
</defs>
<rect x="7" y="7" width="283" height="196" fill="none" stroke="#1b2a4a" stroke-width="1.4"/>
<path d="M10 10H287V200H10Z M15 15V195H282V15Z" fill="url(#weave)" fill-rule="evenodd"/>
<rect x="10" y="10" width="277" height="190" fill="none" stroke="#b08d57" stroke-width="0.35"/>
<rect x="15" y="15" width="267" height="180" fill="none" stroke="#b08d57" stroke-width="0.35"/>
<rect x="18" y="18" width="261" height="174" fill="none" stroke="#1b2a4a" stroke-width="0.25"/>
{% for x, y in [[18, 18], [279, 18], [18, 192], [279, 192]] %}
<g transform="translate({{ x }} {{ y }})">
<rect x="-4.2" y="-4.2" width="8.4" height="8.4" transform="rotate(45)" fill="#ffffff" stroke="#b08d57" stroke-width="0.4"/>
<rect x="-2.4" y="-2.4" width="4.8" height="4.8" transform="rotate(45)" fill="#1b2a4a"/>
</g>
{% endfor %}
</svg>
<div class="content">
<header class="issuer">
<svg class="issuer-mark" viewBox="0 0 48 48" aria-hidden="true">
<path d="M24 3l18 10.5v21L24 45 6 34.5v-21z" fill="#1b2a4a"/>
<path d="M24 12l10 5.8v11.6L24 35l-10-5.6V17.8z" fill="none" stroke="#b08d57" stroke-width="1.8"/>
<path d="M24 12v23M14 17.8l20 11.6M34 17.8l-20 11.6" stroke="#b08d57" stroke-width="0.9"/>
</svg>
<p class="issuer-name">{{ issuer.name }}</p>
</header>
<h1 class="title">Certificate of Completion</h1>
<svg class="ornament" viewBox="0 0 120 8" aria-hidden="true">
<path d="M0 4h50M70 4h50" stroke="#b08d57" stroke-width="0.6"/>
<path d="M60 0.5l3.5 3.5-3.5 3.5-3.5-3.5z" fill="#b08d57"/>
<circle cx="52.5" cy="4" r="1" fill="#b08d57"/>
<circle cx="67.5" cy="4" r="1" fill="#b08d57"/>
</svg>
<p class="intro">This certifies that</p>
<p class="recipient">{{ recipient.name }}</p>
<p class="intro">has successfully completed the {{ course.hours }}-hour course</p>
<p class="course">{{ course.title }}</p>
<p class="details">
{{ course.delivery }} ·
{{ course.start_date | format_date("long", locale) }} to {{ certificate.completion_date | format_date("long", locale) }}
{% if course.distinction %}<span class="distinction">With distinction</span>{% endif %}
</p>
{% if course.modules %}
<ul class="modules">
{% for module in course.modules %}<li>{{ module }}{% if not loop.last %}<span class="dot" aria-hidden="true">◆</span>{% endif %}</li>{% endfor %}
</ul>
{% endif %}
<footer class="bottom">
{% for person in signatories %}
<div class="signatory">
<div class="sig-space"></div>
<p class="sig-name">{{ person.name }}</p>
<p class="sig-title">{{ person.title }}</p>
</div>
{% endfor %}
<div class="verify">
<div class="verify-text">
<p class="verify-label">Certificate ID</p>
<p class="verify-id">{{ certificate.id }}</p>
<p class="verify-label">Issued</p>
<p class="verify-date">{{ certificate.completion_date | format_date("long", locale) }}</p>
<p class="verify-url">Verify at {{ certificate.verify_url | replace("https://", "") }}</p>
</div>
{{ certificate.verify_url | qrcode(size=200, margin=0, ecc="Q", color="#1b2a4a", alt="QR code to verify this certificate online") }}
</div>
</footer>
</div>
</div><title>Certificate of Completion – {{ recipient.name }}</title>
<style>
:root {
--navy: #1b2a4a;
--gold: #b08d57;
--muted: #5b6475;
}
* { box-sizing: border-box; }
html { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
body {
margin: 0;
color: var(--navy);
font-family: "Lato", "Liberation Sans", Arial, sans-serif;
font-size: 10pt;
line-height: 1.35;
}
p { margin: 0; }
/* One landscape A4 sheet; slightly shorter than 210 mm so rounding never adds a blank page. */
.sheet { position: relative; width: 297mm; height: 209mm; overflow: hidden; background: #ffffff; }
.frame { position: absolute; left: 0; top: 0; width: 297mm; height: 209mm; }
.content {
position: absolute; left: 30mm; right: 30mm; top: 25mm; bottom: 25mm;
display: flex; flex-direction: column; align-items: center; text-align: center;
}
.issuer { display: flex; flex-direction: column; align-items: center; }
.issuer-mark { width: 12mm; height: 12mm; }
.issuer-name {
margin-top: 2mm; font-family: "Montserrat", "Liberation Sans", Arial, sans-serif; font-size: 8.5pt; font-weight: 600;
letter-spacing: 0.28em; text-transform: uppercase; color: var(--navy);
}
.title {
margin: 7mm 0 0; font-family: "Montserrat", "Liberation Sans", Arial, sans-serif; font-size: 21pt; font-weight: 600;
letter-spacing: 0.26em; text-transform: uppercase; line-height: 1.1;
}
.ornament { width: 70mm; height: 4.7mm; margin: 3mm 0 6mm; }
.intro { font-size: 11pt; font-style: italic; color: var(--muted); }
.recipient {
margin: 2mm 0 3.5mm; padding: 0 12mm 2.5mm; border-bottom: 0.35mm solid var(--gold);
font-family: "Montserrat", "Liberation Sans", Arial, sans-serif; font-size: 31pt; font-weight: 500; letter-spacing: 0.01em; line-height: 1.15;
}
.course {
margin-top: 2mm; font-family: "Montserrat", "Liberation Sans", Arial, sans-serif; font-size: 16pt; font-weight: 600; line-height: 1.25;
}
.details { margin-top: 2.5mm; font-size: 9.5pt; color: var(--muted); }
.distinction {
display: inline-block; margin-left: 2mm; padding: 0.4mm 2.5mm; border: 0.3mm solid var(--gold); border-radius: 3mm;
color: #8a6a37; font-size: 8pt; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
}
.modules { margin: 2mm 0 0; padding: 0; list-style: none; font-size: 8.5pt; color: var(--muted); }
.modules li { display: inline; }
.modules .dot { margin: 0 2mm; font-size: 5pt; color: var(--gold); vertical-align: 0.4mm; }
.bottom {
display: flex; align-items: flex-end; justify-content: space-between; gap: 10mm;
width: 100%; margin-top: auto; text-align: left;
}
.signatory { width: 62mm; }
.sig-space { height: 13mm; border-bottom: 0.3mm solid var(--navy); }
.sig-name { margin-top: 1.5mm; font-weight: 700; font-size: 9.5pt; }
.sig-title { font-size: 8pt; color: var(--muted); }
.verify { display: flex; align-items: flex-end; gap: 3.5mm; margin-left: auto; }
.verify img { display: block; width: 21mm; height: 21mm; }
.verify-text { text-align: right; }
.verify-label { font-size: 6.5pt; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.verify-id { margin-bottom: 1mm; font-family: "DejaVu Sans Mono", "Liberation Mono", monospace; font-size: 8pt; }
.verify-date { margin-bottom: 1mm; font-size: 8.5pt; }
.verify-url { font-size: 7pt; color: var(--muted); }
</style>Render it with the API
After adding the template to your workspace, render it by ID and pass your data. Arrays are shortened here.
curl -X POST https://api-eu.dynamicdocumentapi.com/v1/renders \
-H "Authorization: Bearer $DYNAMIC_DOCUMENT_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"input": {
"type": "template",
"template_id": "tpl_01J9ZK3M7Q8V5W2X4Y6Z8A0B1C"
},
"data": {
"issuer": {
"name": "Aldermoor Institute of Applied Technology",
"website": "aldermoor.example.org"
},
"certificate": {
"id": "AMI-CSE-2026-04817",
"completion_date": "2026-09-11",
"verify_url": "https://verify.example.org/c/AMI-CSE-2026-04817",
"locale": "en-US"
},
"recipient": {
"name": "Jordan A. Whitcombe"
},
"course": {
"title": "Foundations of Cloud Security Engineering",
"hours": 36,
"delivery": "Live online cohort",
"start_date": "2026-07-20",
"modules": [
"Identity and access",
"Network segmentation"
],
"distinction": true
},
"signatories": [
{
"name": "Dr. Selene Oyelaran",
"title": "Lead Instructor"
},
{
"name": "Marcus Feldhaus",
"title": "Director of Professional Programs"
}
]
},
"output": {
"format": "pdf",
"filename": "certificate-course-completion.pdf"
}
}'const response = await fetch("https://api-eu.dynamicdocumentapi.com/v1/renders", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.DYNAMIC_DOCUMENT_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
"input": {
"type": "template",
"template_id": "tpl_01J9ZK3M7Q8V5W2X4Y6Z8A0B1C"
},
"data": {
"issuer": {
"name": "Aldermoor Institute of Applied Technology",
"website": "aldermoor.example.org"
},
"certificate": {
"id": "AMI-CSE-2026-04817",
"completion_date": "2026-09-11",
"verify_url": "https://verify.example.org/c/AMI-CSE-2026-04817",
"locale": "en-US"
},
"recipient": {
"name": "Jordan A. Whitcombe"
},
"course": {
"title": "Foundations of Cloud Security Engineering",
"hours": 36,
"delivery": "Live online cohort",
"start_date": "2026-07-20",
"modules": [
"Identity and access",
"Network segmentation"
],
"distinction": true
},
"signatories": [
{
"name": "Dr. Selene Oyelaran",
"title": "Lead Instructor"
},
{
"name": "Marcus Feldhaus",
"title": "Director of Professional Programs"
}
]
},
"output": {
"format": "pdf",
"filename": "certificate-course-completion.pdf"
}
}),
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const result = await response.json();
console.log(result);import os
import uuid
import requests
response = requests.post(
"https://api-eu.dynamicdocumentapi.com/v1/renders",
headers={
"Authorization": f"Bearer {os.environ['DYNAMIC_DOCUMENT_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"input": {
"type": "template",
"template_id": "tpl_01J9ZK3M7Q8V5W2X4Y6Z8A0B1C",
},
"data": {
"issuer": {
"name": "Aldermoor Institute of Applied Technology",
"website": "aldermoor.example.org",
},
"certificate": {
"id": "AMI-CSE-2026-04817",
"completion_date": "2026-09-11",
"verify_url": "https://verify.example.org/c/AMI-CSE-2026-04817",
"locale": "en-US",
},
"recipient": {
"name": "Jordan A. Whitcombe",
},
"course": {
"title": "Foundations of Cloud Security Engineering",
"hours": 36,
"delivery": "Live online cohort",
"start_date": "2026-07-20",
"modules": ["Identity and access", "Network segmentation"],
"distinction": True,
},
"signatories": [
{
"name": "Dr. Selene Oyelaran",
"title": "Lead Instructor",
},
{
"name": "Marcus Feldhaus",
"title": "Director of Professional Programs",
},
],
},
"output": {
"format": "pdf",
"filename": "certificate-course-completion.pdf",
},
},
timeout=90,
)
response.raise_for_status()
print(response.json())