Skip to content

210 × 90 mm

Tickets & passes

Event admission ticket

A 210 × 90 mm seated admission ticket with a tear-off stub: event, venue, door and show times, section, row and seat, the holder's name, price with booking fee, a scannable QR code and short conditions of entry.

Custom sizeLocale en-GBHTML + Jinja

Opens Dynamic Document API with this template preloaded in a free workspace.

Template language features

  • Loops
  • Conditionals
  • Macros
  • Filters
  • Currency formatting
  • Date formatting
  • QR code

Filters such as format_currency and qrcode are described in the template language reference.

Variables

Derived from the sample data: 7 top-level fields, 28 paths in total. Send the same shape as data.

PathTypeExample
eventobject
event.namestring"The Halcyon Tramlines"
event.subtitlestring"Night Ferry Tour 2026 · with support from Orla…"
event.presenterstring"Kelsbury Arts Trust presents"
event.doors_atdate"2026-11-21T18:30:00Z"
event.starts_atdate"2026-11-21T19:30:00Z"
event.timezonestring"Europe/London"
event.age_policystring"Ages 14+; under-16s must be accompanied by an …"
venueobject
venue.namestring"Ropewalk Hall"
venue.addressstring"Quayside Road, Kelsbury KB4 2QT"
seatobject
seat.entrancestring"Door 3"
seat.sectionstring"Stalls left"
seat.rowstring"H"
seat.numberstring"14"
holderobject
holder.namestring"Harriet Oyelaran-Beck"
ticketobject
ticket.typestring"Seated · Standard"
ticket.numberstring"KAT-261121-004817"
ticket.order_referencestring"ORD-88213"
ticket.currencystring"GBP"
ticket.face_valuenumber38.5
ticket.booking_feenumber3.85
ticket.scan_tokenstring"https://tickets.example.com/v/KAT261121004817?…"
fine_printarray<string> · 4"Valid for one admission on the date shown"
help_urlstring"tickets.example.com/help"

Sample data

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

data.json
{
  "event": {
    "name": "The Halcyon Tramlines",
    "subtitle": "Night Ferry Tour 2026 · with support from Orla Wrenfield",
    "presenter": "Kelsbury Arts Trust presents",
    "doors_at": "2026-11-21T18:30:00Z",
    "starts_at": "2026-11-21T19:30:00Z",
    "timezone": "Europe/London",
    "age_policy": "Ages 14+; under-16s must be accompanied by an adult"
  },
  "venue": {
    "name": "Ropewalk Hall",
    "address": "Quayside Road, Kelsbury KB4 2QT"
  },
  "seat": {
    "entrance": "Door 3",
    "section": "Stalls left",
    "row": "H",
    "number": "14"
  },
  "holder": {
    "name": "Harriet Oyelaran-Beck"
  },
  "ticket": {
    "type": "Seated · Standard",
    "number": "KAT-261121-004817",
    "order_reference": "ORD-88213",
    "currency": "GBP",
    "face_value": 38.5,
    "booking_fee": 3.85,
    "scan_token": "https://tickets.example.com/v/KAT261121004817?c=7QK3M"
  },
  "fine_print": [
    "Valid for one admission on the date shown",
    "Each code can be scanned once and copies are refused",
    "Latecomers are seated at a suitable break",
    "Resale above face value cancels the ticket"
  ],
  "help_url": "tickets.example.com/help"
}

Source

The body markup with Jinja, the stylesheet placed in <head>.

