8.5 × 11 in
Purchase orders
Blanket purchase order
A US Letter blanket purchase order: an agreed price list with committed quantities, a month-by-item delivery schedule built with nested loops, the total committed value against a not-to-exceed ceiling, release conditions in Markdown and signature lines.
Opens Dynamic Document API with this template preloaded in a free workspace.
Template language features
- Loops
- Conditionals
- Macros
- Filters
- Currency formatting
- Date formatting
- Markdown
- Repeating table headers
- Header & footer
- Page numbers
Filters such as format_currency and qrcode are described in the template language reference.
Variables
Derived from the sample data: 8 top-level fields, 47 paths in total. Send the same shape as data.
| Path | Type | Example |
|---|---|---|
| buyer | object | |
| buyer.name | string | "Wrenhaven Café Group, Inc." |
| buyer.address | string | "300 Alder Mill Road, Suite 410 ⏎ Portland, OR …" |
| buyer.contact | string | "Marisol Achterberg" |
| buyer.contact_title | string | "Purchasing Manager" |
| buyer.email | string | "purchasing@wrenhaven.example.com" |
| buyer.phone | string | "+1 202-555-0118" |
| supplier | object | |
| supplier.name | string | "Kettlebrook Roasting Collective" |
| supplier.address | string | "1880 Sawmill Creek Rd ⏎ Eugene, OR 97402" |
| supplier.vendor_number | string | "V-10233" |
| supplier.contact | string | "Desmond Arkwright" |
| supplier.email | string | "wholesale@kettlebrook.example.net" |
| ship_to | object | |
| ship_to.name | string | "Wrenhaven Central Kitchen" |
| ship_to.address | string | "77 Foundry Loop, Dock 2 ⏎ Portland, OR 97210" |
| ship_to.hours | string | "Tuesdays, 6:00–10:00 AM" |
| agreement | object | |
| agreement.number | string | "BPO-2026-014" |
| agreement.issue_date | date | "2026-09-15" |
| agreement.start_date | date | "2026-10-01" |
| agreement.months | number | 6 |
| agreement.currency | string | "USD" |
| agreement.not_to_exceed | number | 56000 |
| agreement.payment_terms | string | "Net 30 from each delivery" |
| agreement.freight | string | "Delivered, freight included" |
| price_list | array<object> · 6 | |
| price_list[].code | string | "KRC-ESP-5" |
| price_list[].name | string | "House espresso blend, whole bean" |
| price_list[].short_name | string | "Espresso" |
| price_list[].pack | string | "5 lb bag" |
| price_list[].unit_price | number | 52.5 |
| price_list[].committed_quantity | number | 372 |
| price_list[].committed_value | number | 19530 |
| schedule | array<object> · 6 | |
| schedule[].month | date | "2026-10-01" |
| schedule[].release | string | "R01" |
| schedule[].delivery_dates | array<date> · 2 | "2026-10-06" |
| schedule[].deliveries | array<object> · 6 | |
| schedule[].deliveries[].code | string | "KRC-ESP-5" |
| schedule[].deliveries[].quantity | number | 60 |
| schedule[].deliveries[].amount | number | 3150 |
| release_conditions | string | "1. **Releases.** Wrenhaven confirms each month…" |
| signatures | array<object> · 2 | |
| signatures[].label | string | "Authorized for the buyer" |
| signatures[].name | string | "Marisol Achterberg" |
| signatures[].title | string | "Purchasing Manager" |
Sample data
Fictional records used for previews. Replace them with your own data when you call the API.
{
"buyer": {
"name": "Wrenhaven Café Group, Inc.",
"address": "300 Alder Mill Road, Suite 410\nPortland, OR 97209",
"contact": "Marisol Achterberg",
"contact_title": "Purchasing Manager",
"email": "purchasing@wrenhaven.example.com",
"phone": "+1 202-555-0118"
},
"supplier": {
"name": "Kettlebrook Roasting Collective",
"address": "1880 Sawmill Creek Rd\nEugene, OR 97402",
"vendor_number": "V-10233",
"contact": "Desmond Arkwright",
"email": "wholesale@kettlebrook.example.net"
},
"ship_to": {
"name": "Wrenhaven Central Kitchen",
"address": "77 Foundry Loop, Dock 2\nPortland, OR 97210",
"hours": "Tuesdays, 6:00–10:00 AM"
},
"agreement": {
"number": "BPO-2026-014",
"issue_date": "2026-09-15",
"start_date": "2026-10-01",
"months": 6,
"currency": "USD",
"not_to_exceed": 56000.0,
"payment_terms": "Net 30 from each delivery",
"freight": "Delivered, freight included"
},
"price_list": [
{ "code": "KRC-ESP-5", "name": "House espresso blend, whole bean", "short_name": "Espresso", "pack": "5 lb bag", "unit_price": 52.5, "committed_quantity": 372, "committed_value": 19530.0 },
{ "code": "KRC-DRP-5", "name": "Daily drip blend, whole bean", "short_name": "Drip", "pack": "5 lb bag", "unit_price": 46.25, "committed_quantity": 248, "committed_value": 11470.0 },
{ "code": "KRC-DEC-5", "name": "Water-process decaf, whole bean", "short_name": "Decaf", "pack": "5 lb bag", "unit_price": 58.75, "committed_quantity": 50, "committed_value": 2937.5 },
{ "code": "KRC-SO-2", "name": "Seasonal single origin, whole bean", "short_name": "Single origin", "pack": "2 lb bag", "unit_price": 31.8, "committed_quantity": 130, "committed_value": 4134.0 },
{ "code": "KRC-CB-5", "name": "Cold brew blend, coarse ground", "short_name": "Cold brew", "pack": "5 lb bag", "unit_price": 44.0, "committed_quantity": 98, "committed_value": 4312.0 },
{ "code": "KRC-RTL-12", "name": "Retail bags, 12 oz, mixed blends", "short_name": "Retail 12 oz", "pack": "case of 12", "unit_price": 118.8, "committed_quantity": 72, "committed_value": 8553.6 }
],
"schedule": [
{
"month": "2026-10-01",
"release": "R01",
"delivery_dates": ["2026-10-06", "2026-10-20"],
"deliveries": [
{ "code": "KRC-ESP-5", "quantity": 60, "amount": 3150.0 },
{ "code": "KRC-DRP-5", "quantity": 40, "amount": 1850.0 },
{ "code": "KRC-DEC-5", "quantity": 8, "amount": 470.0 },
{ "code": "KRC-SO-2", "quantity": 20, "amount": 636.0 },
{ "code": "KRC-CB-5", "quantity": 24, "amount": 1056.0 },
{ "code": "KRC-RTL-12", "quantity": 10, "amount": 1188.0 }
]
},
{
"month": "2026-11-01",
"release": "R02",
"delivery_dates": ["2026-11-03", "2026-11-17"],
"deliveries": [
{ "code": "KRC-ESP-5", "quantity": 64, "amount": 3360.0 },
{ "code": "KRC-DRP-5", "quantity": 42, "amount": 1942.5 },
{ "code": "KRC-DEC-5", "quantity": 8, "amount": 470.0 },
{ "code": "KRC-SO-2", "quantity": 24, "amount": 763.2 },
{ "code": "KRC-CB-5", "quantity": 16, "amount": 704.0 },
{ "code": "KRC-RTL-12", "quantity": 14, "amount": 1663.2 }
]
},
{
"month": "2026-12-01",
"release": "R03",
"delivery_dates": ["2026-12-01", "2026-12-15"],
"deliveries": [
{ "code": "KRC-ESP-5", "quantity": 70, "amount": 3675.0 },
{ "code": "KRC-DRP-5", "quantity": 48, "amount": 2220.0 },
{ "code": "KRC-DEC-5", "quantity": 10, "amount": 587.5 },
{ "code": "KRC-SO-2", "quantity": 30, "amount": 954.0 },
{ "code": "KRC-CB-5", "quantity": 12, "amount": 528.0 },
{ "code": "KRC-RTL-12", "quantity": 22, "amount": 2613.6 }
]
},
{
"month": "2027-01-01",
"release": "R04",
"delivery_dates": ["2027-01-05", "2027-01-19"],
"deliveries": [
{ "code": "KRC-ESP-5", "quantity": 58, "amount": 3045.0 },
{ "code": "KRC-DRP-5", "quantity": 40, "amount": 1850.0 },
{ "code": "KRC-DEC-5", "quantity": 8, "amount": 470.0 },
{ "code": "KRC-SO-2", "quantity": 18, "amount": 572.4 },
{ "code": "KRC-CB-5", "quantity": 12, "amount": 528.0 },
{ "code": "KRC-RTL-12", "quantity": 8, "amount": 950.4 }
]
},
{
"month": "2027-02-01",
"release": "R05",
"delivery_dates": ["2027-02-02", "2027-02-16"],
"deliveries": [
{ "code": "KRC-ESP-5", "quantity": 58, "amount": 3045.0 },
{ "code": "KRC-DRP-5", "quantity": 38, "amount": 1757.5 },
{ "code": "KRC-DEC-5", "quantity": 8, "amount": 470.0 },
{ "code": "KRC-SO-2", "quantity": 18, "amount": 572.4 },
{ "code": "KRC-CB-5", "quantity": 14, "amount": 616.0 },
{ "code": "KRC-RTL-12", "quantity": 8, "amount": 950.4 }
]
},
{
"month": "2027-03-01",
"release": "R06",
"delivery_dates": ["2027-03-02", "2027-03-16"],
"deliveries": [
{ "code": "KRC-ESP-5", "quantity": 62, "amount": 3255.0 },
{ "code": "KRC-DRP-5", "quantity": 40, "amount": 1850.0 },
{ "code": "KRC-DEC-5", "quantity": 8, "amount": 470.0 },
{ "code": "KRC-SO-2", "quantity": 20, "amount": 636.0 },
{ "code": "KRC-CB-5", "quantity": 20, "amount": 880.0 },
{ "code": "KRC-RTL-12", "quantity": 10, "amount": 1188.0 }
]
}
],
"release_conditions": "1. **Releases.** Wrenhaven confirms each monthly release in writing by the 20th of the previous month. A release fixes the delivery dates and quantities for that month.\n2. **Flexibility.** A release may move up to 15% above or below the scheduled quantity for any item at the agreed unit price. Larger changes need written agreement from both parties.\n3. **Prices.** Unit prices in the price list stay fixed for the whole agreement period.\n4. **Ceiling.** The total of all releases must stay within the not-to-exceed amount. The supplier should not ship quantities that would take the agreement above it.\n5. **Freshness.** Every bag shows its roast date, and coffee arrives no more than 7 days after roasting.\n6. **Invoicing.** Invoice each delivery separately and quote both the agreement number and the release number.",
"signatures": [
{ "label": "Authorized for the buyer", "name": "Marisol Achterberg", "title": "Purchasing Manager" },
{ "label": "Accepted for the supplier", "name": "Desmond Arkwright", "title": "Wholesale Director" }
]
}Source
The body markup with Jinja, the stylesheet placed in <head> and the header and footer settings.
{#- Blanket purchase order: an agreed price list plus a monthly delivery schedule (months × items). -#}
{%- set locale = "en-US" -%}
{%- set currency = agreement.currency -%}
{%- set end_date = agreement.start_date | date_add(months=agreement.months) | date_add(days=-1) -%}
{%- set committed = price_list | sum_by("committed_value") -%}
{%- set headroom = agreement.not_to_exceed - committed -%}
{%- set used_share = (committed / agreement.not_to_exceed * 100) | round(1) -%}
{%- macro money(value) -%}{{ value | format_currency(currency, locale) }}{%- endmacro -%}
<header class="masthead">
<div>
<p class="kicker">{{ buyer.name }}</p>
<h1>Blanket purchase order</h1>
<p class="subtitle">Framework agreement for scheduled monthly releases</p>
</div>
<div class="doc-number">
<span>Agreement</span>
<strong>{{ agreement.number }}</strong>
<span>Issued {{ agreement.issue_date | format_date("long", locale) }}</span>
</div>
</header>
<section class="parties">
<div>
<p class="label">Buyer</p>
<p class="name">{{ buyer.name }}</p>
<p>{{ buyer.address | nl2br }}</p>
<p class="muted">{{ buyer.contact }}, {{ buyer.contact_title }}<br>{{ buyer.email }} · {{ buyer.phone }}</p>
</div>
<div>
<p class="label">Supplier</p>
<p class="name">{{ supplier.name }}</p>
<p>{{ supplier.address | nl2br }}</p>
<p class="muted">Vendor {{ supplier.vendor_number }} · {{ supplier.contact }}<br>{{ supplier.email }}</p>
</div>
<div>
<p class="label">Ship to</p>
<p class="name">{{ ship_to.name }}</p>
<p>{{ ship_to.address | nl2br }}</p>
<p class="muted">Receiving: {{ ship_to.hours }}</p>
</div>
</section>
<section class="terms-strip">
<div><span>Agreement period</span><strong>{{ agreement.start_date | format_date("medium", locale) }} – {{ end_date | format_date("medium", locale) }}</strong></div>
<div><span>Term</span><strong>{{ agreement.months }} months</strong></div>
<div><span>Payment terms</span><strong>{{ agreement.payment_terms }}</strong></div>
<div><span>Freight</span><strong>{{ agreement.freight }}</strong></div>
</section>
<h2 class="section-title"><span>1</span>Agreed price list</h2>
<table class="grid prices">
<thead>
<tr>
<th scope="col">Item code</th>
<th scope="col">Description</th>
<th scope="col">Pack</th>
<th class="num" scope="col">Unit price</th>
<th class="num" scope="col">Committed qty</th>
<th class="num" scope="col">Committed value</th>
</tr>
</thead>
<tbody>
{%- for item in price_list %}
<tr>
<td class="code">{{ item.code }}</td>
<td>{{ item.name }}</td>
<td class="muted">{{ item.pack }}</td>
<td class="num">{{ money(item.unit_price) }}</td>
<td class="num">{{ item.committed_quantity }}</td>
<td class="num">{{ money(item.committed_value) }}</td>
</tr>
{%- endfor %}
</tbody>
</table>
<section class="commitment">
<div class="figures">
<div><span>Total committed value</span><strong>{{ money(committed) }}</strong></div>
<div><span>Not-to-exceed amount</span><strong>{{ money(agreement.not_to_exceed) }}</strong></div>
<div><span>Headroom for variations</span><strong>{{ money(headroom) }}</strong></div>
</div>
<div class="meter" aria-hidden="true">
<span class="meter-fill" style="width: {{ used_share }}%"></span>
</div>
<p class="meter-note">{{ (committed / agreement.not_to_exceed) | format_percent(locale, 1) }} of the not-to-exceed amount is scheduled below; {{ (headroom / agreement.not_to_exceed) | format_percent(locale, 1) }} remains for approved variations.</p>
</section>
<h2 class="section-title"><span>2</span>Monthly delivery schedule</h2>
<table class="grid schedule">
<thead>
<tr>
<th class="rel" scope="col">Release</th>
<th class="month" scope="col">Month and deliveries</th>
{%- for item in price_list %}
<th class="num qty" scope="col">{{ item.short_name }}</th>
{%- endfor %}
<th class="num value" scope="col">Value</th>
</tr>
</thead>
<tbody>
{%- for month in schedule %}
<tr>
<td class="rel">{{ agreement.number }}-{{ month.release }}</td>
<td class="month">
<strong>{{ month.month | format_date("%B %Y", locale) }}</strong>
<span class="drops">
{%- for day in month.delivery_dates %}{{ day | format_date("%m/%d", locale) }}{{ " · " if not loop.last else "" }}{% endfor -%}
</span>
</td>
{%- for item in price_list %}
{%- set delivery = month.deliveries | selectattr("code", "eq", item.code) | first %}
<td class="num qty">{% if delivery %}{{ delivery.quantity }}{% else %}<span class="muted">–</span>{% endif %}</td>
{%- endfor %}
<td class="num value">{{ money(month.deliveries | sum_by("amount")) }}</td>
</tr>
{%- endfor %}
</tbody>
<tfoot>
<tr>
<th colspan="2" scope="row">Total, {{ schedule | length }} monthly releases</th>
{%- for item in price_list %}
<td class="num qty">{{ item.committed_quantity }}</td>
{%- endfor %}
<td class="num value">{{ money(committed) }}</td>
</tr>
</tfoot>
</table>
<p class="table-note">Quantities are in packs as listed in the price list. Each release number is quoted on delivery notes and invoices.</p>
<section class="conditions">
<h2 class="section-title"><span>3</span>Release conditions</h2>
<div class="conditions-body">{{ release_conditions | markdown }}</div>
</section>
<section class="signatures">
{%- for signer in signatures %}
<div class="signature">
<p class="label">{{ signer.label }}</p>
<div class="sign-line"></div>
<p class="signer">{{ signer.name }}, {{ signer.title }}</p>
<p class="muted">Date</p>
</div>
{%- endfor %}
</section><title>Blanket purchase order {{ agreement.number }} – {{ supplier.name }}</title>
<style>
:root {
--ink: #1f2731;
--slate: #263241;
--muted: #66707c;
--rule: #dcd6cc;
--cream: #f7f3ee;
--copper: #b1602f;
--copper-soft: #f3e2d6;
}
* { box-sizing: border-box; }
html { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
body {
margin: 0;
color: var(--ink);
font-family: "Noto Sans", "Liberation Sans", Arial, sans-serif;
font-size: 8.5pt;
line-height: 1.42;
}
p, h1, h2 { margin: 0; }
.muted { color: var(--muted); }
.num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.label {
margin-bottom: 1.2mm;
font-size: 6.6pt;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--copper);
}
/* Masthead */
.masthead { display: flex; justify-content: space-between; align-items: flex-end; padding-bottom: 5mm; border-bottom: 0.3mm solid var(--rule); }
.kicker { font-size: 8pt; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--copper); }
.masthead h1 {
margin-top: 1mm;
font-family: "Noto Serif", "Liberation Serif", Georgia, serif;
font-size: 24pt;
font-weight: 700;
line-height: 1.1;
color: var(--slate);
}
.subtitle { font-size: 8.5pt; color: var(--muted); }
.doc-number { display: flex; flex-direction: column; align-items: flex-end; padding: 3mm 0 3mm 5mm; border-left: 1mm solid var(--copper); }
.doc-number span { font-size: 7.4pt; color: var(--muted); }
.doc-number strong { font-family: "Noto Serif", "Liberation Serif", Georgia, serif; font-size: 15pt; color: var(--slate); }
.parties { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7mm; margin: 5mm 0 4mm; }
.parties .name { font-weight: 700; }
.parties .muted { margin-top: 1.2mm; font-size: 7.6pt; }
.terms-strip { display: grid; grid-template-columns: 1.4fr 0.7fr 1.2fr 1.2fr; margin-bottom: 6mm; background: var(--slate); color: #ffffff; }
.terms-strip div { padding: 2.4mm 3.5mm; border-right: 0.25mm solid #3b4a5c; }
.terms-strip div:last-child { border-right: none; }
.terms-strip span { display: block; font-size: 6.4pt; letter-spacing: 0.08em; text-transform: uppercase; color: #b9c3cf; }
.terms-strip strong { font-weight: 600; }
.section-title {
display: flex;
align-items: center;
gap: 2.5mm;
margin: 0 0 2.5mm;
font-family: "Noto Serif", "Liberation Serif", Georgia, serif;
font-size: 11.5pt;
font-weight: 700;
color: var(--slate);
break-after: avoid;
page-break-after: avoid;
}
.section-title span {
display: inline-flex;
align-items: center;
justify-content: center;
width: 5.5mm;
height: 5.5mm;
border-radius: 50%;
background: var(--copper);
color: #ffffff;
font-family: "Noto Sans", "Liberation Sans", Arial, sans-serif;
font-size: 7.5pt;
}
/* Tables */
table.grid { width: 100%; border-collapse: collapse; }
table.grid thead { display: table-header-group; }
/* Totals print once, under the last row: a footer group would repeat at the bottom of every page. */
table.grid tfoot { display: table-row-group; }
table.grid thead th {
padding: 1.8mm 2mm;
border-bottom: 0.4mm solid var(--slate);
font-size: 6.6pt;
font-weight: 700;
letter-spacing: 0.05em;
text-align: left;
text-transform: uppercase;
color: var(--muted);
vertical-align: bottom;
}
table.grid thead th.num { text-align: right; }
table.grid td, table.grid tfoot th { padding: 2mm; border-bottom: 0.2mm solid var(--rule); vertical-align: top; }
table.grid tr { break-inside: avoid; page-break-inside: avoid; }
table.grid tfoot td, table.grid tfoot th { padding-top: 2.4mm; border-top: 0.4mm solid var(--slate); border-bottom: none; font-weight: 700; background: var(--cream); }
table.grid tfoot th { text-align: left; }
.code { font-family: "DejaVu Sans Mono", "Liberation Mono", monospace; font-size: 7.2pt; white-space: nowrap; }
.commitment { margin: 4mm 0 7mm; padding: 3.5mm 4.5mm; border-radius: 2mm; background: var(--cream); break-inside: avoid; page-break-inside: avoid; }
.figures { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4mm; }
.figures span { display: block; font-size: 7pt; color: var(--muted); }
.figures strong { font-family: "Noto Serif", "Liberation Serif", Georgia, serif; font-size: 13pt; color: var(--slate); font-variant-numeric: tabular-nums; }
.meter { position: relative; height: 2.6mm; margin-top: 3mm; border-radius: 2mm; background: var(--copper-soft); overflow: hidden; }
.meter-fill { position: absolute; top: 0; bottom: 0; left: 0; border-radius: 2mm; background: var(--copper); }
.meter-note { margin-top: 1.4mm; font-size: 7.4pt; color: var(--muted); }
.schedule th.qty { width: 15mm; }
.schedule th.value, .schedule td.value { width: 25mm; }
.schedule .rel { width: 30mm; font-family: "DejaVu Sans Mono", "Liberation Mono", monospace; font-size: 7pt; white-space: nowrap; }
.schedule td.month strong { display: block; font-weight: 600; }
.drops { display: block; font-size: 7pt; color: var(--muted); font-variant-numeric: tabular-nums; }
.schedule tbody tr:nth-child(odd) td { background: #fcfaf7; }
/* No release alone at the bottom or the top of a page. */
.schedule tbody tr:first-child { break-after: avoid; page-break-after: avoid; }
.schedule tbody tr:last-child { break-before: avoid; page-break-before: avoid; }
.table-note { margin-top: 1.5mm; font-size: 7.2pt; color: var(--muted); }
.conditions { margin-top: 7mm; break-inside: avoid; page-break-inside: avoid; }
.conditions-body ol { margin: 0; padding-left: 5mm; columns: 2; column-gap: 9mm; }
.conditions-body li { margin-bottom: 1.8mm; padding-left: 1mm; break-inside: avoid; page-break-inside: avoid; }
.conditions-body li::marker { font-weight: 700; color: var(--copper); }
.conditions-body strong { color: var(--slate); }
.conditions-body p { margin: 0; }
.signatures { display: grid; grid-template-columns: 1fr 1fr; gap: 14mm; margin-top: 8mm; break-inside: avoid; page-break-inside: avoid; }
.sign-line { height: 14mm; border-bottom: 0.3mm solid var(--ink); }
.signer { margin-top: 1.2mm; font-weight: 600; }
.signature .muted { margin-top: 5mm; padding-top: 0.8mm; border-top: 0.25mm solid var(--rule); font-size: 7pt; }
</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": {
"buyer": {
"name": "Wrenhaven Café Group, Inc.",
"address": "300 Alder Mill Road, Suite 410\nPortland, OR 97209",
"contact": "Marisol Achterberg",
"contact_title": "Purchasing Manager",
"email": "purchasing@wrenhaven.example.com",
"phone": "+1 202-555-0118"
},
"supplier": {
"name": "Kettlebrook Roasting Collective",
"address": "1880 Sawmill Creek Rd\nEugene, OR 97402",
"vendor_number": "V-10233",
"contact": "Desmond Arkwright",
"email": "wholesale@kettlebrook.example.net"
},
"ship_to": {
"name": "Wrenhaven Central Kitchen",
"address": "77 Foundry Loop, Dock 2\nPortland, OR 97210",
"hours": "Tuesdays, 6:00–10:00 AM"
},
"agreement": {
"number": "BPO-2026-014",
"issue_date": "2026-09-15",
"start_date": "2026-10-01",
"months": 6,
"currency": "USD",
"not_to_exceed": 56000,
"payment_terms": "Net 30 from each delivery",
"freight": "Delivered, freight included"
},
"price_list": [
{
"code": "KRC-ESP-5",
"name": "House espresso blend, whole bean",
"short_name": "Espresso",
"pack": "5 lb bag",
"unit_price": 52.5,
"committed_quantity": 372,
"committed_value": 19530
},
{
"code": "KRC-DRP-5",
"name": "Daily drip blend, whole bean",
"short_name": "Drip",
"pack": "5 lb bag",
"unit_price": 46.25,
"committed_quantity": 248,
"committed_value": 11470
}
],
"schedule": [
{
"month": "2026-10-01",
"release": "R01",
"delivery_dates": [
"2026-10-06",
"2026-10-20"
],
"deliveries": [
{
"code": "KRC-ESP-5",
"quantity": 60,
"amount": 3150
},
{
"code": "KRC-DRP-5",
"quantity": 40,
"amount": 1850
}
]
},
{
"month": "2026-11-01",
"release": "R02",
"delivery_dates": [
"2026-11-03",
"2026-11-17"
],
"deliveries": [
{
"code": "KRC-ESP-5",
"quantity": 64,
"amount": 3360
},
{
"code": "KRC-DRP-5",
"quantity": 42,
"amount": 1942.5
}
]
}
],
"release_conditions": "1. **Releases.** Wrenhaven confirms each monthly release in writing by the 20th of the previous month. A release fixes the delivery dates and quantities for that month.\n2. **Flexibility.** A release may move up to 15% above or below the scheduled quantity for any item at the agreed unit price. Larger changes need written agreement from both parties.\n3. **Prices.** Unit prices in the price list stay fixed for the whole agreement period.\n4. **Ceiling.** The total of all releases must stay within the not-to-exceed amount. The supplier should not ship quantities that would take the agreement above it.\n5. **Freshness.** Every bag shows its roast date, and coffee arrives no more than 7 days after roasting.\n6. **Invoicing.** Invoice each delivery separately and quote both the agreement number and the release number.",
"signatures": [
{
"label": "Authorized for the buyer",
"name": "Marisol Achterberg",
"title": "Purchasing Manager"
},
{
"label": "Accepted for the supplier",
"name": "Desmond Arkwright",
"title": "Wholesale Director"
}
]
},
"output": {
"format": "pdf",
"filename": "purchase-order-blanket.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": {
"buyer": {
"name": "Wrenhaven Café Group, Inc.",
"address": "300 Alder Mill Road, Suite 410\nPortland, OR 97209",
"contact": "Marisol Achterberg",
"contact_title": "Purchasing Manager",
"email": "purchasing@wrenhaven.example.com",
"phone": "+1 202-555-0118"
},
"supplier": {
"name": "Kettlebrook Roasting Collective",
"address": "1880 Sawmill Creek Rd\nEugene, OR 97402",
"vendor_number": "V-10233",
"contact": "Desmond Arkwright",
"email": "wholesale@kettlebrook.example.net"
},
"ship_to": {
"name": "Wrenhaven Central Kitchen",
"address": "77 Foundry Loop, Dock 2\nPortland, OR 97210",
"hours": "Tuesdays, 6:00–10:00 AM"
},
"agreement": {
"number": "BPO-2026-014",
"issue_date": "2026-09-15",
"start_date": "2026-10-01",
"months": 6,
"currency": "USD",
"not_to_exceed": 56000,
"payment_terms": "Net 30 from each delivery",
"freight": "Delivered, freight included"
},
"price_list": [
{
"code": "KRC-ESP-5",
"name": "House espresso blend, whole bean",
"short_name": "Espresso",
"pack": "5 lb bag",
"unit_price": 52.5,
"committed_quantity": 372,
"committed_value": 19530
},
{
"code": "KRC-DRP-5",
"name": "Daily drip blend, whole bean",
"short_name": "Drip",
"pack": "5 lb bag",
"unit_price": 46.25,
"committed_quantity": 248,
"committed_value": 11470
}
],
"schedule": [
{
"month": "2026-10-01",
"release": "R01",
"delivery_dates": [
"2026-10-06",
"2026-10-20"
],
"deliveries": [
{
"code": "KRC-ESP-5",
"quantity": 60,
"amount": 3150
},
{
"code": "KRC-DRP-5",
"quantity": 40,
"amount": 1850
}
]
},
{
"month": "2026-11-01",
"release": "R02",
"delivery_dates": [
"2026-11-03",
"2026-11-17"
],
"deliveries": [
{
"code": "KRC-ESP-5",
"quantity": 64,
"amount": 3360
},
{
"code": "KRC-DRP-5",
"quantity": 42,
"amount": 1942.5
}
]
}
],
"release_conditions": "1. **Releases.** Wrenhaven confirms each monthly release in writing by the 20th of the previous month. A release fixes the delivery dates and quantities for that month.\n2. **Flexibility.** A release may move up to 15% above or below the scheduled quantity for any item at the agreed unit price. Larger changes need written agreement from both parties.\n3. **Prices.** Unit prices in the price list stay fixed for the whole agreement period.\n4. **Ceiling.** The total of all releases must stay within the not-to-exceed amount. The supplier should not ship quantities that would take the agreement above it.\n5. **Freshness.** Every bag shows its roast date, and coffee arrives no more than 7 days after roasting.\n6. **Invoicing.** Invoice each delivery separately and quote both the agreement number and the release number.",
"signatures": [
{
"label": "Authorized for the buyer",
"name": "Marisol Achterberg",
"title": "Purchasing Manager"
},
{
"label": "Accepted for the supplier",
"name": "Desmond Arkwright",
"title": "Wholesale Director"
}
]
},
"output": {
"format": "pdf",
"filename": "purchase-order-blanket.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": {
"buyer": {
"name": "Wrenhaven Café Group, Inc.",
"address": "300 Alder Mill Road, Suite 410\nPortland, OR 97209",
"contact": "Marisol Achterberg",
"contact_title": "Purchasing Manager",
"email": "purchasing@wrenhaven.example.com",
"phone": "+1 202-555-0118",
},
"supplier": {
"name": "Kettlebrook Roasting Collective",
"address": "1880 Sawmill Creek Rd\nEugene, OR 97402",
"vendor_number": "V-10233",
"contact": "Desmond Arkwright",
"email": "wholesale@kettlebrook.example.net",
},
"ship_to": {
"name": "Wrenhaven Central Kitchen",
"address": "77 Foundry Loop, Dock 2\nPortland, OR 97210",
"hours": "Tuesdays, 6:00–10:00 AM",
},
"agreement": {
"number": "BPO-2026-014",
"issue_date": "2026-09-15",
"start_date": "2026-10-01",
"months": 6,
"currency": "USD",
"not_to_exceed": 56000,
"payment_terms": "Net 30 from each delivery",
"freight": "Delivered, freight included",
},
"price_list": [
{
"code": "KRC-ESP-5",
"name": "House espresso blend, whole bean",
"short_name": "Espresso",
"pack": "5 lb bag",
"unit_price": 52.5,
"committed_quantity": 372,
"committed_value": 19530,
},
{
"code": "KRC-DRP-5",
"name": "Daily drip blend, whole bean",
"short_name": "Drip",
"pack": "5 lb bag",
"unit_price": 46.25,
"committed_quantity": 248,
"committed_value": 11470,
},
],
"schedule": [
{
"month": "2026-10-01",
"release": "R01",
"delivery_dates": ["2026-10-06", "2026-10-20"],
"deliveries": [
{
"code": "KRC-ESP-5",
"quantity": 60,
"amount": 3150,
},
{
"code": "KRC-DRP-5",
"quantity": 40,
"amount": 1850,
},
],
},
{
"month": "2026-11-01",
"release": "R02",
"delivery_dates": ["2026-11-03", "2026-11-17"],
"deliveries": [
{
"code": "KRC-ESP-5",
"quantity": 64,
"amount": 3360,
},
{
"code": "KRC-DRP-5",
"quantity": 42,
"amount": 1942.5,
},
],
},
],
"release_conditions": "1. **Releases.** Wrenhaven confirms each monthly release in writing by the 20th of the previous month. A release fixes the delivery dates and quantities for that month.\n2. **Flexibility.** A release may move up to 15% above or below the scheduled quantity for any item at the agreed unit price. Larger changes need written agreement from both parties.\n3. **Prices.** Unit prices in the price list stay fixed for the whole agreement period.\n4. **Ceiling.** The total of all releases must stay within the not-to-exceed amount. The supplier should not ship quantities that would take the agreement above it.\n5. **Freshness.** Every bag shows its roast date, and coffee arrives no more than 7 days after roasting.\n6. **Invoicing.** Invoice each delivery separately and quote both the agreement number and the release number.",
"signatures": [
{
"label": "Authorized for the buyer",
"name": "Marisol Achterberg",
"title": "Purchasing Manager",
},
{
"label": "Accepted for the supplier",
"name": "Desmond Arkwright",
"title": "Wholesale Director",
},
],
},
"output": {
"format": "pdf",
"filename": "purchase-order-blanket.pdf",
},
},
timeout=90,
)
response.raise_for_status()
print(response.json())