# Shipping label PDF from HTML (4×6 in)
Shipping label PDFs from HTML at 4×6 inches, with zero margins, Code 128 barcodes (JsBarcode or server SVG) and many labels per file.
The 4×6 inch label is the standard size for most direct thermal label printers in warehouses and e-commerce. If you make labels yourself (for picking, returns, internal routing, or to lay out a tracking number you already have), HTML is a quick way to design them. A PDF is what label printers and print dialogs handle best.
When you buy postage from a carrier, the carrier's API usually returns the official label, often as a PDF or ZPL. Use your own HTML label for everything around it, or where the carrier lets you print your own, and follow the carrier's barcode and layout specification.
**Quick answer.** Send your label HTML with a 4×6 inch page size and zero margins. Each label on its own page costs one credit.
```bash
curl https://html-pdf.com/v1/pdf -H "Authorization: Bearer $HTML_PDF_KEY" \
-d '{"html": "
SHIP TO: Jane Doe
", "width": "4in", "height": "6in", "margin": "0"}' -o label.pdf
```
## Set the page to exactly 4×6 inches
This section shows the two ways to get an exact label size. Both give the same result.
- **API options:** `"width": "4in", "height": "6in", "margin": "0"`.
- **CSS:** `@page { size: 4in 6in; margin: 0; }` plus `"prefer_css_page_size": true`.
Use zero margins and add spacing with padding inside the label, so nothing gets clipped or scaled. Thermal printers print black only, so use pure black text and bars on a white background.
## The label template
This template gives you a ready label with sender, recipient and a barcode slot.
```html
FROM: Northwind Store · 12 Dock Rd · Leeds LS1 4AP · UK
SHIP TO: Jane Doe 221B Baker Street London NW1 6XE United Kingdom
```
`break-after: page` on each `.label` puts every label on its own page, so one request can produce a whole batch. Fixed `width`/`height` with `overflow: hidden` makes sure a long address never pushes content onto an extra page.
## Option A: barcodes in the page with JsBarcode
This option draws barcodes in the browser while the page renders. JsBarcode draws Code 128, EAN and other 1D barcodes into SVG. Load it, render every barcode, then set a flag that the API waits for with `wait_for_expression`.
```html
```
Then render it from Node.js.
```js
import fs from "node:fs";
const html = fs.readFileSync("labels.html", "utf8");
const res = await fetch("https://html-pdf.com/v1/pdf", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.HTML_PDF_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
html,
width: "4in", height: "6in", margin: "0",
wait_for_expression: "window.labelsReady === true",
filename: "labels-2026-10-10.pdf",
}),
});
if (!res.ok) throw new Error((await res.json()).error.message);
fs.writeFileSync("labels.pdf", Buffer.from(await res.arrayBuffer()));
```
## Option B: generate the barcode SVG on your server
This option builds the barcode before you send the HTML, so there is no CDN or page JavaScript involved. In Python, `python-barcode` can write SVG.
```python
import os, html, io, requests
import barcode
from barcode.writer import SVGWriter
def code128_svg(value):
buf = io.BytesIO()
barcode.get("code128", value, writer=SVGWriter()).write(buf, options={"module_height": 18, "quiet_zone": 2})
svg = buf.getvalue().decode()
return svg[svg.index("