{#- Event admission ticket, 210 × 90 mm: a main panel for the ticket holder and a tear-off stub for the door team. -#}
{%- set locale = "en-GB" -%}
{%- set tz = event.timezone | default("Europe/London") -%}
{%- set currency = ticket.currency -%}
{%- set total_paid = ticket.face_value + ticket.booking_fee -%}
{%- set seated = seat and seat.section -%}

{%- macro fact(label, value, detail=none, wide=false) -%}
<div class="fact{{ ' wide' if wide else '' }}">
  <span class="k">{{ label }}</span>
  <span class="v">{{ value }}</span>
  {%- if detail %}
  <span class="d">{{ detail }}</span>
  {%- endif %}
</div>
{%- endmacro %}

<article class="ticket">
  <section class="main">
    <div class="info">
      <p class="presenter">{{ event.presenter }}</p>

      <div class="title-block">
        <h1 class="headliner">{{ event.name }}</h1>
        {%- if event.subtitle %}
        <p class="subtitle">{{ event.subtitle }}</p>
        {%- endif %}
      </div>

      <div class="facts">
        {{ fact("Date", event.starts_at | format_date("%a %d %b %Y", locale, tz)) }}
        {{ fact("Doors", event.doors_at | format_date("%H:%M", locale, tz)) }}
        {{ fact("Show", event.starts_at | format_date("%H:%M", locale, tz)) }}
        {{ fact("Venue", venue.name, venue.address, wide=true) }}
        {%- if seated %}
        {{ fact("Entrance", seat.entrance) }}
        {%- endif %}
      </div>

      <div class="holder">
        <span class="k">Ticket holder</span>
        <span class="holder-name">{{ holder.name }}</span>
        <span class="holder-meta"><span class="mono">{{ ticket.number }}</span> · Order {{ ticket.order_reference }}</span>
      </div>
    </div>

    <div class="aside">
      <span class="type">{{ ticket.type }}</span>
      <svg class="sunset" viewBox="0 0 100 100" aria-hidden="true">
        <defs>
          <linearGradient id="sunset-fill" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0" stop-color="#ffb547"/>
            <stop offset="1" stop-color="#ff5c39"/>
          </linearGradient>
        </defs>
        <circle cx="50" cy="50" r="47" fill="url(#sunset-fill)"/>
        <g fill="#17112b">
          <rect x="0" y="55" width="100" height="2.4"/>
          <rect x="0" y="63" width="100" height="3.4"/>
          <rect x="0" y="72" width="100" height="4.6"/>
          <rect x="0" y="82" width="100" height="6"/>
          <rect x="0" y="93" width="100" height="7"/>
        </g>
      </svg>
      <div class="seat-grid">
        {%- if seated %}
        <div class="seat-cell span"><span class="k">Section</span><span class="v">{{ seat.section }}</span></div>
        <div class="seat-cell"><span class="k">Row</span><span class="v">{{ seat.row }}</span></div>
        <div class="seat-cell hot"><span class="k">Seat</span><span class="v">{{ seat.number }}</span></div>
        {%- else %}
        <div class="seat-cell span"><span class="k">Admission</span><span class="v">Standing</span></div>
        {%- endif %}
      </div>
    </div>

    <footer class="bottom">
      <p class="fine">
        {%- for term in fine_print %}{{ term }}{{ " · " if not loop.last else ". " }}{% endfor -%}
        {{ event.age_policy }}. Help and accessibility: {{ help_url }}
      </p>
      <div class="price">
        <span class="price-parts">{{ ticket.face_value | format_currency(currency, locale) }} ticket + {{ ticket.booking_fee | format_currency(currency, locale) }} booking fee</span>
        <span class="price-total">{{ total_paid | format_currency(currency, locale) }}</span>
      </div>
    </footer>
  </section>

  <aside class="stub">
    <div class="stub-head">
      <span class="admit">Admit one</span>
      <span class="stub-date">{{ event.starts_at | format_date("%d %b %Y", locale, tz) }}</span>
    </div>
    <p class="stub-event">{{ event.name }}<br><span>{{ venue.name }} · Doors {{ event.doors_at | format_date("%H:%M", locale, tz) }}</span></p>
    <div class="qr">{{ ticket.scan_token | qrcode(size=240, margin=0, ecc="Q", alt="Entry QR code for the door team") }}</div>
    <dl class="stub-seat">
      {%- if seated %}
      <div><dt>Section</dt><dd>{{ seat.section }}</dd></div>
      <div><dt>Row</dt><dd>{{ seat.row }}</dd></div>
      <div><dt>Seat</dt><dd>{{ seat.number }}</dd></div>
      {%- else %}
      <div><dt>Entry</dt><dd>Standing</dd></div>
      {%- endif %}
    </dl>
    <p class="stub-foot"><span class="mono">{{ ticket.number }}</span>Door team: scan the code, then tear along the line.</p>
  </aside>
</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": {
    "event": {
      "name": "The Halcyon Tramlines",
      "subtitle": "Night Ferry Tour 2026 · with support from Orla Wrenfield",
      "presenter": "Kelsbury Arts Trust presents",
      "doors_at": "2026-11-21T18:30:00Z",
      "starts_at": "2026-11-21T19:30:00Z",
      "timezone": "Europe/London",
      "age_policy": "Ages 14+; under-16s must be accompanied by an adult"
    },
    "venue": {
      "name": "Ropewalk Hall",
      "address": "Quayside Road, Kelsbury KB4 2QT"
    },
    "seat": {
      "entrance": "Door 3",
      "section": "Stalls left",
      "row": "H",
      "number": "14"
    },
    "holder": {
      "name": "Harriet Oyelaran-Beck"
    },
    "ticket": {
      "type": "Seated · Standard",
      "number": "KAT-261121-004817",
      "order_reference": "ORD-88213",
      "currency": "GBP",
      "face_value": 38.5,
      "booking_fee": 3.85,
      "scan_token": "https://tickets.example.com/v/KAT261121004817?c=7QK3M"
    },
    "fine_print": [
      "Valid for one admission on the date shown",
      "Each code can be scanned once and copies are refused"
    ],
    "help_url": "tickets.example.com/help"
  },
  "output": {
    "format": "pdf",
    "filename": "ticket-event-admission.pdf"
  }
}'