Design the invoice in HTML and CSS, the tools you already know, then POST it and get a PDF back. Rendering happens in real Chromium, so flexbox, grid and web fonts all work.
curl -X POST https://shotmint.creasework.com/v1/pdf \
-H "X-API-Key: $SHOTMINT_KEY" -H "Content-Type: application/json" \
-d '{"html": "<html>...your template...</html>", "format": "A4", "margin": "0mm"}' \
-o invoice.pdf
<html><head><style>
@page { size: A4; margin: 18mm 16mm; }
body { font-family: Inter, Arial, sans-serif; font-size: 12px; color: #111; }
table { width: 100%; border-collapse: collapse; }
td, th { padding: 6px 4px; border-bottom: 1px solid #ddd; text-align: left; }
tr { break-inside: avoid; } /* never split a line item across pages */
thead { display: table-header-group; } /* repeat the header row on every page */
.total { font-size: 16px; font-weight: 700; text-align: right; }
</style></head><body>
<h1>Invoice #2026-042</h1>
<p>Acme Ltd · 1 Main St · billing@acme.test</p>
<table><thead><tr><th>Item</th><th>Qty</th><th>Price</th></tr></thead>
<tbody><tr><td>Consulting</td><td>10</td><td>€1,200.00</td></tr></tbody></table>
<p class="total">Total: €1,200.00</p>
</body></html>
@page { margin } and pass "margin":"0mm", or leave CSS alone and use the API's margin param.break-before: page on a section to force a new page, and break-inside: avoid on rows and cards.print_background=true). Add -webkit-print-color-adjust: exact if colors look washed out.@font-face.https:// URLs or data URIs. Relative paths have no base to resolve against."format":"Letter" for US customers.One invoice = one credit. €5 covers 2,000 invoices and the credits never expire. That suits low-volume billing much better than a $20/month plan.
No signup, no card. Get a key in one click, then buy credits only if you need more (from €5 for 2,000, never expire).
Get a free API key Full API reference