Invoices, receipts, quotes, statements and reports usually start life as data in your database and end up as a PDF in someone's inbox. Building them with a PDF library means positioning every line by hand. Building them in HTML means using the layout skills, components and CSS you already have, and Chrome's print engine does the pagination.
Render a template
Fill in your template on the server and send it with format=pdf:
curl -X POST "https://shotkit.net/api/take" \
-H "X-Access-Key: YOUR_ACCESS_KEY" \
-H "Content-Type: application/json" \
-d '{"html":"<style>body{font:14px/1.5 system-ui;color:#111} h1{font-size:28px;margin:0 0 4px} table{width:100%;border-collapse:collapse;margin-top:24px} td,th{padding:8px 0;border-bottom:1px solid #e5e7eb;text-align:left} .r{text-align:right} .total{font-weight:700;font-size:18px}</style><h1>Invoice #1042</h1><p>Acme Inc. · Due 30 November 2026</p><table><tr><th>Item</th><th class=\"r\">Amount</th></tr><tr><td>Pro plan, October</td><td class=\"r\">$90.00</td></tr><tr><td>Extra screenshots</td><td class=\"r\">$12.00</td></tr><tr><td class=\"total\">Total</td><td class=\"r total\">$102.00</td></tr></table>","format":"pdf","pdf_paper_format":"a4","pdf_margin":"2cm","pdf_print_background":true}' \
--fail-with-body -o shot.pdfThe text in the PDF stays selectable and searchable, and links stay clickable.
Paper, margins and orientation
| Option | Values |
|---|---|
pdf_paper_format |
a0–a6, letter (default), legal, tabloid |
pdf_landscape |
true for landscape pages |
pdf_margin |
Any CSS length for all sides: 20px, 1.5cm, 0.5in |
pdf_margin_top, _right, _bottom, _left |
Override one side |
pdf_print_background |
true to keep background colors and images |
Page breaks, headers and page numbers
Pagination is controlled with standard print CSS:
break-before: pagestarts a section on a new page;break-inside: avoidkeeps a table row or a totals block together.theadrows of long tables repeat at the top of every page.- Chrome supports
@pagemargin boxes, so page numbers are one CSS rule. Leave room for them with a bottom margin:
curl -X POST "https://shotkit.net/api/take" \
-H "X-Access-Key: YOUR_ACCESS_KEY" \
-H "Content-Type: application/json" \
-d '{"html":"<style>@page { @bottom-right { content: \"Page \" counter(page) \" of \" counter(pages); font: 10px system-ui; color: #6b7280 } } section { break-after: page }</style><section><h1>Quarterly report</h1><p>Summary…</p></section><section><h2>Revenue</h2><p>Details…</p></section>","format":"pdf","pdf_paper_format":"a4","pdf_margin":"2cm"}' \
--fail-with-body -o shot.pdfGenerate PDFs at scale
- For a file you'll store or email, use
response_type=json: you get a URL to download from instead of the bytes in the response. - Long reports with many charts can take longer than a normal request allows. Send them with
async=trueand awebhook_url, and the PDF arrives at your webhook when it's ready. See async and webhooks. - Files on the CDN expire after
cache_ttl(4 hours by default). Copy the PDF to your own storage if customers need it later.
Compared to wkhtmltopdf and PDF libraries
wkhtmltopdf uses an old WebKit engine and was archived in 2023, so flexbox, grid and modern CSS often break. Libraries like PDFKit or ReportLab are fast but have you place text by coordinates. Rendering in current Chrome gives you modern CSS and web fonts without running a browser yourself.
Frequently asked questions
Can I use A4 instead of US Letter?
Yes. Set pdf_paper_format to a4. Letter is the default.
Is the text in the PDF selectable?
Yes. Chrome prints real text, not an image of it, so the PDF is searchable, copyable and accessible to screen readers.
Can I password-protect or sign the PDF?
Not through the API. Post-process the file with a PDF library such as pdf-lib or qpdf if you need encryption or digital signatures.
Why are my background colors missing?
Browsers drop backgrounds when printing by default. Set pdf_print_background to true.