Long reports and statements need page numbers, and usually a header or footer
on every page. CSS alone can't number pages in Chromium, but its print
settings can: Printmint passes them through as header_html and
footer_html.
A footer with page numbers
curl -X POST https://api-printmint.plxi.us/v1/pdf/render \
-H "X-API-Key: $PRINTMINT_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<html><head><title>Statement, October 2026</title></head><body><h1>Statement</h1><p>…</p></body></html>",
"pdf": {
"margin": { "top": "20mm", "bottom": "20mm", "left": "16mm", "right": "16mm" },
"footer_html": "<div style=\"width:100%; font-size:8px; padding:0 16mm; display:flex; justify-content:space-between\"><span class=\"title\"></span><span>Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></span></div>"
},
"inline": true
}'
Chromium fills in elements with these classes on each page:
| Class | Becomes |
|---|---|
pageNumber |
This page's number |
totalPages |
The number of pages |
title |
The document's <title> |
date |
Today's date |
url |
The page's address |
Three things that trip people up
- The margin is where it goes. The header sits in the top margin and the footer in the bottom one. With no margin there's no room, and nothing shows. 15 to 20 mm is enough for one line.
- Styles go inline. The header and footer don't see the page's CSS, and
their default font size is tiny. Put
styleon the elements, with afont-sizeyou can read. - They load nothing. Images in a header or footer have to be
data:URLs.
If you only want a footer, leave header_html out: the header stays empty.
In a template
The built-in report template already has the title and page numbers in its
footer. For a template of your own, save pdf.footer_html with it, and every
PDF printed from it gets the same footer unless the call sends another.