210 × 297 mm
Reports
Meeting minutes
An A4 meeting record that is easy to edit visually: key facts, an attendee table, optional apologies, one section per agenda item with an optional highlighted decision, an action-item table and a next-meeting note.
Opens Dynamic Document API with this template preloaded in a free workspace.
Template language features
- Loops
- Conditionals
- Date formatting
- Header & footer
- Page numbers
- Repeating table headers
Filters such as format_currency and qrcode are described in the template language reference.
Variables
Derived from the sample data: 8 top-level fields, 27 paths in total. Send the same shape as data.
| Path | Type | Example |
|---|---|---|
| organisation | string | "Riverside Community Garden Association" |
| meeting | object | |
| meeting.title | string | "Board meeting minutes" |
| meeting.date | date | "2026-09-10" |
| meeting.time | string | "18:30–20:05" |
| meeting.location | string | "Community hall, room 2" |
| meeting.chair | string | "Maya Okafor" |
| meeting.minute_taker | string | "Daniel Brooks" |
| attendance_summary | string | "6 of 7 board members present (quorate)" |
| attendees | array<object> · 6 | |
| attendees[].name | string | "Maya Okafor" |
| attendees[].role | string | "Chair" |
| apologies | array<string> · 1 | "Grace Whitfield (Member)" |
| agenda | array<object> · 4 | |
| agenda[].number | number | 1 |
| agenda[].topic | string | "Minutes of the last meeting" |
| agenda[].notes | string | "The minutes of 13 August were read and approve…" |
| agenda[].decision | string | "Approved unanimously." |
| actions | array<object> · 4 | |
| actions[].id | string | "A1" |
| actions[].task | string | "Submit the rainwater tank grant application" |
| actions[].owner | string | "Leonie Grant" |
| actions[].due | date | "2026-09-30" |
| next_meeting | object | |
| next_meeting.date | date | "2026-10-08" |
| next_meeting.time | string | "18:30" |
| next_meeting.location | string | "Community hall, room 2" |
Sample data
Fictional records used for previews. Replace them with your own data when you call the API.
{
"organisation": "Riverside Community Garden Association",
"meeting": {
"title": "Board meeting minutes",
"date": "2026-09-10",
"time": "18:30–20:05",
"location": "Community hall, room 2",
"chair": "Maya Okafor",
"minute_taker": "Daniel Brooks"
},
"attendance_summary": "6 of 7 board members present (quorate)",
"attendees": [
{
"name": "Maya Okafor",
"role": "Chair"
},
{
"name": "Daniel Brooks",
"role": "Secretary"
},
{
"name": "Leonie Grant",
"role": "Treasurer"
},
{
"name": "Samir Haddad",
"role": "Volunteer coordinator"
},
{
"name": "Ruth Kellerman",
"role": "Member"
},
{
"name": "Oliver Tan",
"role": "Member"
}
],
"apologies": [
"Grace Whitfield (Member)"
],
"agenda": [
{
"number": 1,
"topic": "Minutes of the last meeting",
"notes": "The minutes of 13 August were read and approved without changes.",
"decision": "Approved unanimously."
},
{
"number": 2,
"topic": "Treasurer's report",
"notes": "Balance of €8,420 after the summer market. The water bill rose by 18 % because of the dry August; the committee discussed rainwater tanks as a long-term fix.",
"decision": ""
},
{
"number": 3,
"topic": "Rainwater tanks",
"notes": "Two quotes were compared. The larger tank covers about 60 % of summer watering. The borough offers a 40 % grant for community projects.",
"decision": "Apply for the borough grant and order the larger tank if it is approved."
},
{
"number": 4,
"topic": "Autumn volunteer day",
"notes": "Planned for 17 October with bulb planting and path repairs. Samir will reach out to the two local schools.",
"decision": ""
}
],
"actions": [
{
"id": "A1",
"task": "Submit the rainwater tank grant application",
"owner": "Leonie Grant",
"due": "2026-09-30"
},
{
"id": "A2",
"task": "Invite both schools to the volunteer day",
"owner": "Samir Haddad",
"due": "2026-09-24"
},
{
"id": "A3",
"task": "Order bulbs and gravel for the paths",
"owner": "Ruth Kellerman",
"due": "2026-10-03"
},
{
"id": "A4",
"task": "Publish these minutes on the notice board",
"owner": "Daniel Brooks",
"due": "2026-09-15"
}
],
"next_meeting": {
"date": "2026-10-08",
"time": "18:30",
"location": "Community hall, room 2"
}
}Source
The body markup with Jinja, the stylesheet placed in <head> and the header and footer settings.
<p class="organisation">{{ organisation }}</p>
<h1>{{ meeting.title }}</h1>
<table class="facts">
<tbody>
<tr>
<th scope="row">Date</th>
<td>{{ meeting.date | format_date("full", "en-GB") }}</td>
<th scope="row">Time</th>
<td>{{ meeting.time }}</td>
</tr>
<tr>
<th scope="row">Location</th>
<td>{{ meeting.location }}</td>
<th scope="row">Chair</th>
<td>{{ meeting.chair }}</td>
</tr>
<tr>
<th scope="row">Minutes</th>
<td>{{ meeting.minute_taker }}</td>
<th scope="row">Attendance</th>
<td>{{ attendance_summary }}</td>
</tr>
</tbody>
</table>
<h2>Attendees</h2>
<table class="attendees">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Role</th>
</tr>
</thead>
<tbody>
{% for person in attendees %}
<tr>
<td>{{ person.name }}</td>
<td>{{ person.role }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if apologies %}
<div class="apologies">
<p><strong>Apologies:</strong></p>
<ul class="dashes">
{% for name in apologies %}
<li>{{ name }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<h2>Agenda and discussion</h2>
{% for item in agenda %}
<div class="agenda-item">
<h3>{{ item.number }}. {{ item.topic }}</h3>
<p>{{ item.notes }}</p>
{% if item.decision %}<p class="decision"><strong>Decision:</strong> {{ item.decision }}</p>{% endif %}
</div>
{% endfor %}
<h2>Action items</h2>
<table class="actions">
<thead>
<tr>
<th class="id" scope="col">#</th>
<th scope="col">Action</th>
<th scope="col">Owner</th>
<th class="due" scope="col">Due</th>
</tr>
</thead>
<tbody>
{% for action in actions %}
<tr>
<td class="id">{{ action.id }}</td>
<td>{{ action.task }}</td>
<td>{{ action.owner }}</td>
<td class="due">{{ action.due | format_date("medium", "en-GB") }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if next_meeting.date %}<p class="next-meeting"><strong>Next meeting:</strong> {{ next_meeting.date | format_date("long", "en-GB") }}, {{ next_meeting.time }} · {{ next_meeting.location }}</p>{% endif %}<title>{{ meeting.title }}, {{ meeting.date | format_date("long", "en-GB") }}</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
font-family: "Inter", "Liberation Sans", Arial, sans-serif;
font-size: 10pt;
line-height: 1.5;
color: #1f2937;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
h1, h2, h3 {
margin: 0 0 4.5pt;
font-family: "Merriweather", "Liberation Serif", Georgia, serif;
font-weight: 700;
line-height: 1.25;
color: #78350f;
break-after: avoid;
}
h1 { margin-top: 18pt; font-size: 20pt; letter-spacing: -0.01em; }
h2 { margin-top: 17pt; font-size: 17.5pt; }
h3 { margin-top: 16pt; font-size: 15pt; }
p { margin: 0 0 5pt; }
table { width: 100%; border-collapse: collapse; margin-bottom: 10pt; }
th, td { padding: 0.45em 0.6em; text-align: left; vertical-align: top; }
thead { display: table-header-group; }
tr { break-inside: avoid; }
.organisation { font-size: 8.5pt; font-weight: 700; text-transform: uppercase; color: #b45309; }
/* Date, place and people */
.facts th, .facts td { padding: 0 1.2em 0.3em 0; }
.facts th { width: 1%; font-weight: 400; color: #6b7280; white-space: nowrap; }
.facts td { width: 49%; }
/* Attendees: a light list with a ruled header */
.attendees th {
border-bottom: 1pt solid #78350f;
font-size: 0.85em;
font-weight: 600;
letter-spacing: 0.05em;
text-transform: uppercase;
color: #6b7280;
}
.apologies ul { margin: 0 0 10pt; padding: 0; list-style: none; }
.apologies li { margin-bottom: 5pt; }
.apologies li::before { content: "— "; }
/* Agenda items and decisions */
.decision, .next-meeting {
margin: 0 0 10pt;
padding: 0.75em 1em;
border-left: 3pt solid #1f8a4c;
border-radius: 2pt;
background: #ecf6f0;
break-inside: avoid;
}
.next-meeting { border-left-color: #2f6fde; background: #eef3fd; }
/* Action items in a ruled grid */
.actions th, .actions td { border: 0.75pt solid #e5e7eb; }
.actions th { background: #fef3c7; font-weight: 600; color: #78350f; }
.actions .id { width: 6%; }
.actions .due { text-align: right; white-space: nowrap; }
</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": {
"organisation": "Riverside Community Garden Association",
"meeting": {
"title": "Board meeting minutes",
"date": "2026-09-10",
"time": "18:30–20:05",
"location": "Community hall, room 2",
"chair": "Maya Okafor",
"minute_taker": "Daniel Brooks"
},
"attendance_summary": "6 of 7 board members present (quorate)",
"attendees": [
{
"name": "Maya Okafor",
"role": "Chair"
},
{
"name": "Daniel Brooks",
"role": "Secretary"
}
],
"apologies": [
"Grace Whitfield (Member)"
],
"agenda": [
{
"number": 1,
"topic": "Minutes of the last meeting",
"notes": "The minutes of 13 August were read and approved without changes.",
"decision": "Approved unanimously."
},
{
"number": 2,
"topic": "Treasurer'\''s report",
"notes": "Balance of €8,420 after the summer market. The water bill rose by 18 % because of the dry August; the committee discussed rainwater tanks as a long-term fix.",
"decision": ""
}
],
"actions": [
{
"id": "A1",
"task": "Submit the rainwater tank grant application",
"owner": "Leonie Grant",
"due": "2026-09-30"
},
{
"id": "A2",
"task": "Invite both schools to the volunteer day",
"owner": "Samir Haddad",
"due": "2026-09-24"
}
],
"next_meeting": {
"date": "2026-10-08",
"time": "18:30",
"location": "Community hall, room 2"
}
},
"output": {
"format": "pdf",
"filename": "report-meeting-minutes.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": {
"organisation": "Riverside Community Garden Association",
"meeting": {
"title": "Board meeting minutes",
"date": "2026-09-10",
"time": "18:30–20:05",
"location": "Community hall, room 2",
"chair": "Maya Okafor",
"minute_taker": "Daniel Brooks"
},
"attendance_summary": "6 of 7 board members present (quorate)",
"attendees": [
{
"name": "Maya Okafor",
"role": "Chair"
},
{
"name": "Daniel Brooks",
"role": "Secretary"
}
],
"apologies": [
"Grace Whitfield (Member)"
],
"agenda": [
{
"number": 1,
"topic": "Minutes of the last meeting",
"notes": "The minutes of 13 August were read and approved without changes.",
"decision": "Approved unanimously."
},
{
"number": 2,
"topic": "Treasurer's report",
"notes": "Balance of €8,420 after the summer market. The water bill rose by 18 % because of the dry August; the committee discussed rainwater tanks as a long-term fix.",
"decision": ""
}
],
"actions": [
{
"id": "A1",
"task": "Submit the rainwater tank grant application",
"owner": "Leonie Grant",
"due": "2026-09-30"
},
{
"id": "A2",
"task": "Invite both schools to the volunteer day",
"owner": "Samir Haddad",
"due": "2026-09-24"
}
],
"next_meeting": {
"date": "2026-10-08",
"time": "18:30",
"location": "Community hall, room 2"
}
},
"output": {
"format": "pdf",
"filename": "report-meeting-minutes.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": {
"organisation": "Riverside Community Garden Association",
"meeting": {
"title": "Board meeting minutes",
"date": "2026-09-10",
"time": "18:30–20:05",
"location": "Community hall, room 2",
"chair": "Maya Okafor",
"minute_taker": "Daniel Brooks",
},
"attendance_summary": "6 of 7 board members present (quorate)",
"attendees": [
{
"name": "Maya Okafor",
"role": "Chair",
},
{
"name": "Daniel Brooks",
"role": "Secretary",
},
],
"apologies": ["Grace Whitfield (Member)"],
"agenda": [
{
"number": 1,
"topic": "Minutes of the last meeting",
"notes": "The minutes of 13 August were read and approved without changes.",
"decision": "Approved unanimously.",
},
{
"number": 2,
"topic": "Treasurer's report",
"notes": "Balance of €8,420 after the summer market. The water bill rose by 18 % because of the dry August; the committee discussed rainwater tanks as a long-term fix.",
"decision": "",
},
],
"actions": [
{
"id": "A1",
"task": "Submit the rainwater tank grant application",
"owner": "Leonie Grant",
"due": "2026-09-30",
},
{
"id": "A2",
"task": "Invite both schools to the volunteer day",
"owner": "Samir Haddad",
"due": "2026-09-24",
},
],
"next_meeting": {
"date": "2026-10-08",
"time": "18:30",
"location": "Community hall, room 2",
},
},
"output": {
"format": "pdf",
"filename": "report-meeting-minutes.pdf",
},
},
timeout=90,
)
response.raise_for_status()
print(response.json())More reports templates
- 210 × 297 mm
Monthly KPI report
A4A two-page A4 management report with KPI cards that show the change against last month, a 12-month revenue bar chart drawn with render_chart from a JSON array, the current month highlighted against a target line, revenue by channel, a top-products table and Markdown commentary, with page numbers.
- 210 × 297 mm
Site inspection report
A4An A4 facility inspection report with an overall result, pass and fail counts, findings ranked by severity with due dates, a checklist grouped by area with status badges, photo reference placeholders and a separate sign-off page with page numbers.