Skip to content

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.

A6 portraitLocale en-USHTML + Jinja

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.

PathTypeExample
conferenceobject
conference.namestring"Driftline Summit"
conference.editionstring"2026"
conference.taglinestring"Applied data engineering"
conference.venuestring"Halvorsen Convention Center"
conference.citystring"Minneapolis, MN"
conference.timezonestring"America/Chicago"
conference.websitestring"driftline.example.org"
conference.daysarray<object> · 3
conference.days[].datedate"2026-10-06"
conference.days[].labelstring"Hands-on workshops"
conference.days[].locationstring"Level 2 labs"
attendeeobject
attendee.first_namestring"Rosalind"
attendee.last_namestring"Achebe-Toft"
attendee.pronounsstring"she/her"
attendee.job_titlestring"Principal Data Engineer"
attendee.companystring"Tern Harbor Analytics"
attendee.rolestring"speaker"
attendee.badge_idstring"DLS26-S-0419"
attendee.access_daysarray<date> · 2"2026-10-07"
attendee.check_in_codestring"https://checkin.example.org/dls26/S-0419?k=KX7…"
attendee.sessionobject
attendee.session.titlestring"Backfills without tears: replaying five years …"
attendee.session.starts_atdate"2026-10-07T10:40:00-05:00"
attendee.session.roomstring"Room 204"
wifiobject
wifi.networkstring"Driftline-Guest"
wifi.passwordstring"tidepool-2026"

Sample data

Fictional records used for previews. Replace them with your own data when you call the API.

data.json
{
  "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>

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"
  }
}'