105 × 148 mm
Tickets & passes
Conference attendee pass
An A6 conference badge with the attendee's name, company and a role pill coloured for speakers, attendees, sponsors or staff, a per-day access list, the speaker's session details, a Wi-Fi hint and a check-in QR code.
Opens Dynamic Document API with this template preloaded in a free workspace.
Template language features
- Loops
- Conditionals
- Macros
- Filters
- Date formatting
- QR code
Filters such as format_currency and qrcode are described in the template language reference.
Variables
Derived from the sample data: 3 top-level fields, 29 paths in total. Send the same shape as data.
| Path | Type | Example |
|---|---|---|
| conference | object | |
| conference.name | string | "Driftline Summit" |
| conference.edition | string | "2026" |
| conference.tagline | string | "Applied data engineering" |
| conference.venue | string | "Halvorsen Convention Center" |
| conference.city | string | "Minneapolis, MN" |
| conference.timezone | string | "America/Chicago" |
| conference.website | string | "driftline.example.org" |
| conference.days | array<object> · 3 | |
| conference.days[].date | date | "2026-10-06" |
| conference.days[].label | string | "Hands-on workshops" |
| conference.days[].location | string | "Level 2 labs" |
| attendee | object | |
| attendee.first_name | string | "Rosalind" |
| attendee.last_name | string | "Achebe-Toft" |
| attendee.pronouns | string | "she/her" |
| attendee.job_title | string | "Principal Data Engineer" |
| attendee.company | string | "Tern Harbor Analytics" |
| attendee.role | string | "speaker" |
| attendee.badge_id | string | "DLS26-S-0419" |
| attendee.access_days | array<date> · 2 | "2026-10-07" |
| attendee.check_in_code | string | "https://checkin.example.org/dls26/S-0419?k=KX7…" |
| attendee.session | object | |
| attendee.session.title | string | "Backfills without tears: replaying five years …" |
| attendee.session.starts_at | date | "2026-10-07T10:40:00-05:00" |
| attendee.session.room | string | "Room 204" |
| wifi | object | |
| wifi.network | string | "Driftline-Guest" |
| wifi.password | string | "tidepool-2026" |
Sample data
Fictional records used for previews. Replace them with your own data when you call the API.
{
"conference": {
"name": "Driftline Summit",
"edition": "2026",
"tagline": "Applied data engineering",
"venue": "Halvorsen Convention Center",
"city": "Minneapolis, MN",
"timezone": "America/Chicago",
"website": "driftline.example.org",
"days": [
{ "date": "2026-10-06", "label": "Hands-on workshops", "location": "Level 2 labs" },
{ "date": "2026-10-07", "label": "Keynotes and talks", "location": "Hall B" },
{ "date": "2026-10-08", "label": "Talks and expo", "location": "Hall B" }
]
},
"attendee": {
"first_name": "Rosalind",
"last_name": "Achebe-Toft",
"pronouns": "she/her",
"job_title": "Principal Data Engineer",
"company": "Tern Harbor Analytics",
"role": "speaker",
"badge_id": "DLS26-S-0419",
"access_days": ["2026-10-07", "2026-10-08"],
"check_in_code": "https://checkin.example.org/dls26/S-0419?k=KX7P2",
"session": {
"title": "Backfills without tears: replaying five years of events",
"starts_at": "2026-10-07T10:40:00-05:00",
"room": "Room 204"
}
},
"wifi": {
"network": "Driftline-Guest",
"password": "tidepool-2026"
}
}Source
The body markup with Jinja, the stylesheet placed in <head>.
{#- Conference pass (A6 portrait). The attendee's role sets the pill and footer colour. -#}
{%- set locale = "en-US" -%}
{%- set tz = conference.timezone | default("America/Chicago") -%}
{%- if attendee.role == "speaker" -%}
{%- set role_label = "Speaker" -%}{%- set role_color = "#e8590c" -%}
{%- elif attendee.role == "sponsor" -%}
{%- set role_label = "Sponsor" -%}{%- set role_color = "#7048e8" -%}
{%- elif attendee.role == "staff" -%}
{%- set role_label = "Staff" -%}{%- set role_color = "#2b8a3e" -%}
{%- else -%}
{%- set role_label = "Attendee" -%}{%- set role_color = "#1c7ed6" -%}
{%- endif -%}
{%- set included_days = conference.days | selectattr("date", "in", attendee.access_days) | list -%}
{%- macro state_icon(allowed) -%}
{%- if allowed -%}
<svg class="state" viewBox="0 0 16 16" role="img" aria-label="Included"><circle cx="8" cy="8" r="8" fill="#12805c"/><path d="M4.6 8.3l2.3 2.3 4.6-4.8" fill="none" stroke="#fff" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>
{%- else -%}
<svg class="state" viewBox="0 0 16 16" role="img" aria-label="Not included"><circle cx="8" cy="8" r="7.2" fill="none" stroke="#b7bfcc" stroke-width="1.4"/><path d="M5.4 10.6l5.2-5.2" stroke="#b7bfcc" stroke-width="1.4" stroke-linecap="round"/></svg>
{%- endif -%}
{%- endmacro %}
<article class="pass" style="--role: {{ role_color }};">
<header class="band">
<span class="slot" aria-hidden="true"></span>
<svg class="contours" viewBox="0 0 120 90" aria-hidden="true" fill="none" stroke="#2ec4a6" stroke-width="0.7">
<path d="M6 72C28 42 58 30 90 38s36 34 26 52"/>
<path d="M20 82C36 56 60 46 86 52s30 26 24 42"/>
<path d="M36 92C48 72 66 64 84 68s24 18 20 30"/>
<ellipse cx="98" cy="18" rx="17" ry="10"/>
<ellipse cx="98" cy="18" rx="9" ry="4.6"/>
</svg>
<div class="brand">
<svg class="mark" viewBox="0 0 32 32" aria-hidden="true">
<rect width="32" height="32" rx="8" fill="#2ec4a6"/>
<path d="M8 11h16M8 16h11M8 21h6" stroke="#0f1b3d" stroke-width="3" stroke-linecap="round"/>
</svg>
<div>
<div class="conf-name">{{ conference.name }} {{ conference.edition }}</div>
<div class="conf-meta">{{ conference.tagline }} · {{ conference.city }}</div>
</div>
</div>
</header>
<main class="pass-body">
<section class="who">
<h1 class="first">{{ attendee.first_name }}</h1>
<p class="last">
{{- attendee.last_name -}}
{%- if attendee.pronouns %} <span class="pronouns">{{ attendee.pronouns }}</span>{% endif -%}
</p>
<p class="job">{{ attendee.job_title }}</p>
<p class="company">{{ attendee.company }}</p>
<span class="pill">{{ role_label }}</span>
</section>
<section class="access">
<div class="days">
<p class="label">Access · {{ included_days | length }} of {{ conference.days | length }} days</p>
<ul>
{%- for day in conference.days %}
{%- set allowed = day.date in attendee.access_days %}
<li class="{{ 'yes' if allowed else 'no' }}">
<span class="tile">
<span class="mon">{{ day.date | format_date("%b", locale) | upper }}</span>
<span class="dd">{{ day.date | format_date("%d", locale) }}</span>
</span>
<span class="day-text">
<strong>{{ day.date | format_date("%A", locale) }}</strong>
{{ day.label }} · {{ day.location }}
</span>
{{ state_icon(allowed) }}
</li>
{%- endfor %}
</ul>
</div>
<div class="checkin">
<div class="qr">{{ attendee.check_in_code | qrcode(size=200, margin=0, ecc="M", alt="Check-in QR code") }}</div>
<span class="badge-id">{{ attendee.badge_id }}</span>
</div>
</section>
{%- if attendee.role == "speaker" and attendee.session %}
<section class="session">
<p class="label">Your session</p>
<p class="session-title">{{ attendee.session.title }}</p>
<p class="session-meta">{{ attendee.session.starts_at | format_date("%a, %b %d · %I:%M %p", locale, tz) }} · {{ attendee.session.room }}</p>
</section>
{%- endif %}
<p class="wifi">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M2.5 9.2a14 14 0 0 1 19 0M5.8 12.6a9.2 9.2 0 0 1 12.4 0M9.1 16a4.4 4.4 0 0 1 5.8 0" fill="none" stroke="#0f1b3d" stroke-width="2.2" stroke-linecap="round"/><circle cx="12" cy="19.2" r="1.6" fill="#0f1b3d"/></svg>
<span>Wi-Fi <strong>{{ wifi.network }}</strong> · password <strong>{{ wifi.password }}</strong></span>
</p>
</main>
<footer class="role-strip">
<span>{{ role_label }}</span>
<span class="site">{{ conference.website }}</span>
</footer>
</article><title>{{ conference.name }} {{ conference.edition }} pass – {{ attendee.first_name }} {{ attendee.last_name }}</title>
<style>
:root {
--navy: #0f1b3d;
--teal: #2ec4a6;
--ink: #151b2c;
--muted: #5f6b80;
--rule: #e1e5ec;
--soft: #f3f5f9;
--role: #1c7ed6;
}
* { box-sizing: border-box; }
html { -webkit-print-color-adjust: exact; print-color-adjust: exact; background: #ffffff; }
html, body { margin: 0; padding: 0; width: 105mm; height: 148mm; overflow: hidden; }
body {
color: var(--ink);
font-family: "Poppins", "Liberation Sans", Arial, sans-serif;
font-size: 7.4pt;
line-height: 1.35;
}
p, h1, ul { margin: 0; padding: 0; }
.label {
font-size: 5.8pt;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--muted);
}
.pass { display: flex; flex-direction: column; width: 105mm; height: 148mm; overflow: hidden; }
/* Brand band with lanyard slot */
.band {
position: relative;
flex: 0 0 27mm;
padding: 10mm 7mm 0;
background: var(--navy);
color: #ffffff;
overflow: hidden;
}
.slot {
position: absolute;
top: 3.4mm;
left: 50%;
width: 16mm;
height: 3.2mm;
margin-left: -8mm;
border-radius: 2mm;
background: #ffffff;
}
.contours { position: absolute; top: -3mm; right: -8mm; width: 56mm; height: 42mm; opacity: 0.55; }
.brand { position: relative; display: flex; align-items: center; gap: 3mm; }
.mark { flex: none; width: 10.5mm; height: 10.5mm; }
.conf-name { font-size: 12pt; font-weight: 700; line-height: 1.15; letter-spacing: -0.01em; }
.conf-meta { font-size: 6.6pt; color: #b9c4e2; }
.pass-body {
flex: 1 1 auto;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 5mm 7mm 3.6mm;
}
/* Attendee */
.first { font-size: 25pt; font-weight: 700; line-height: 1.02; letter-spacing: -0.02em; }
.last { margin-top: 0.4mm; font-size: 14.5pt; font-weight: 600; line-height: 1.1; }
.pronouns {
display: inline-block;
margin-left: 1.5mm;
padding: 0.2mm 1.6mm;
border: 0.25mm solid var(--rule);
border-radius: 3mm;
font-size: 6.2pt;
font-weight: 500;
color: var(--muted);
vertical-align: middle;
}
.job { margin-top: 1.6mm; font-size: 7.8pt; font-weight: 500; }
.company { font-size: 7.8pt; color: var(--muted); }
.pill {
display: inline-block;
margin-top: 2mm;
padding: 0.7mm 3mm;
border-radius: 4mm;
background: var(--role);
color: #ffffff;
font-size: 6.6pt;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
}
/* Day access and check-in code */
.access { display: grid; grid-template-columns: 1fr 29mm; gap: 4mm; align-items: start; }
.days ul { list-style: none; margin-top: 1.4mm; }
.days li {
display: grid;
grid-template-columns: 9mm 1fr 3.6mm;
gap: 2mm;
align-items: center;
padding: 1mm 0;
border-top: 0.25mm solid var(--rule);
}
.days li:last-child { border-bottom: 0.25mm solid var(--rule); }
.tile {
display: block;
padding: 0.5mm 0 0.7mm;
border-radius: 1.4mm;
background: var(--navy);
color: #ffffff;
text-align: center;
line-height: 1.05;
}
.tile .mon { display: block; font-size: 5pt; font-weight: 600; letter-spacing: 0.08em; color: var(--teal); }
.tile .dd { display: block; font-size: 9pt; font-weight: 700; }
.day-text { font-size: 6.2pt; line-height: 1.3; color: var(--muted); }
.day-text strong { display: block; font-size: 7pt; font-weight: 600; color: var(--ink); }
.days li.no .tile { background: var(--soft); color: #9aa3b2; }
.days li.no .tile .mon { color: #9aa3b2; }
.days li.no .day-text, .days li.no .day-text strong { color: #9aa3b2; }
.state { display: block; width: 3.6mm; height: 3.6mm; }
.checkin { text-align: center; }
.qr { padding: 1.6mm; border: 0.3mm solid var(--rule); border-radius: 2mm; background: #ffffff; }
.qr img { display: block; width: 25.2mm; height: 25.2mm; margin: 0 auto; }
.badge-id {
display: block;
margin-top: 1mm;
font-family: "DejaVu Sans Mono", "Liberation Mono", monospace;
font-size: 6pt;
letter-spacing: 0.04em;
color: var(--muted);
}
/* Speaker session */
.session {
padding: 2mm 3mm;
border-left: 1mm solid var(--role);
border-radius: 0 1.6mm 1.6mm 0;
background: var(--soft);
}
.session-title { margin-top: 0.4mm; font-size: 7.4pt; font-weight: 600; line-height: 1.3; }
.session-meta { font-size: 6.4pt; color: var(--muted); }
.wifi {
display: flex;
align-items: center;
gap: 2mm;
padding: 1.3mm 2.4mm;
border: 0.25mm dashed #b9c1ce;
border-radius: 1.6mm;
font-size: 6.6pt;
color: var(--muted);
}
.wifi svg { flex: none; width: 4mm; height: 4mm; }
.wifi strong { font-weight: 600; color: var(--ink); }
.role-strip {
flex: 0 0 12mm;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 7mm;
background: var(--role);
color: #ffffff;
font-size: 14pt;
font-weight: 700;
letter-spacing: 0.24em;
text-transform: uppercase;
}
.role-strip .site { font-size: 6.2pt; font-weight: 500; letter-spacing: 0.02em; text-transform: none; opacity: 0.9; }
</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": {
"conference": {
"name": "Driftline Summit",
"edition": "2026",
"tagline": "Applied data engineering",
"venue": "Halvorsen Convention Center",
"city": "Minneapolis, MN",
"timezone": "America/Chicago",
"website": "driftline.example.org",
"days": [
{
"date": "2026-10-06",
"label": "Hands-on workshops",
"location": "Level 2 labs"
},
{
"date": "2026-10-07",
"label": "Keynotes and talks",
"location": "Hall B"
}
]
},
"attendee": {
"first_name": "Rosalind",
"last_name": "Achebe-Toft",
"pronouns": "she/her",
"job_title": "Principal Data Engineer",
"company": "Tern Harbor Analytics",
"role": "speaker",
"badge_id": "DLS26-S-0419",
"access_days": [
"2026-10-07",
"2026-10-08"
],
"check_in_code": "https://checkin.example.org/dls26/S-0419?k=KX7P2",
"session": {
"title": "Backfills without tears: replaying five years of events",
"starts_at": "2026-10-07T10:40:00-05:00",
"room": "Room 204"
}
},
"wifi": {
"network": "Driftline-Guest",
"password": "tidepool-2026"
}
},
"output": {
"format": "pdf",
"filename": "ticket-conference-pass.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": {
"conference": {
"name": "Driftline Summit",
"edition": "2026",
"tagline": "Applied data engineering",
"venue": "Halvorsen Convention Center",
"city": "Minneapolis, MN",
"timezone": "America/Chicago",
"website": "driftline.example.org",
"days": [
{
"date": "2026-10-06",
"label": "Hands-on workshops",
"location": "Level 2 labs"
},
{
"date": "2026-10-07",
"label": "Keynotes and talks",
"location": "Hall B"
}
]
},
"attendee": {
"first_name": "Rosalind",
"last_name": "Achebe-Toft",
"pronouns": "she/her",
"job_title": "Principal Data Engineer",
"company": "Tern Harbor Analytics",
"role": "speaker",
"badge_id": "DLS26-S-0419",
"access_days": [
"2026-10-07",
"2026-10-08"
],
"check_in_code": "https://checkin.example.org/dls26/S-0419?k=KX7P2",
"session": {
"title": "Backfills without tears: replaying five years of events",
"starts_at": "2026-10-07T10:40:00-05:00",
"room": "Room 204"
}
},
"wifi": {
"network": "Driftline-Guest",
"password": "tidepool-2026"
}
},
"output": {
"format": "pdf",
"filename": "ticket-conference-pass.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": {
"conference": {
"name": "Driftline Summit",
"edition": "2026",
"tagline": "Applied data engineering",
"venue": "Halvorsen Convention Center",
"city": "Minneapolis, MN",
"timezone": "America/Chicago",
"website": "driftline.example.org",
"days": [
{
"date": "2026-10-06",
"label": "Hands-on workshops",
"location": "Level 2 labs",
},
{
"date": "2026-10-07",
"label": "Keynotes and talks",
"location": "Hall B",
},
],
},
"attendee": {
"first_name": "Rosalind",
"last_name": "Achebe-Toft",
"pronouns": "she/her",
"job_title": "Principal Data Engineer",
"company": "Tern Harbor Analytics",
"role": "speaker",
"badge_id": "DLS26-S-0419",
"access_days": ["2026-10-07", "2026-10-08"],
"check_in_code": "https://checkin.example.org/dls26/S-0419?k=KX7P2",
"session": {
"title": "Backfills without tears: replaying five years of events",
"starts_at": "2026-10-07T10:40:00-05:00",
"room": "Room 204",
},
},
"wifi": {
"network": "Driftline-Guest",
"password": "tidepool-2026",
},
},
"output": {
"format": "pdf",
"filename": "ticket-conference-pass.pdf",
},
},
timeout=90,
)
response.raise_for_status()
print(response.json())