Recipe
Shipping label template
An A6 shipping label template for the PaperPony PDF API, sized for a thermal label printer with large addresses and a service band.
Worth knowing
- The page is A6, 105 by 148 mm, with zero margin, because a label printer has no margins and anything you leave is cropped. A6 is the closest named format to the 4 by 6 inch label stock.
- Set the size through options.format. There is no width or height option, and the request is rejected if you send one. Printing a label on A4 and expecting the printer to scale is how labels come out unreadable.
- Barcodes are images. Generate the PNG yourself and pass it as a data URL, or reference it over HTTPS. There is no barcode helper, and there should not be one.
The template
Store it once with POST /v1/templates. It is compiled when you store it, so a mistake surfaces now rather than on the first render.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
*, *::before, *::after { box-sizing: border-box; }
body {
margin: 0;
font-family: 'Noto Sans', sans-serif;
font-size: 10pt;
line-height: 1.5;
color: #111827;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
table { border-collapse: collapse; width: 100%; }
thead { display: table-header-group; }
tr { break-inside: avoid; }
.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
body {
width: 105mm;
height: 148mm;
padding: 4mm;
display: flex;
flex-direction: column;
font-size: 9pt;
}
.service {
background: #111827;
color: #fff;
padding: 2mm 3mm;
font-size: 13pt;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
display: flex;
justify-content: space-between;
}
.block { border-bottom: 1px solid #111827; padding: 3mm 0; }
.label {
font-size: 7pt;
letter-spacing: 0.16em;
text-transform: uppercase;
color: #6b7280;
}
.to { font-size: 13pt; font-weight: 700; line-height: 1.3; white-space: pre-line; }
.from { color: #374151; white-space: pre-line; }
.tracking {
margin-top: auto;
text-align: center;
font-family: 'Noto Sans Mono', monospace;
}
.tracking img { display: block; width: 100%; height: 0.9in; object-fit: contain; }
.tracking .code { margin-top: 1.5mm; font-size: 11pt; letter-spacing: 0.08em; }
</style>
</head>
<body>
<div class="service">
<span>{{service}}</span>
<span>{{weight}}</span>
</div>
<div class="block">
<div class="label">From</div>
<div class="from">{{sender.name}}
{{sender.address}}</div>
</div>
<div class="block">
<div class="label">Ship to</div>
<div class="to">{{recipient.name}}
{{recipient.address}}</div>
</div>
{{#if reference}}
<div class="block">
<div class="label">Reference</div>
<div>{{reference}}</div>
</div>
{{/if}}
<div class="tracking">
{{#if barcode_url}}<img src="{{barcode_url}}" alt="">{{/if}}
<div class="code">{{tracking_number}}</div>
</div>
</body>
</html>Rendering it
Substitute the template id you got back, and send this payload.
curl https://api.paperpony.dev/v1/pdf/render \
-H "Authorization: Bearer $PAPERPONY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_id": "tpl_YOUR_TEMPLATE_ID",
"data": {
"service": "Express",
"weight": "2.4 kg",
"sender": {
"name": "Northwind Studio",
"address": "14 Bridgewater Street\nManchester M15 4RN\nUnited Kingdom"
},
"recipient": {
"name": "Fabrikam Ltd",
"address": "9 Peveril Road\nSheffield S11 7AQ\nUnited Kingdom"
},
"reference": "PO-99213",
"tracking_number": "NW 4821 7734 GB",
"barcode_url": "https://cdn.example.com/barcodes/NW48217734GB.png"
},
"options": {
"format": "A6",
"margin": {
"top": "0",
"right": "0",
"bottom": "0",
"left": "0"
},
"print_background": true,
"wait_for": "networkidle"
}
}'import { PaperPony } from 'paperpony';
const pony = new PaperPony({ apiKey: process.env.PAPERPONY_API_KEY });
const job = await pony.pdf.render({
"template_id": "tpl_YOUR_TEMPLATE_ID",
"data": {
"service": "Express",
"weight": "2.4 kg",
"sender": {
"name": "Northwind Studio",
"address": "14 Bridgewater Street\nManchester M15 4RN\nUnited Kingdom"
},
"recipient": {
"name": "Fabrikam Ltd",
"address": "9 Peveril Road\nSheffield S11 7AQ\nUnited Kingdom"
},
"reference": "PO-99213",
"tracking_number": "NW 4821 7734 GB",
"barcode_url": "https://cdn.example.com/barcodes/NW48217734GB.png"
},
"options": {
"format": "A6",
"margin": {
"top": "0",
"right": "0",
"bottom": "0",
"left": "0"
},
"print_background": true,
"wait_for": "networkidle"
}
});
console.log(job.output_url);import os
import requests
response = requests.post(
"https://api.paperpony.dev/v1/pdf/render",
headers={"Authorization": f"Bearer {os.environ['PAPERPONY_API_KEY']}"},
json={
"template_id": "tpl_YOUR_TEMPLATE_ID",
"data": {
"service": "Express",
"weight": "2.4 kg",
"sender": {
"name": "Northwind Studio",
"address": "14 Bridgewater Street\nManchester M15 4RN\nUnited Kingdom"
},
"recipient": {
"name": "Fabrikam Ltd",
"address": "9 Peveril Road\nSheffield S11 7AQ\nUnited Kingdom"
},
"reference": "PO-99213",
"tracking_number": "NW 4821 7734 GB",
"barcode_url": "https://cdn.example.com/barcodes/NW48217734GB.png"
},
"options": {
"format": "A6",
"margin": {
"top": "0",
"right": "0",
"bottom": "0",
"left": "0"
},
"print_background": true,
"wait_for": "networkidle"
}
},
)
response.raise_for_status()
print(response.json()["output_url"])