Selling and buying / A4
Trade price list PDF template
A dated catalogue of prices by item code, usually with a second column for volume, issued to trade accounts.
When this document is the right one
Prices are published to a set of customers for a season or a period. The document is a reference rather than a transaction, so it is read by scanning rather than by reading, and it is superseded rather than amended.
Why each part is there
The fields are visible in the markup. What is not visible is why they are present, which is the part that gets removed first when someone adapts a template for their own use.
- An effective date and the version it supersedes, so two lists in circulation can be told apart at a glance.
- An item code on every line, because that is what an order will be placed against and a description is not unique.
- The conditions under which the prices can move, stated once. Silence here is read as a firm price.
- Volume break quantities stated explicitly, including whether they accumulate across orders, which is the question that always follows.
- A note on tax treatment, since a trade list is net and a mistake here changes every number on the page.
The template
A complete file. Doctype, stylesheet, body: paste it into a renderer unchanged and it produces a finished A4 page. Replace the sample data and the styling holds.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Trade price list, Summer 2026</title>
<style>
@page { size: A4; margin: 16mm 14mm 20mm; }
* { box-sizing: border-box; }
body { margin: 0; font: 9pt/1.4 "Helvetica Neue", Arial, sans-serif; color: #1b1b1b; }
header { border-bottom: 3px solid #1b1b1b; padding-bottom: 5mm;
display: flex; justify-content: space-between; align-items: flex-end; }
h1 { margin: 0; font-size: 20pt; letter-spacing: -0.01em; }
.effective { text-align: right; font-size: 9pt; }
.effective strong { display: block; font-size: 11pt; }
.note { margin: 5mm 0 7mm; font-size: 8.5pt; color: #555;
border-left: 3px solid #ddd; padding-left: 4mm; }
/* Two columns of listings, and a category heading that must not be the last
thing on a page with its first row overleaf. */
.cols { column-count: 2; column-gap: 8mm; }
section.cat { break-inside: avoid-column; margin-bottom: 6mm; }
h2 { font-size: 9pt; text-transform: uppercase; letter-spacing: 0.08em;
margin: 0 0 2mm; padding-bottom: 1mm; border-bottom: 1.5px solid #1b1b1b;
break-after: avoid; }
.row { display: grid; grid-template-columns: 1fr 16mm 16mm; gap: 2mm;
padding: 1.4mm 0; border-bottom: 1px dotted #d5d5d5; }
.row .name { font-size: 8.5pt; }
.row .name small { display: block; color: #777; font-size: 7.5pt; }
.row .p { text-align: right; font-variant-numeric: tabular-nums; }
.hdr { display: grid; grid-template-columns: 1fr 16mm 16mm; gap: 2mm;
font-size: 7pt; text-transform: uppercase; letter-spacing: 0.05em;
color: #777; padding-bottom: 1mm; }
.hdr span:not(:first-child) { text-align: right; }
.breaks { margin-top: 8mm; break-inside: avoid; border: 1px solid #ddd; padding: 4mm;
font-size: 8.5pt; column-span: all; }
.breaks table { border-collapse: collapse; width: 100%; margin-top: 2mm; }
.breaks td, .breaks th { border: 1px solid #ddd; padding: 1.5mm 2mm; text-align: center; }
</style>
</head>
<body>
<header>
<div>
<h1>Trade price list</h1>
<div style="margin-top:1.5mm;font-size:10pt">Kilnworks Studio · wholesale</div>
</div>
<div class="effective">
<strong>Summer 2026</strong>
Effective 01 June 2026<br>
Supersedes Spring 2026
</div>
</header>
<p class="note">
Trade prices are net of VAT and apply to accounts with an agreed credit line.
Column A is the standard trade price; column B applies at or above the volume
break shown at the foot of this list. Prices hold until 30 November 2026 except
where a clay or glaze material cost moves by more than 8%, which is the one
thing outside our control.
</p>
<div class="cols">
<section class="cat">
<h2>Tableware, house glaze</h2>
<div class="hdr"><span>Item</span><span>A</span><span>B</span></div>
<div class="row"><span class="name">Dinner plate, 27cm<small>KW-DP-27</small></span>
<span class="p">18.00</span><span class="p">16.20</span></div>
<div class="row"><span class="name">Side plate, 19cm<small>KW-SP-19</small></span>
<span class="p">12.50</span><span class="p">11.25</span></div>
<div class="row"><span class="name">Bowl, 16cm<small>KW-BW-16</small></span>
<span class="p">14.00</span><span class="p">12.60</span></div>
<div class="row"><span class="name">Serving platter, 38cm<small>KW-PL-38</small></span>
<span class="p">46.00</span><span class="p">41.40</span></div>
</section>
<section class="cat">
<h2>Drinkware</h2>
<div class="hdr"><span>Item</span><span>A</span><span>B</span></div>
<div class="row"><span class="name">Tumbler, 280ml<small>KW-TU-28</small></span>
<span class="p">9.50</span><span class="p">8.55</span></div>
<div class="row"><span class="name">Mug, 350ml, handled<small>KW-MG-35</small></span>
<span class="p">11.00</span><span class="p">9.90</span></div>
<div class="row"><span class="name">Carafe, 1L<small>KW-CF-10</small></span>
<span class="p">32.00</span><span class="p">28.80</span></div>
</section>
<section class="cat">
<h2>Bespoke and finishing</h2>
<div class="hdr"><span>Service</span><span>A</span><span>B</span></div>
<div class="row"><span class="name">Hand-applied rim, per piece<small>KW-RIM</small></span>
<span class="p">2.20</span><span class="p">1.98</span></div>
<div class="row"><span class="name">Glaze match to sample<small>KW-GM, per batch</small></span>
<span class="p">450.00</span><span class="p">450.00</span></div>
<div class="row"><span class="name">Stock held, 12 months<small>KW-HOLD, per range</small></span>
<span class="p">890.00</span><span class="p">890.00</span></div>
</section>
</div>
<section class="breaks">
<strong>Volume breaks</strong> Column B applies from the quantity shown, per item
code, per order. Breaks do not accumulate across a calendar year.
<table>
<tr><th>Tableware</th><th>Drinkware</th><th>Finishing</th></tr>
<tr><td>150 pieces</td><td>200 pieces</td><td>500 pieces</td></tr>
</table>
</section>
</body>
</html>The layout decision worth understanding
The listings are set in two CSS columns with break-inside: avoid-column on each category, so a heading is never left at the bottom of a column with its rows in the next one. The volume break panel uses column-span: all to sit across both columns, which is the one place the two-column flow is deliberately interrupted.
The mistake people make adapting it
Issuing a list with no effective date. Two versions then circulate, a customer orders against the older one, and the difference is either absorbed or argued about, both of which cost more than a date would have.
Rendering it
The page box is declared in the template's own CSS as A4, so the size travels with the markup rather than living in the code that calls the renderer. A4 is also one of the six named formats the API accepts, so it can be passed in the request options instead if that suits your setup better.
curl -X POST https://api.pdfpipe.xyz/v1/pdf \
-H "Authorization: Bearer $PDFPIPE_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<!doctype html>...",
"options": { "format": "A4" }
}' \
--output price-list.pdfFrequently asked
Can I use this template commercially?
Yes. Copy it, change it, ship it. It is sample markup written to be taken, and the sample data in it is invented, so replace the names and the numbers before anyone sees it.
Why is the page size in the CSS rather than in the API call?
Because a trade price list is a A4 document, and that is a property of the document rather than of the code that renders it. Declaring it in the page box means the size cannot be lost between the template and the call, which is the usual way a document ends up on the wrong paper.
Will it look the same in every renderer?
The layout will, because it uses ordinary CSS. The page break behaviour will not: break-inside and break-after are implemented differently by browser engines and by dedicated print engines, and some of the paged media specification is not implemented in browser renders at all. That difference is documented per property in the paged CSS reference.
Other templates
Documents from the same part of a business, and one from each of the other groups.
Quotation HTML template with CSS
A priced proposal with a validity date, a scope, optional items kept out of the headline total, and somewhere to sign.
Purchase order HTML template
Issued by the buyer: an instruction to supply specific goods at specific prices, with separate delivery and invoicing addresses and the conditions of the order.
Order confirmation HTML template
Sent to the buyer after an order is placed: what was ordered, what it cost, and above all when it will arrive.
Product datasheet PDF template
A two-column technical specification sheet with a revision number, grouped tables, a dimensions figure and an ordering code.
HTML invoice template with CSS
The standard commercial invoice: a demand for payment with line items, a tax figure, and terms that say when the money is due.
Payment receipt HTML template
Proof that a payment was made: the amount, the payment reference, the method, and what it was for.
Packing slip HTML template
The document that goes in the box: what was ordered, what was actually shipped, and no prices at all.
Every template
The full set, grouped by what part of a business produces the document.
A4 page size for PDF generation
A4 is the default page for business documents everywhere except North America, and the default this API uses when no format is given.
Paste the template into the playground and get the PDF back. No signup, no key.